blob: f7609dee6624fe4b056f3053fef2c86834c81303 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
---
title: OffscreenCanvas
slug: Web/API/OffscreenCanvas
tags:
- API
- Canvas
- Experimental
- Interface
- Reference
translation_of: Web/API/OffscreenCanvas
---
<div>{{APIRef("Canvas API")}} {{SeeCompatTable}}</div>
<p><strong><code>OffscreenCanvas提供了一个可以脱离屏幕渲染的canvas对象。它在窗口环境和<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Workers_API">web worker</a>环境均有效。</code></strong></p>
<h2 id="构造函数">构造函数</h2>
<dl>
<dt>{{domxref("OffscreenCanvas.OffscreenCanvas", "OffscreenCanvas()")}}</dt>
<dd><code>OffscreenCanvas构造函数。创建一个新的</code><code>OffscreenCanvas对象。</code></dd>
</dl>
<h2 id="属性">属性</h2>
<dl>
<dt>{{domxref("OffscreenCanvas.height")}}</dt>
<dd>offscreen canvas对象的高度。</dd>
<dt>{{domxref("OffscreenCanvas.width")}}</dt>
<dd>offscreen canvas对象的宽度。</dd>
</dl>
<h2 id="方法">方法</h2>
<dl>
<dt>{{domxref("OffscreenCanvas.getContext()")}}</dt>
<dd>为offscreen canvas对象返回一个渲染画布。</dd>
</dl>
<dl>
<dt>{{domxref("OffscreenCanvas.toBlob()")}}</dt>
<dd>创建一个代表canvas中的图像的{{domxref("Blob")}}对象。</dd>
</dl>
<dl>
<dt>{{domxref("OffscreenCanvas.transferToImageBitmap()")}}</dt>
<dd>从<code>OffscreenCanvas最近渲染的图像</code>创建一个 {{domxref("ImageBitmap")}} 对象。</dd>
</dl>
<h2 id="例子">例子</h2>
<h3 id="同步显示OffscreenCanvas中的帧">同步显示<code>OffscreenCanvas中的帧</code></h3>
<p>一种方式是使用<code>OffscreenCanvas</code> API,也就是用已经包含<code>OffscreenCanvas</code>对象的{{domxref("RenderingContext")}} 来生成新的帧。 每次一个新的帧在画布中完成渲染,{{domxref("OffscreenCanvas.transferToImageBitmap", "transferToImageBitmap()")}} 方法都会被调用来保存最近渲染的图像。该方法返回一个{{domxref("ImageBitmap")}}对象,该对象可以被用在各种Web APIs中,也可以用在下一个canvas中,并且不需要转换备份。</p>
<p>为了显示<code>ImageBitmap</code>,你可以用{{domxref("ImageBitmapRenderingContext")}}上下文,通过一个canvas(可见的)元素调用<code>canvas.getContext("bitmaprenderer")</code>方法来创建它。该上下文只提供用<code>ImageBitmap</code>替换canvas的内容的功能。调用{{domxref("ImageBitmapRenderingContext.transferFromImageBitmap()")}} 以前的渲染结果并且通过OffscreenCanvas保存<code>ImageBitmap</code>,会在canvas里显示<code>ImageBitmap</code>并且转换其所有权到canvas。 一个单独的OffscreenCanvas可以将帧转换到任意数量的其他<code>ImageBitmapRenderingContext</code>对象。</p>
<p>提供两个 {{HTMLElement("canvas")}} 元素</p>
<pre class="brush: html notranslate"><canvas id="one"></canvas>
<canvas id="two"></canvas></pre>
<p>下面的代码会用<code>OffscreenCanva提供渲染结果,就像上面描述的一样。</code></p>
<pre class="brush: js notranslate">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);
</pre>
<h3 id="异步显示OffscreenCanvas生成的帧"> 异步显示<code>OffscreenCanvas生成的帧</code></h3>
<p><code>另一种使用 OffscreenCanvas</code> API的方式, 是在一个{{HTMLElement("canvas")}}元素上调用{{domxref("HTMLCanvasElement.transferControlToOffscreen", "transferControlToOffscreen()")}}, 也可以在<a href="/en-US/docs/Web/API/Web_Workers_API">worker</a>或主线程,上调用,这将从主线程的{{domxref("HTMLCanvasElement")}}对象返回一个<code>OffscreenCanvas对象。调用</code>{{domxref("OffscreenCanvas.getContext", "getContext()")}} 会从这个<code>OffscreenCanvas获取一个<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/RenderingContext">RenderingContext </a>。</code></p>
<p>main.js (主线程代码):</p>
<pre class="brush: js notranslate">var htmlCanvas = document.getElementById("canvas");
var offscreen = htmlCanvas.transferControlToOffscreen();
var worker = new Worker("offscreencanvas.js");
worker.postMessage({canvas: offscreen}, [offscreen]);
</pre>
<p>offscreencanvas.js (web work代码):</p>
<pre class="brush: js notranslate">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();
};
</pre>
<p>也可以在 worker 中使用 requestAnimationFrame</p>
<pre class="brush: js notranslate">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);
};</pre>
<h2 id="规范">规范</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">规范</th>
<th scope="col">状态</th>
<th scope="col">备注</th>
</tr>
<tr>
<td>{{SpecName('HTML WHATWG', "scripting.html#the-offscreencanvas-interface", "OffscreenCanvas")}}</td>
<td>{{Spec2('HTML WHATWG')}}</td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<div>
<p>{{Compat("api.OffscreenCanvas")}}</p>
</div>
<h2 id="另请参见">另请参见</h2>
<ul>
<li><a href="https://hacks.mozilla.org/2016/01/webgl-off-the-main-thread/">WebGL Off the Main Thread – Mozilla Hacks</a></li>
<li>{{domxref("CanvasRenderingContext2D")}}</li>
<li>{{domxref("ImageBitmap")}}</li>
<li>{{domxref("ImageBitmapRenderingContext")}}</li>
<li>{{domxref("HTMLCanvasElement.transferControlToOffscreen()")}}</li>
<li>{{domxref("WebGLRenderingContext.commit()")}}</li>
</ul>
<div id="gtx-anchor" style="position: absolute; left: 78px; top: 2140px; width: 183px; height: 20px;"></div>
<div class="jfk-bubble gtx-bubble" style="">
<div class="jfk-bubble-content-id" id="bubble-3">
<div id="gtx-host" style="max-width: 400px;"></div>
</div>
<div class="jfk-bubble-closebtn-id jfk-bubble-closebtn"></div>
<div class="jfk-bubble-arrow-id jfk-bubble-arrow jfk-bubble-arrowdown" style="left: 71.5px;">
<div class="jfk-bubble-arrowimplbefore"></div>
<div class="jfk-bubble-arrowimplafter"></div>
</div>
</div>
|