请求动画polyfill中回调中的参数

时间:2013-04-09 10:34:50

标签: javascript

我阅读了以下请求动画polyfill。但是,我无法理解为什么作者将currTime + timeToCall参数放入callback中的setInterval

var id = window.setTimeout(function() {
                callback(currTime + timeToCall);
            },

以下是完整的polyfill代码段:

// Set up requestAnimationFrame and cancelAnimationFrame for use in the game code
(function() {
    var lastTime = 0;
    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 + timeToCall);
            },
            timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };
    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());

1 个答案:

答案 0 :(得分:0)

polyfill中的此参数用于涵盖requestAnimationFrame规范。 如果您打算在动画中使用时间控制,则回调应提供时间戳参数。 与简单使用(currTime + timeToCall)相比,polyfill中的setTimeout可为动画提供更准确的时间戳。

var now, timeBetweenFrames, lastTime;

function animation (timestamp) {
  now  = timestamp; // the value of timestamp is changing
  timeSinceLastFrame = now - lastTime; // time between frames in miliseconds
  lastTime = now;       

  // ... performe your animations

  // you can use the timeSinceLastFrame value, for example, 
  // to interpolate the position of your objects,
  // making the animation reacts equally, independent of performance scenarios

  // here is an example:
  // ... 

  // if you have an object named player, with moves depending on his velocity
  // update the player position
  player.x += player.velocity.x * (timeSinceLastFrame/1000);
  player.y += player.velocity.y * (timeSinceLastFrame/1000);
  // note that timeSinceLastFrame/1000 is the time in seconds instead of miliseconds
  // draw the player on the screen
  player.draw();

  // ...

  requestAnimationFrame(animation);
}

function start() {
  lastTime = Date.now() // or performance.now() like described below this code snippet
  requestAnimationFrame(animation);  // let this party begin
}

start();

请注意,如果浏览器具有原始timestamp支持,则requestAnimationFrame参数会发送到您的回调,其时间格式与performance.now()中使用的格式相同,而不是Date.now() 。这适用于某些新版本的浏览器,例如Chrome。有关更详细的说明,请参阅此HTML5 Rocks文章: http://updates.html5rocks.com/2012/05/requestAnimationFrame-API-now-with-sub-millisecond-precision