Up to date polyfill for requestAnimationFrame

霸气de小男生 提交于 2019-12-01 00:53:18

问题


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).


回答1:


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.




回答2:


The change for hi-res timing only affects the parameter to the callback. I don't believe any polyfills explicitly reference the parameter, it just depends on how you use it. So the polyfills don't need updating and should be working just fine already - just be careful about how you use the parameter to the RAF callback, and if you don't, it's nothing to worry about!




回答3:


this might work. modified this gist

https://gist.github.com/1579671

(function() {
    var lastTime = 0;
    var startTime = Date().getTime();
    var vendors = ['ms', 'moz', 'webkit', 'o'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] 
                                   || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime - startTime); }, 
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());

get the timestamp when the closure first executes (page load), then pass into the callback the difference between the current timestamp and the original. Should give you an integer equivalent of the new method. Not as precise, but better than a totally different value.




回答4:


Here is the blog entry from Paul Irish containing the original polyfil and his updates.

http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

That should suffice for most scenarios.




回答5:


Paul Irish has suggested a polyfill for this.

window.requestAminFrame = (function(){
    return window.requestAminFrame || window.webkitRequestAnimFrame || window.mozRequestAnimFrame || window.msRequestAnimFrame || window.oRequestAnimFrame || function(func){return setTimeout(func,1/60);};
})();


来源:https://stackoverflow.com/questions/13241314/up-to-date-polyfill-for-requestanimationframe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!