OffscreenCanvas

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

OffscreenCanvas提供了一个可以脱离屏幕渲染的canvas对象。它在窗口环境和web worker环境均有效。

构造函数

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

属性

OffscreenCanvas.height
offscreen canvas对象的高度。
OffscreenCanvas.width
offscreen canvas对象的宽度。

方法

OffscreenCanvas.getContext()
为offscreen canvas对象返回一个渲染画布。
OffscreenCanvas.toBlob()
创建一个代表canvas中的图像的Blob对象。
OffscreenCanvas.transferToImageBitmap()
OffscreenCanvas最近渲染的图像创建一个 ImageBitmap 对象。

例子

同步显示OffscreenCanvas中的帧

一种方式是使用OffscreenCanvas API,也就是用已经包含OffscreenCanvas对象的RenderingContext 来生成新的帧。 每次一个新的帧在画布中完成渲染,transferToImageBitmap() 方法都会被调用来保存最近渲染的图像。该方法返回一个ImageBitmap对象,该对象可以被用在各种Web APIs中,也可以用在下一个canvas中,并且不需要转换备份。

为了显示ImageBitmap,你可以用ImageBitmapRenderingContext上下文,通过一个canvas(可见的)元素调用canvas.getContext("bitmaprenderer")方法来创建它。该上下文只提供用ImageBitmap替换canvas的内容的功能。调用ImageBitmapRenderingContext.transferFromImageBitmap() 以前的渲染结果并且通过OffscreenCanvas保存ImageBitmap,会在canvas里显示ImageBitmap并且转换其所有权到canvas。 一个单独的OffscreenCanvas可以将帧转换到任意数量的其他ImageBitmapRenderingContext对象。

提供两个 <canvas> 元素

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

下面的代码会用OffscreenCanva提供渲染结果,就像上面描述的一样。

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

// ... some drawing for the first canvas using the gl context ...

// Commit rendering to the first canvas
var bitmapOne = offscreen.transferToImageBitmap();
one.transferFromImageBitmap(bitmapOne);

// ... some more drawing for the second canvas using the gl context ...

// Commit rendering to the second canvas
var bitmapTwo = offscreen.transferToImageBitmap();
two.transferFromImageBitmap(bitmapTwo);

 异步显示OffscreenCanvas生成的帧

另一种使用 OffscreenCanvas API的方式, 是在一个<canvas>元素上调用transferControlToOffscreen(), 也可以在worker或主线程,上调用,这将从主线程的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 (web work代码):

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

  // ... some drawing using the gl context ...

  // Push frames back to the original HTMLCanvasElement
  gl.commit();
};

也可以在 worker 中使用 requestAnimationFrame

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

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

规范

规范 状态 备注
HTML Living Standard
OffscreenCanvas
Living Standard

浏览器兼容性

BCD tables only load in the browser

另请参见