Up to date polyfill for requestAnimationFrame

Chris Jefferson picture Chris Jefferson · Nov 5, 2012 · Viewed 7.6k times · Source

http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision tells me that recently (Chrome 20) requestAnimationFrame has gained a new sub-millisecond precision timer, and that I have to update my code to support it.

Looking around at the various polyfills around, they all seem to pre-date this update. Are they somehow functional (I don't think so), or is there simply not an up-to-date one available? Should I just do the timing myself (seems a bit wasteful).

Answer

Tim Hall picture Tim Hall · Nov 15, 2012

I had just read that article too and was curious to try this myself. I've taken a stab at adding a wrapper to the rAF callback in browsers that don't support high-resolution timers. It uses Paul Irish's original polyfill with the following added lines:

var hasPerformance = !!(window.performance && window.performance.now);

// Add new wrapper for browsers that don't have performance
if (!hasPerformance) {
    // Store reference to existing rAF and initial startTime
    var rAF = window.requestAnimationFrame,
        startTime = +new Date;

    // Override window rAF to include wrapped callback
    window.requestAnimationFrame = function (callback, element) {
        // Wrap the given callback to pass in performance timestamp
        var wrapped = function (timestamp) {
            // Get performance-style timestamp
            var performanceTimestamp = (timestamp < 1e12) 
                ? timestamp 
                : timestamp - startTime;

            return callback(performanceTimestamp);
        };

        // Call original rAF with wrapped callback
        rAF(wrapped, element);
    }        
}

Here's a gist of it all combined together and an updated example using the new code:

https://gist.github.com/4078614

http://jsfiddle.net/timhall/XQpzU/4351/

This approach aims at normalizing the parameter that is passed into the callback function to the high-resolution timer format. You could use a similar approach, just opposite, to convert the high-resolution timer to the old format if you have existing code expecting that, but I see that as a regression.

I'm going to try it out in one of my projects that I'm working on right now and will update the gist if I find any issues / improvements.