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 的定义 |
现行的标准 | - |
桌面浏览器兼容性
特性 | Chrome | Edge | Firefox | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|---|
基础支持 | 69 | 未知 | 441 | 不支持 | 56 | 不支持 |
OffscreenCanvas() 构造函数 | 69 | 未知 | 461 | 不支持 | 56 | 不支持 |
convertToBlob | 69 | 未知 | 4612 | 不支持 | 56 | 不支持 |
getContext | 69 | 未知 | 441 | 不支持 | 56 | 不支持 |
height | 69 | 未知 | 441 | 不支持 | 56 | 不支持 |
transferToImageBitmap | 69 | 未知 | 461 | 不支持 | 56 | 不支持 |
width | 69 | 未知 | 441 | 不支持 | 56 | 不支持 |
移动浏览器兼容性
特性 | Android | Chrome for Android | Edge mobile | Firefox for Android | IE mobile | Opera Android | iOS 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
支持。