Skip to content

Instantly share code, notes, and snippets.

@louisremi
Created July 29, 2011 17:34
Show Gist options
  • Star 44 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save louisremi/1114293 to your computer and use it in GitHub Desktop.
Save louisremi/1114293 to your computer and use it in GitHub Desktop.
Animation loop with requestAnimationFrame
function animLoop( render, element ) {
var running, lastFrame = +new Date;
function loop( now ) {
// stop the loop if render returned false
if ( running !== false ) {
requestAnimationFrame( loop, element );
var deltaT = now - lastFrame;
// do not render frame when deltaT is too high
if ( deltaT < 160 ) {
running = render( deltaT );
}
lastFrame = now;
}
}
loop( lastFrame );
}
function animLoop( render, element ) {
var running, lastFrame = +new Date;
function loop( now ) {
// stop the loop if render returned false
if ( running !== false ) {
requestAnimationFrame( loop, element );
running = render( now - lastFrame );
lastFrame = now;
}
}
loop( lastFrame );
}
// Usage
animLoop(function( deltaT ) {
elem.style.left = ( left += 10 * deltaT / 16 ) + "px";
if ( left > 400 ) {
return false;
}
// optional 2nd arg: elem containing the animation
}, animWrapper );
// Cross browser, backward compatible solution
(function( window, Date ) {
// feature testing
var raf = window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame;
window.animLoop = function( render, element ) {
var running, lastFrame = +new Date;
function loop( now ) {
if ( running !== false ) {
raf ?
raf( loop, element ) :
// fallback to setTimeout
setTimeout( loop, 16 );
// Make sure to use a valid time, since:
// - Chrome 10 doesn't return it at all
// - setTimeout returns the actual timeout
now = now && now > 1E4 ? now : +new Date;
var deltaT = now - lastFrame;
// do not render frame when deltaT is too high
if ( deltaT < 160 ) {
running = render( deltaT, now );
}
lastFrame = now;
}
}
loop();
};
})( window, Date );
// Usage
animLoop(function( deltaT, now ) {
// rendering code goes here
// return false; will stop the loop
...
// optional 2nd arg: elem containing the animation
}, animWrapper );
var elem = document.getElementById("animatedElem"),
left = 0,
lastFrame = +new Date,
timer;
// Move the element on the right at ~600px/s
timer = setInterval(function() {
var now = +new Date,
deltaT = now - lastFrame;
elem.style.left = ( left += 10 * deltaT / 16 ) + "px";
lastFrame = now;
// clear the timer at 400px to stop the animation
if ( left > 400 ) {
clearInterval( timer );
}
}, 16);
@darius
Copy link

darius commented May 13, 2013

Would this do the same thing? It's simpler:

// Periodically call render(timeInterval) via requestAnimationFrame on
// element until it returns false. (But call render only when the
// interval is < 160ms; otherwise wait and try again, hoping for a
// reasonable interval.)
function animLoop(render, element) {
    var then = Date.now();
    function loop(now) {
        var interval = now - then;
        if (160 <= interval || render(interval) !== false)
            requestAnimationFrame(loop, element);
        then = now;
    }
    loop(then);
}

(Do any browsers or specifications use this element parameter?)

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