crazy4groovy
7/29/2011 - 5:34 PM

Animation loop with requestAnimationFrame

Animation loop with requestAnimationFrame

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);
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 );
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 );
}
// 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 );