在我的应用程序中,我有一个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();
}
答案 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,如果跳过帧,则每个未跳过的帧都将绘制准确的更新情况。
你必须做一些事情来决定动画何时结束。