DedicatedWorkerGlobalScope: cancelAnimationFrame() 方法

Baseline 已广泛支持

此功能已成熟,并可在许多设备和浏览器版本上运行。自 2023 年 3 月以来,它已在各种浏览器中可用。

注意:此功能仅在 专用 Web Worker 中可用。

DedicatedWorkerGlobalScope 接口的 cancelAnimationFrame() 方法会取消通过调用 requestAnimationFrame() 方法先前计划的动画帧请求。

调用 cancelAnimationFrame() 方法需要当前 worker 拥有一个关联的 Window 对象。这意味着当前 worker 必须由 Window 对象创建,或者由一个也拥有关联 Window 对象的专用 worker 创建。

语法

js
cancelAnimationFrame(handle)

参数

handle

通过调用 requestAnimationFrame() 返回的 ID 值;该调用必须在同一个 worker 中进行。

返回值

无(undefined)。

异常

NotSupportedError DOMException

如果当前 worker 不支持该方法,则会抛出此错误。

示例

这是一个完整的示例,展示了如何在专用 worker 中使用带有 OffscreenCanvasrequestAnimationFrame()

HTML 代码应包含

html
<canvas width="100" height="100"></canvas>

它应该链接到以下 JavaScript

js
const worker = new Worker("worker.js");

// Transfer canvas control to the worker
const offscreenCanvas = document
  .querySelector("canvas")
  .transferControlToOffscreen();

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

// Stop the animation after 5 seconds
setTimeout(() => {
  worker.postMessage({
    type: "stop",
  });
}, 5000);

worker.js

js
let ctx;
let pos = 0;
let animationId;
let isRunning = false;
let lastTime = 0;

function draw(currentTime) {
  if (!isRunning) return;

  // Calculate delta time for smooth animation
  if (lastTime === 0) lastTime = currentTime;
  const deltaTime = (currentTime - lastTime) / 1000;
  lastTime = currentTime;

  // Clear and draw the moving rectangle
  ctx.clearRect(0, 0, 100, 100);
  ctx.fillRect(pos, 0, 10, 10);
  pos += 50 * deltaTime; // Move 50 pixels per second

  // Loop the animation
  if (pos > 100) pos = -10;

  animationId = self.requestAnimationFrame(draw);
}

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

在主线程中,我们首先使用 HTMLCanvasElement.transferControlToOffscreen() 将一个 <canvas> 元素的控制权转移给一个 OffscreenCanvas,然后发送一个 "start" 消息到 worker,以启动其工作,并将 OffscreenCanvas 传递给它。

在 worker 文件 (worker.js) 中,我们处理动画逻辑。当收到 "start" 消息时,worker 开始动画,使矩形从左到右移动。收到 "stop" 消息后,它会停止动画。

最后,主线程可以在延迟后向 worker 发送 "stop" 消息来停止动画,这样在停止之前可以看到动画。

规范

规范
HTML
# animationframeprovider-cancelanimationframe

浏览器兼容性

另见