Using while(Date.now() < interval) {} with requestAnimati
Using while(Date.now() < interval) {} with requestAnimationFrame()
我们都知道,如果某些 fps 很重要或类似的东西,制作正确的更新算法是多么困难。
无论如何,我只是想出了这个无限的循环黑客,它只是将程序冻结到下一帧,它似乎完美无缺。
var then = Date.now()
var fps = 40;
var interval = 1000 / fps;
function mainloop() {
while (Date.now() - then < interval) {} // freezes program until next frame
requestAnimationFrame(mainloop);
then = Date.now();
// update logic goes here
}
mainloop();
我在任何地方都没有看到这个解决方案,所以我想问它是否干净和正确。我知道冻结程序只是为了等待某些东西是不好的,那段代码看起来很糟糕,但它似乎有效。有没有一个更干净的解决方案可以与我的代码类似?
您可以使用 setTimeout 等待一定时间,但这不会非常精确。但是,通过一直更改interval
,您可以获得足够精确的平均延迟。
var startTime = Date.now();
var fps = 40;
var frames = 0;
var interval = 1000 / fps;
function mainloop() {
frames++;
var timeElapsed = Date.now() - startTime,
averageFps = 1000 * frames / timeElapsed;
if(averageFps < fps && interval > 0) interval -= 0.1;
if(averageFps > fps) interval += 0.1;
setTimeout(mainloop, interval);
// update logic goes here
}
setTimeout(mainloop, interval);
但是,如果速度太慢,计算机仍然无法满足请求的 fps 的风险。
使用 while 循环来浪费时间是一个坏主意。它只是浪费了处理器时间,而这些时间本可以做其他事情。
按照 jishi 的建议使用 SetTimeout 是一种可能的解决方案。但是,这仅控制代码的运行时间。您无法真正控制浏览器实际绘制的时间。基本上,浏览器将绘制代码更新的最后一帧。
因此,另一种可能的解决方案是使用 requestAnimation。在绘图代码中,确定以首选速率出现的最后一帧。画那个框架。例如。。。
var start = null;
var fps = 40;
var interval = 1000 / fps;
function mainloop(timeStamp) {
if (!start) {
start = timeStamp;
}
var n = (timeStamp - start) / interval;
// update logic goes here to paint nth frame
requestAnimationFrame(mainloop);
}
mainloop();
在您的特定场景中,最好使用 setTimeout 延迟主循环执行,如下所示:
var nextExecution = Date.now() - then + interval;
if (nextExecution < 0) nextExecution = 0;
setTimeout(mainloop, nextExecution);
这将允许它在等待下一帧渲染时执行其他操作。
相关文章:
- Fighting with FRP
- issue with FB.Event.subscribe
- geolocation-marker.js conflict with markerclusterer.js
- Angular 2.0 with JavaScript or TypeScript?
- 为什么不推荐使用“with”?是否有更好或其他方法可以“下降”到对象的命名空间
- WebComponentsJS with IE10
- 指令的模板必须只有一个根元素:With restrict E&替换true
- timeago.js with datatable and PHP
- Ajax and Json with Rails
- errors with Javascript try catch
- how to split a string with ','
- Understanding Javascript scope with "var that = this&qu
- Architecture for CPU intensive tasks with NodeJS & Socke
- How to declare a Map containing certain properties with flow
- 设置'这'在React with Inverse Data Flow中
- Unit-testing multiple use cases with Karma & Mocha.js
- Modify Javascript with C#
- 谷歌地图API v3:Initial View is Fine,but Gray Box with No Map if
- jQuery AJAX with an interval
- Using while(Date.now() < interval) {} with requestAnimati