RequestAnimationFrame调用时间根据我的画布大小而变化

时间:2012-03-25 13:16:21

标签: javascript html5 canvas requestanimationframe

在我的应用程序中,我有一个CSS大小(CSS,而不是html)更新的画布,具体取决于窗口大小。

我有一个主要的gameplayLoop,看起来像这样:

run = function(){

    console.log(timerDiff(frameTime));

    game.inputManage();
    game.logics();
    game.graphics.animate();
    game.graphics.render();

    frameTime = timerInit();

    requestAnimFrame(run);

}

我的requestAnimFrame函数来自Paul Irish:

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

所以基本上问题是我记录的定时器测量requestAnimFrame调用和有效函数调用之间的时间完全改变。 如果我的浏览器是全屏的,我会得到50/60毫秒,如果我有一个小窗口,我可以达到10毫秒。

因为requestAnimFrame调用应该不断调用60fps节奏下的函数(我认为这是30毫秒)我不应该有这种结果,因为在计时器的创建和它之间基本没有任何事情发生检查,requestAnimFrame

除外

我也有一些反复的微冻结(不到一秒钟),每2/3秒发生一次。但是计时器没有检测到任何时间的变化(就像javascript的时间计数器被阻止一样)

我的计时器功能是这样的,但这并不重要

timerInit = function()
{
    return new Date();
}

timerDiff = function(datePrev)
{
    return new Date().getTime() - datePrev.getTime();
}

2 个答案:

答案 0 :(得分:7)

嗯,标准基本上说requestAnimationFrame将“尽力”以“一致”的帧速率运行。这不能保证60fps;它只是说它会尽可能快地制作动画。

不幸的是,我对它的体验一直和你的一样黯淡。我最终回到了setTimeout。它的速率大致相同,图形更新是准确的,并且不会像requestAnimationFrame那样跳过节拍。当然它不是60fps,但至少你可以知道发生了什么。

我确信性能只会随着浏览器开发人员优化新功能而改善,但暂时考虑回到timeouts

编辑:我想提醒大家一年前这已经回答了,时代已经改变了:)

答案 1 :(得分:4)

“所以基本上问题是我记录的计时器测量requestAnimFrame调用和有效函数调用之间的时间完全改变了......”

当然它确实如此,这就是为什么你需要测量它并根据这个时间差值来计算下一帧。

让我们假设您想要以60 fps的速度在1秒内将div的'left'css属性设置为0px到120px。

  • 使用setTimeout ,因为您设置了帧数,您知道必须增加多少'left'属性:120px / 60frames = 2px / frame

  • 使用requestAnimationFrame ,在下一帧发生时你没有想法,直到它发生;然后你测量这个和前一帧之间的时间差,你计算你必须增加css'左值'的值;如果帧在500ms后发生,则增量距离=(120px * 500ms)/ 1000ms = 60px; ideea是在动画开始时你没有固定的预定值来增加每帧,你需要根据时差动态计算它

因此,即使动画不是广告的60fps,如果跳过帧,则每个未跳过的帧都将绘制准确的更新情况。

你必须做一些事情来决定动画何时结束。