DedicatedWorkerGlobalScope:requestAnimationFrame() 方法

基线 2023

新可用

2023 年 3 月起,此功能在最新的设备和浏览器版本中均可使用。此功能可能在较旧的设备或浏览器中无法使用。

注意:此功能仅在专用 Web 工作线程中可用。

requestAnimationFrame() 方法是 DedicatedWorkerGlobalScope 接口的方法,它告诉浏览器您希望执行动画帧请求并在下一次重绘之前调用用户提供的回调函数。

对回调函数的调用频率通常与显示刷新率匹配。最常见的刷新率是 60 Hz(每秒 60 个周期/帧),尽管 75 Hz、120 Hz 和 144 Hz 也被广泛使用。当在后台选项卡或隐藏的 <iframe> 中运行时,大多数浏览器都会暂停 requestAnimationFrame() 调用,以提高性能和延长电池寿命。

requestAnimationFrame() 方法的调用仅安排对回调函数的一次调用。如果要为下一帧设置动画,则回调函数必须再次调用 requestAnimationFrame()

警告:务必始终使用第一个参数(或其他某种获取当前时间的方法)来计算动画在一帧中将前进多少——否则,动画将在高刷新率屏幕上运行得更快。有关执行此操作的方法,请参见下面的示例。

调用 requestAnimationFrame() 方法需要当前工作线程具有关联的拥有者 window。这意味着当前工作线程必须由 window 或也具有关联的拥有者 window 的专用工作线程创建。

语法

js
requestAnimationFrame(callback)

参数

callback

在需要更新动画以进行下一次重绘时要调用的函数。此回调函数传递一个参数

timestamp

一个 DOMHighResTimeStamp,指示前一帧渲染的结束时间(基于自 时间原点 以来的毫秒数)。时间戳是十进制数,以毫秒为单位,但最小精度为 1 毫秒。时间戳值也类似于在回调函数开始时调用 performance.now(),但它永远不会是相同的值。

当由 requestAnimationFrame() 排队的多个回调开始在一帧中触发时,即使在计算每个先前回调的工作负载期间已经过去了一段时间,每个回调也会收到相同的时间戳。

返回值

一个 long 整数值,它是唯一标识回调列表中条目的请求 ID。这是一个非零值,但您不能对它做出任何其他假设。您可以将此值传递给 cancelAnimationFrame() 以取消刷新回调请求,取消操作必须在同一工作线程中进行。

异常

NotSupportedError DOMException

如果当前工作线程不支持该方法,则抛出。

示例

在主线程中,我们首先使用 HTMLCanvasElement.transferControlToOffscreen()<canvas> 元素的控制权转移到 OffscreenCanvas,然后向工作线程发送一条消息以“启动”其使用离屏画布的工作。

js
const offscreenCanvas = document
  .querySelector("canvas")
  .transferControlToOffscreen();

worker.postMessage(
  {
    type: "start",
    canvas: offscreenCanvas,
  },
  [offscreenCanvas],
);

在收到“启动”消息后,工作线程开始动画,将矩形从左移到右。在收到“停止”消息后,它将停止动画。

js
let ctx;
let pos = 0;
let handle;

function draw(dt) {
  ctx.clearRect(0, 0, 100, 100);
  ctx.fillRect(pos, 0, 10, 10);
  pos += 10 * dt;
  handle = self.requestAnimationFrame(draw);
}

self.addEventListener("message", (e) => {
  if (e.data.type === "start") {
    const transferredCanvas = e.data.canvas;
    ctx = transferredCanvas.getContext("2d");
    handle = self.requestAnimationFrame(draw);
  }
  if (e.data.type === "stop") {
    self.cancelAnimationFrame(handle);
  }
});

最后,如果需要,主线程可以向工作线程发送“停止”消息以停止动画。

js
worker.postMessage({
  type: "stop",
});

规范

规范
HTML 标准
# dom-animationframeprovider-requestanimationframe

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参阅