Skip to content

Instantly share code, notes, and snippets.

@desandro
Forked from paulirish/rAF.js
Created February 19, 2012 23:29
Show Gist options
  • Star 21 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save desandro/1866474 to your computer and use it in GitHub Desktop.
Save desandro/1866474 to your computer and use it in GitHub Desktop.
requestAnimationFrame polyfill
/**
* requestAnimationFrame polyfill by Erik Möller & Paul Irish et. al.
* https://gist.github.com/1866474
*
* http://paulirish.com/2011/requestanimationframe-for-smart-animating/
* http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
**/
/*jshint asi: false, browser: true, curly: true, eqeqeq: true, forin: false, newcap: true, noempty: true, strict: true, undef: true */
(function( window ) {
'use strict';
var lastTime = 0;
var prefixes = 'webkit moz ms o'.split(' ');
// get unprefixed rAF and cAF, if present
var requestAnimationFrame = window.requestAnimationFrame;
var cancelAnimationFrame = window.cancelAnimationFrame;
// loop through vendor prefixes and get prefixed rAF and cAF
var prefix;
for( var i = 0; i < prefixes.length; i++ ) {
if ( requestAnimationFrame && cancelAnimationFrame ) {
break;
}
prefix = prefixes[i];
requestAnimationFrame = requestAnimationFrame || window[ prefix + 'RequestAnimationFrame' ];
cancelAnimationFrame = cancelAnimationFrame || window[ prefix + 'CancelAnimationFrame' ] ||
window[ prefix + 'CancelRequestAnimationFrame' ];
}
// fallback to setTimeout and clearTimeout if either request/cancel is not supported
if ( !requestAnimationFrame || !cancelAnimationFrame ) {
requestAnimationFrame = function( callback, element ) {
var currTime = new Date().getTime();
var timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
var id = window.setTimeout( function() {
callback( currTime + timeToCall );
}, timeToCall );
lastTime = currTime + timeToCall;
return id;
};
cancelAnimationFrame = function( id ) {
window.clearTimeout( id );
};
}
// put in global namespace
window.requestAnimationFrame = requestAnimationFrame;
window.cancelAnimationFrame = cancelAnimationFrame;
})( window );
@desandro
Copy link
Author

This prevents use of vendorRequestionAnimationFrame unless the equivalent is supported for cancelAnimationFrame.

I ran into an issue with Firefox 10, where mozRequestAnimationFrame is supported, but not an equivalent for cancelAnimationFrame. So I was able to start an animation, but not properly stop it.

Also, has some personal whitespace and code style tweaks.

@charliewalnut
Copy link

I think it would be a lot better to emulate cancelAF() than to completely abort if it's not available. To emulate on browsers without a cancel, wrap pending callbacks along with their IDs and have cancel() set a bit that marks that ID as cancelled. That's in fact exactly we do in the browser.

@desandro
Copy link
Author

@charliewalnut Agreed that it's a shame to throw out requestAF with cancelAF. Can you provide a fork with this implementation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment