Advanced animations with requestAnimationFrame

Original author: Paul Irish
  • Transfer
If you have never written code to perform animations, then you may not read further :)

What is requestAnimationFrame?


In all of your animation features, you use a repeating timer to apply changes every few milliseconds. The good news is: browser makers have decided "why don't we give you an API for this because we may be able to optimize some points for you." So, this is the main API for creating animations based on changing DOM styles, redrawing canvas or WebGL

Why should I use this?


Browsers can optimize animations running at the same time, reducing the number of reflow and repaint to one, which in turn will increase the accuracy of the animation. For example, animations in JavaScript synchronized with CSS transitions or SVG SMIL. Plus, if the animation is performed in a tab that is invisible, browsers will not continue to redraw , which will lead to less use of CPU, GPU, memory and as a result will reduce battery consumption in mobile devices.

Usage example


    // Если ничего нет - возвращаем обычный таймер
    window.requestAnimFrame = (function(){
      return  window.requestAnimationFrame       || 
              window.webkitRequestAnimationFrame || 
              window.mozRequestAnimationFrame    || 
              window.oRequestAnimationFrame      || 
              window.msRequestAnimationFrame     || 
              function(/* function */ callback, /* DOMElement */ element){
                window.setTimeout(callback, 1000 / 60);
              };
    })();
    // Использование: 
    (function animloop(){
      render();
      requestAnimFrame(animloop, element);
    })();

Note: I use requestAnimFrame because the specification is still under development and therefore I do not want to declare a global requestAnimationFrame (apply polyfill )

in advance . See in action here: jsfiddle.net/paul/XQpzU

requestAnimationFrame API


window.requestAnimationFrame(function(/* time */ time){
	// time ~= +new Date
}, /* связанный элемент */ elem);

The current time is transferred to the callback, it will be necessary for you anyway. The second parameter passes the element associated with the current animation (for optimization). For canvas and WebGL, this will be an element. For other animations, you can transfer nothing or define anything to improve performance.

Already can be used?


Now Webkit ( Nightly Safari and Chrome Dev Channel ) and Mozilla (FF4) are slightly different. Mozilla has a bug that limits the number of frames of the animation (about 30) Actually, “it is limited to 1000 / (16 + N) fps, where N is the number of milliseconds needed to perform the animation function. If the function takes 1 second, then the number of frames will be less than 1 per second. If the animation function takes 1 ms, then the number of frames will be about 60. This will be fixed on the next FF release, but after FF4. Also, Chrome 10 does not have a time parameter (added in m11), FF now ignores the elem argument.

Write reviews!


If you work with animations, then the developers of WebKit and Gecko will be happy to hear your feedback and suggestions. Check out the draft specification for requestAnimationFrame. Now it acts like setTimeout; Is it worth replacing with setInterval? Does this API have flaws when animating multiple objects at the same time? Does elem optimization work? Does this API cover all animation needs?

Other sources

  1. Draft spec (authored by heycam and jamesr)
  2. Chromium design doc
  3. A basic example
  4. A more comprehensive example with some available config
  5. MDC docs on mozRequestAnimationFrame
  6. Libraries using animation timers yui anim loop , three.js , limejs , ticket for jQuery's implementation
  7. Demo by Louis-Rémi Babé when switching tabs look at the processor load
  8. Nokarma's coverage of requestAnimationFrame
  9. Mozilla's Robert O'Callhan early post on rAF

Also popular now: