Using requestAnimationFrame in JavaScript

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.