HTML Canvas Interval与RequestAnimationFrame

时间:2012-08-13 22:17:50

标签: javascript canvas html5-canvas

所以,也许在这里完全是大脑。 setInterval()的语法非常清楚。每隔x毫秒做一些事情。如何最好地转换为使用requestAnimationFrame()

我有大约300个对象,每个对象应该以一定的间隔(每8,6,2等秒)执行动画序列?我怎样才能最好地使用requestAnimationFrame()来实现这一点,这被称为每秒60次?可能有一个简单的答案,我只是,因为我的生活,无法弄明白。

2 个答案:

答案 0 :(得分:10)

requestAnimationFrame非常低级别,它只是按照您已经说过的方式执行:大致以60fps调用(假设浏览器可以跟上这个速度)。所以通常你需要在那之上构建一些东西,就像一个有游戏循环的游戏引擎。

在我的游戏引擎中,我有这个(paraphased / simplified here):

window.requestAnimationFrame(this._doFrame);

...

_doFrame: function(timestamp) {
     var delta = timestamp - (this._lastTimestamp || timestamp);

     for(var i = 0, len = this.elements.length; i < len; ++i) {
         this.elements[i].update(delta);
     }

     this._lastTimestamp = timestamp;

     // I used underscore.js's 'bindAll' to make _doFrame always
     // get called against my game engine object
     window.requestAnimationFrame(this._doFrame);
 }

然后我的游戏引擎中的每个元素都知道如何更新自己。在您的情况下,应每2,6,8秒更新一次的每个元素需要跟踪已经过了多少时间并相应地更新:

update: function(delta) {
     this.elapsed += delta;

     // has 8 seconds passed?
     if(this.elapsed >= 8000) {
          this.elapsed -= 8000;  // reset the elapsed counter
          this.doMyUpdate(); // whatever it should be
     }
 }

Canvas API和requestAnimationFrame的级别相当低,它们是动画和游戏引擎之类的构建块。如果可能的话,我会尝试使用像cocos2d-js这样的现有产品或者其他产品。

答案 1 :(得分:10)

要强制requestAnimationFrame坚持使用特定的FPS,您可以同时使用两者!

var fps = 15;
function draw() {
    setTimeout(function() {
        requestAnimationFrame(draw);
        // Drawing code goes here
    }, 1000 / fps);
}

有点奇怪,但不是世界上最混乱的事情。

你也可以使用requestAnimationFrame而不是FPS但是经过了时间,以便根据自上次调用以来的时间差来绘制需要更新的对象:

var time;
function draw() {
    requestAnimationFrame(draw);
    var now = new Date().getTime(),
        dt = now - (time || now);

    time = now;

    // Drawing code goes here... for example updating an 'x' position:
    this.x += 10 * dt; // Increase 'x' by 10 units per millisecond
}

这两个片段来自this fine article,其中包含其他详细信息。

顺便说一句好问题!我不认为我已经看到过这样的回答了(我在这里太过分了)