0

我阅读了以下请求动画 polyfill。但是,我不明白为什么作者将currTime + timeToCall参数放入callbackin 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);
        };
}());
4

1 回答 1

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

于 2013-04-10T11:53:02.633 回答