javascript - 为什么毫秒计数器在 requestAnimationFrame() 中一直走?

标签 javascript requestanimationframe

我正在使用很棒的 requestAnimationFrame(callback) 函数用 JavaScript 制作游戏。

今天我了解到传递给 requestAnimationFrame() 的回调获得了 self 们打开该页面以来测量的高分辨率时间。我们称它为 ms:

function paint(ms) {
    // draw my game
    requestAnimationFrame(paint);
}

requestAnimationFrame(paint);

一切都很好,但有一件事我不太明白。

当我们转到另一个选项卡时,函数 requestAnimationFrame() 不会执行任何操作,因此渲染会暂停。另一方面,传递给回调的时间在我们离开时仍然继续。因此,我不确定如何使用该值。如果它与渲染引擎成比例地工作,我可以使用 ms 来计算我的游戏的逻辑时间,因为依赖 requestAnimationFrame() 作为稳定的 60 FPS 听起来并不喜欢最伟大的想法。

我错过了什么吗?如果 ms 参数在我们离开标签页时继续计数,它的目的是什么?

最佳答案

那只是一个时间戳,并没有什么实际意义。它实际上通常与 performance.now() 相同,后者给出自页面处于事件状态以来的时间量。至于为什么,这就是DOMHighResTimeStamp's origin已定义。

我们通常用它来了解自某个先前事件发生以来经过了多长时间,即我们存储一个开始时间,然后检查当前时间戳,我们可以获得动画的增量时间,而不管实际时间帧速率。

顺便说一下,不,依赖于 requestAnimationFrame 处于任何固定帧率确实不是一个好主意,requestAnimationFrame 不依赖于任何帧率根据规范,实际上建议将其与屏幕刷新率对齐(尽管只有 Blink 这样做)。

所以您实际上需要依赖这样的时间戳,以便在不同的设置中保持一致的速度。在每一帧执行一个简单的 pos++ 将使您的动画在 120Hz 显示器上的运行速度比在 60Hz 显示器上快两倍(至少在 Chrome 中是这样)。

这只会让您的想法变得更加复杂,难以理解它是如何实现的:当窗口移动到 120Hz 显示器时,您的绘画计时器会快两倍吗?

这个时间戳也可能有助于 catch 长帧,这并不是因为系统有问题你一定希望你的动画持续更长时间。
同样,并非所有情况都希望动画逻辑在窗口模糊时停止。假设我有一个带有由 rAF 驱动的背景动画的标题,我真的不希望它在离开屏幕时暂停,即使它没有被绘制。

如果您希望游戏逻辑在窗口模糊时暂停,请监听 onvisibilitychange ,并保存当前时间戳(使用 performance.now() 因为我们在 rAF 之外)。

关于javascript - 为什么毫秒计数器在 requestAnimationFrame() 中一直走?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58984325/

相关文章:

javascript - 如何从异步回调函数中更新全局变量?

javascript - 如何从 dojo 商店的项目数​​组中删除对象

javascript - 使用钩子(Hook)取消 React 组件中的 requestAnimationRequest 不起作用

javascript - setTimeOut 产生 233 fps 而 requestAnimationFrame 产生 61

javascript - requestAnimationFrame 之前不必要的延迟?

javascript - 在 jQuery 中的 .css() 操作之前使用 .delay() 函数

javascript - IE 不会切换元素

ASP.Net 脚本控件,从 OnClick 和 FireFox 返回 False

javascript - 要在单个页面中执行两个动画,一个在 Canvas 中一个在另一个上

javascript - 等待所有 dom 更新完成