画布

基线 2023

新可用

2023 年 3 月起,此功能适用于最新的设备和浏览器版本。此功能可能不适用于旧设备或浏览器。

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

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

画布 接口提供了一个可以在屏幕外渲染的画布,将 DOM 和 Canvas API 解耦,以便 <canvas> 元素不再完全依赖于 DOM。渲染操作也可以在 worker 上下文中运行,允许您在单独的线程中运行某些任务,并避免在主线程上进行繁重的工作。

画布 是一个 可转移对象

EventTarget OffscreenCanvas

构造函数

画布()

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

实例属性

画布.height

画布的高度。

画布.width

画布的宽度。

实例方法

画布.getContext()

返回画布的渲染上下文。

画布.convertToBlob()

创建一个表示画布中包含的图像的 Blob 对象。

画布.transferToImageBitmap()

画布 的最近渲染的图像创建一个 ImageBitmap 对象。有关管理此 ImageBitmap 的重要说明,请参阅其参考。

事件

继承自父级 EventTarget 的事件。

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

contextlost

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

contextrestored

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

示例

同步显示由 画布 生成的帧

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

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

给定这两个 <canvas> 元素

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

以下代码将使用 画布 提供渲染,如上所述。

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);

异步显示由 画布 生成的帧

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

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

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

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

offscreencanvas.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 上的 画布示例源代码,或运行 画布示例现场

规范

规范
HTML 标准
# the-offscreencanvas-interface

浏览器兼容性

BCD 表格仅在浏览器中加载

另请参阅