Using requestAnimationFrame in JavaScript

Monday, July 23, 2012

There are a few different techniques you can use to animate objects in a web browser. The easiest animations are declarative animations with CSS 3 transitions. With CSS you can tell the browser to apply property changes over time instead of instantaneously, and even add some easing to make the animation appear natural. See David Rousset’s Introduction to CSS3 Animations and David Catuhe’s Transitions Puzzle for some clever examples.

Other types of animation require custom algorithms. Verlet integration, as you’ll see in a future post, can produce some enjoyable effects, but also requires custom logic in script code and a timer tick to manually update the screen at regular intervals. Script code traditionally implemented the periodic screen updates using setTimeout or setInterval,  but the future is requestAnimationFrame.

RAF in 17 Syllables

One way to think about requestAnimationFrame (RAF for short), is to contemplate the following poem, which I wrote while waiting for a dish of Yakisoba topped with red peppers and sesame seeds to arrive.

game loop request
electron salvation
render springtime on my screen

To express RAF in more straightforward prose is to say that RAF allows you to setup a loop by repeatedly telling the browser you want to draw a frame on the screen. Since the browser knows when the best time is to update the screen, it can optimize calls into your drawing code and synchronize with all the other painting and drawing. The optimization can lead to faster performance, improved CPU utilization, and extended battery life for portable devices. RAF is already supported in Chrome, Firefox, and IE 10. If a browser doesn’t support RAF natively, you can always fallback to setTimeout.

Example

To use RAF you need to invoke the RAF method and pass a callback. The callback is the function with your code to paint the illusion of motion, and you’ll keep calling RAF from within the paint method to set up an endless loop. Here is a simple example with a crude calculation for frames per second. The code will output the FPS measurement to a div.

<div id="frameRate"></div>

<script>

 

$(document).ready(function () {

var framesPerSecond = 0;
var output = $("#frameRate");
var lastRun = new Date().getTime();

var loop = function () {
requestAnimationFrame(loop);
framesPerSecond = 1 / ((new Date().getTime() - lastRun) / 1000);
lastRun = new Date().getTime();
output.text(Math.round(framesPerSecond));
};



loop();



});

</script>


Typically you would move objects or refresh and draw in a canvas element during the loop. We’ll look at simulating a swinging rope with verlet integration in a future post.


Comments
gravatar Doeke Tuesday, July 24, 2012
To get this working, you have to prefix requestAnimationFrame with webkit or moz.

See also: http://jsfiddle.net/3GWqf/1/
gravatar scott Tuesday, July 24, 2012
@Doeke: Yes, good point. I'm using the polyfill from https://gist.github.com/1579671 that will setup the correct prefix.
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!