Animation Timing API
The Animation Timing API deals with the control of script-based animations, specifically the
requestAnimationFrame() method of the
window object. The
requestAnimationFrame method provides a smoother and more efficient way to create animated webpages by calling the animation frame when the system is ready to paint the frame. Prior to this API, animations drawn using
setInterval() didn't provide web developers an efficient way to schedule graphics timers for animations. This resulted in overdrawn animations, wasted CPU cycles, and extra power usage. Further, animation frequently occurs even when a website isn't visible, particularly when the website uses pages in background tabs or when the browser is minimized.
The top row represents the 16.7ms display frequency displayed on most monitors and the bottom row represents a typical
setTimeout of 10ms. Every third draw cannot be painted (indicated by the red arrow) because another draw request occurs before the display refresh interval. This overdrawing results in choppy animations because every third frame is lost. This timer resolution reduction can also negatively impact battery life, and reduce performance of other apps.
requestAnimationFrame method (defined in the World Wide Web Consortium (W3C)'s Timing control for script-based animations specification) can solve the lost frame problem because it enables apps to be notified when (and only when) the browser needs to update the page display. As a result, apps are perfectly aligned with the browser painting interval and use only the appropriate amount of resources. Switching from
requestAnimationFrame is easy, as they both schedule a single callback. For continued animation, call
requestAnimationFrame again after the animation function has been called.
To use this new API, you just call
requestAnimationFrame using a callback function. The timing is handled by the system. If you're currently using
setTimeout to drive your animation timing, like this:
var handle = setTimeout(renderLoop, PERIOD);
You can replace
requestAnimationFrame, as shown here:
var handle = requestAnimationFrame(renderLoop);
This takes care of your first repaint. To keep the animation going, call
requestAnimationFrame again from within your callback function (shown as renderLoop here).
This examples starts by saving the
<div> element to a global variable using
renderLoop() function is called to start the animation. After the
<div> element is repositioned,
requestAnimationFrame is called again to set up for the next move. This continues until you close the browser or click the
Time in a callback function
You can use the callback function to animate almost anything, for example, SVG, Canvas, or as we show here, CSS properties. The callback function has one incoming time parameter, which represents the time the callback function is called. This is a
DOMHighResTimeStamp, a high resolution time measured from the beginning of the navigation of the page.
DOMHighResTimeStamp is measured in milliseconds accurate to a thousandth of a millisecond. This time value isn't directly comparable with
Date.now(), which measures time in milliseconds since 01 January 1970. If you want to compare the time parameter with the current time, use
window.performance.now for the current time.
Changing the time value from
DOMHighResTimeStamp was a change in 2012 (see Editors Draft of the W3C Timing control for script-based animation specification). Earlier versions of the W3C specification used the DOMTimeStamp, which allowed you to use
Date.now for the current time. The difference being
DOMTimeStamp has a millisecond precision and
DOMHighResTimeStamp has a minimal precision of ten microseconds.
Older browsers might still implement the
DOMTimeStamp parameter, or not support the
window.performance.now timing function. This example provides a sample animation program that works across several browsers and uses time to move the
This example is an updated version of a sample from the W3C specification, with vender prefixed elements added. The example tests for
window.performance.now, and if it isn't supported, uses
Date.now to get the current time. If
cancelAnimationFrame aren't supported, then
clearTimeout are used. This gives compatibility for earlier versions of the browser.