OffscreenCanvas - 提供了可以在屏幕外渲染的画布

这是一个实验中的功能
此功能某些浏览器尚在开发中,请参考浏览器兼容性表格以得到在不同浏览器中适合使用的前缀。由于该功能对应的标准文档可能被重新修订,所以在未来版本的浏览器中该功能的语法和行为可能随之改变。

OffscreenCanvas 接口提供了可以在屏幕外渲染的画布。在窗口和 worker 上下文中均可用。

构造函数

OffscreenCanvas()

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

属性

OffscreenCanvas.height

屏幕外画布的高度。

OffscreenCanvas.width

屏幕外画布的宽度。

方法

OffscreenCanvas.getContext()

返回屏幕外画布的渲染上下文。

OffscreenCanvas.convertToBlob()

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

OffscreenCanvas.transferToImageBitmap()

创建一个 ImageBitmap 对象,该对象为 OffscreenCanvas 的最新渲染图像。

实例

同步显示由 OffscreenCanvas 产生的帧

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

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

给定这两个 <canvas> 元素

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

下面的代码将如上所述使用 OffscreenCanvas 提供渲染。

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

var offscreen = new OffscreenCanvas(256, 256);
var gl = offscreen.getContext('webgl');

// ... 使用 gl 上下文为第一个画布绘制一些图形 ...

// 提交渲染到第一个画布
var bitmapOne = offscreen.transferToImageBitmap();
one.transferFromImageBitmap(bitmapOne);

// ... 使用 gl 上下文为第二个画布进行更多绘制 ...

// 将渲染提交到第二个画布
var bitmapTwo = offscreen.transferToImageBitmap();
two.transferFromImageBitmap(bitmapTwo);

OffscreenCanvas 产生的帧的异步显示

使用 OffscreenCanvas API 的另一种方法是在 worker 或主线程上调用 <canvas> 元素的 transferControlToOffscreen(),它将从主线程的 HTMLCanvasElement 对象返回 OffscreenCanvas 对象。然后,调用 getContext() 将从该 OffscreenCanvas 获得 RenderingContext

main.js(主线程代码):

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

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

offscreencanvas.js(worker 代码):

onmessage = function(evt) {
  var canvas = evt.data.canvas;
  var gl = canvas.getContext("webgl");

  // ... 使用 gl 上下文的绘图 ...
};

您还可以在 worker 中使用 requestAnimationFrame

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

  function render(time) {
    // ... 使用 gl 上下文的绘图...
    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);
};

规范

规范 状态 备注
HTML Living Standard
OffscreenCanvas 的定义
现行的标准 -

桌面浏览器兼容性

特性ChromeEdgeFirefoxInternet ExplorerOperaSafari
基础支持69 未知441 不支持56 不支持
OffscreenCanvas() 构造函数69 未知461 不支持56 不支持
convertToBlob69 未知4612 不支持56 不支持
getContext69 未知441 不支持56 不支持
height69 未知441 不支持56 不支持
transferToImageBitmap69 未知461 不支持56 不支持
width69 未知441 不支持56 不支持

移动浏览器兼容性

特性AndroidChrome for AndroidEdge mobileFirefox for AndroidIE mobileOpera AndroidiOS Safari
基础支持 不支持69 未知441 未知48 不支持
OffscreenCanvas() 构造函数 不支持69 未知461 未知 支持 不支持
convertToBlob 不支持69 未知4612 未知48 不支持
getContext 不支持69 未知441 未知48 不支持
height 不支持69 未知441 未知48 不支持
transferToImageBitmap 不支持69 未知461 未知48 不支持
width 不支持69 未知441 未知48 不支持

1. 参阅 bug 1390089

2. 通过 toBlob 支持。

相关链接