OffscreenCanvas

Baseline 广泛可用 *

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

* 此特性的某些部分可能存在不同级别的支持。

注意:此功能在 Web Workers 中可用。

在使用 <canvas> 元素或 Canvas API 时,渲染、动画和用户交互通常发生在 Web 应用程序的主执行线程上。与 Canvas 动画和渲染相关的计算可能会对应用程序性能产生重大影响。

OffscreenCanvas 接口提供了一个可以在屏幕外渲染的 Canvas,将 DOM 与 Canvas API 分解开,因此 <canvas> 元素不再完全依赖于 DOM。渲染操作也可以在 Worker 上下文中运行,这允许您在单独的线程中运行某些任务,并避免在主线程上执行繁重的工作。

OffscreenCanvas 是一个 可转移对象

EventTarget OffscreenCanvas

构造函数

OffscreenCanvas()

OffscreenCanvas 构造函数。创建一个新的 OffscreenCanvas 对象。

实例属性

OffscreenCanvas.height

离屏 Canvas 的高度。

OffscreenCanvas.width

离屏 Canvas 的宽度。

实例方法

OffscreenCanvas.getContext()

返回离屏 Canvas 的绘图上下文,如果上下文标识符不受支持,或者离屏 Canvas 已被设置为不同的上下文模式,则返回 null

OffscreenCanvas.convertToBlob()

创建一个表示 Canvas 中图像的 Blob 对象。

OffscreenCanvas.transferToImageBitmap()

OffscreenCanvas 最近渲染的图像创建一个 ImageBitmap 对象。请参阅其参考文档,了解有关管理此 ImageBitmap 的重要注意事项。

事件

继承其父级 EventTarget 的事件。

使用 addEventListener() 监听这些事件,或通过将事件监听器分配给此接口的 oneventname 属性。

contextlost

如果浏览器检测到 OffscreenCanvasRenderingContext2D 上下文丢失,则触发此事件。

contextrestored

如果浏览器成功恢复了 OffscreenCanvasRenderingContext2D 上下文,则触发此事件。

示例

同步显示 OffscreenCanvas 生成的帧

使用 OffscreenCanvas API 的一种方法是使用从 OffscreenCanvas 对象获得的渲染上下文来生成新帧。一旦在新帧在此上下文中完成渲染,就可以调用 transferToImageBitmap() 方法来保存最近渲染的图像。此方法返回一个 ImageBitmap 对象,该对象可用于各种 Web API,也可在第二个 Canvas 中使用,而无需创建传输副本。

要显示 ImageBitmap,可以使用 ImageBitmapRenderingContext 上下文,该上下文可以通过在(可见的)Canvas 元素上调用 canvas.getContext("bitmaprenderer") 来创建。此上下文仅提供将 Canvas 内容替换为给定 ImageBitmap 的功能。将之前渲染并保存的 OffscreenCanvasImageBitmap 传递给 ImageBitmapRenderingContext.transferFromImageBitmap() 会将 ImageBitmap 显示在 Canvas 上,并将其所有权转移给 Canvas。单个 OffscreenCanvas 可以将帧传输到任意数量的其他 ImageBitmapRenderingContext 对象。

给定这两个 <canvas> 元素

html
<canvas id="one"></canvas> <canvas id="two"></canvas>

以下代码将按照上述描述提供使用 OffscreenCanvas 的渲染。

js
const one = document.getElementById("one").getContext("bitmaprenderer");
const two = document.getElementById("two").getContext("bitmaprenderer");

const offscreen = new OffscreenCanvas(256, 256);
const gl = offscreen.getContext("webgl");

// Perform some drawing for the first canvas using the gl context
const bitmapOne = offscreen.transferToImageBitmap();
one.transferFromImageBitmap(bitmapOne);

// Perform some more drawing for the second canvas
const bitmapTwo = offscreen.transferToImageBitmap();
two.transferFromImageBitmap(bitmapTwo);

异步显示 OffscreenCanvas 生成的帧

使用 OffscreenCanvas API 的另一种方法是在 <canvas> 元素上调用 transferControlToOffscreen(),无论是在 Worker 还是主线程上,这将从主线程的 HTMLCanvasElement 对象返回一个 OffscreenCanvas 对象。然后调用 getContext() 将从该 OffscreenCanvas 获取渲染上下文。

main.js 脚本(主线程)可能如下所示

js
const htmlCanvas = document.getElementById("canvas");
const offscreen = htmlCanvas.transferControlToOffscreen();

const worker = new Worker("offscreen-canvas.js");
worker.postMessage({ canvas: offscreen }, [offscreen]);

offscreen-canvas.js 脚本(Worker 线程)可能如下所示

js
onmessage = (evt) => {
  const canvas = evt.data.canvas;
  const gl = canvas.getContext("webgl");
  // Perform some drawing using the gl context
};

在 Worker 中使用 requestAnimationFrame() 也是可能的

js
onmessage = (evt) => {
  const canvas = evt.data.canvas;
  const gl = canvas.getContext("webgl");

  function render(time) {
    // Perform some drawing using the gl context
    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);
};

有关完整示例,请参阅 GitHub 上的 OffscreenCanvas 示例源代码,或 实时运行 OffscreenCanvas 示例

规范

规范
HTML
# the-offscreencanvas-interface

浏览器兼容性

另见