-
Notifications
You must be signed in to change notification settings - Fork 22.4k
/
index.md
141 lines (98 loc) · 6.82 KB
/
index.md
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
---
title: OffscreenCanvas
slug: Web/API/OffscreenCanvas
page-type: web-api-interface
browser-compat: api.OffscreenCanvas
---
{{APIRef("Canvas API")}}{{AvailableInWorkers}}
When using the {{HtmlElement("canvas")}} element or the [Canvas API](/en-US/docs/Web/API/Canvas_API), rendering, animation, and user interaction usually happen on the main execution thread of a web application.
The computation relating to canvas animations and rendering can have a significant impact on application performance.
The **`OffscreenCanvas`** interface provides a canvas that can be rendered off screen, decoupling the DOM and the Canvas API so that the {{HtmlElement("canvas")}} element is no longer entirely dependent on the DOM.
Rendering operations can also be run inside a [worker](/en-US/docs/Web/API/Web_Workers_API) context, allowing you to run some tasks in a separate thread and avoid heavy work on the main thread.
`OffscreenCanvas` is a [transferable object](/en-US/docs/Web/API/Web_Workers_API/Transferable_objects).
{{InheritanceDiagram}}
## Constructors
- {{domxref("OffscreenCanvas.OffscreenCanvas", "OffscreenCanvas()")}}
- : `OffscreenCanvas` constructor. Creates a new `OffscreenCanvas` object.
## Instance properties
- {{domxref("OffscreenCanvas.height")}}
- : The height of the offscreen canvas.
- {{domxref("OffscreenCanvas.width")}}
- : The width of the offscreen canvas.
## Instance methods
- {{domxref("OffscreenCanvas.getContext()")}}
- : Returns a rendering context for the offscreen canvas.
- {{domxref("OffscreenCanvas.convertToBlob()")}}
- : Creates a {{domxref("Blob")}} object representing the image contained in the canvas.
- {{domxref("OffscreenCanvas.transferToImageBitmap()")}}
- : Creates an {{domxref("ImageBitmap")}} object from the most recently rendered image of the `OffscreenCanvas`. See the {{domxref("OffscreenCanvas.transferToImageBitmap()", "API description")}} for important notes on managing this {{domxref("ImageBitmap")}}.
## Events
_Inherits events from its parent, {{domxref("EventTarget")}}._
Listen to these events using {{DOMxRef("EventTarget.addEventListener", "addEventListener()")}} or by assigning an event listener to the `oneventname` property of this interface.
- [`contextlost`](/en-US/docs/Web/API/OffscreenCanvas/contextlost_event)
- : Fired if the browser detects that an [`OffscreenCanvasRenderingContext2D`](/en-US/docs/Web/API/OffscreenCanvasRenderingContext2D) context is lost.
- [`contextrestored`](/en-US/docs/Web/API/OffscreenCanvas/contextrestored_event)
- : Fired if the browser successfully restores an [`OffscreenCanvasRenderingContext2D`](/en-US/docs/Web/API/OffscreenCanvasRenderingContext2D) context.
## Examples
### Synchronous display of frames produced by an `OffscreenCanvas`
One way to use the `OffscreenCanvas` API is to use a rendering context that has been obtained from an `OffscreenCanvas` object to generate new frames. Once a new frame has finished rendering in this context, the {{domxref("OffscreenCanvas.transferToImageBitmap", "transferToImageBitmap()")}} method can be called to save the most recent rendered image. This method returns an {{domxref("ImageBitmap")}} object, which can be used in a variety of Web APIs and also in a second canvas without creating a transfer copy.
To display the `ImageBitmap`, you can use an {{domxref("ImageBitmapRenderingContext")}} context, which can be created by calling `canvas.getContext("bitmaprenderer")` on a (visible) canvas element. This context only provides functionality to replace the canvas's contents with the given `ImageBitmap`. A call to {{domxref("ImageBitmapRenderingContext.transferFromImageBitmap()")}} with the previously rendered and saved `ImageBitmap` from the OffscreenCanvas, will display the `ImageBitmap` on the canvas and transfer its ownership to the canvas. A single `OffscreenCanvas` may transfer frames into an arbitrary number of other `ImageBitmapRenderingContext` objects.
Given these two {{HTMLElement("canvas")}} elements
```html
<canvas id="one"></canvas> <canvas id="two"></canvas>
```
the following code will provide the rendering using `OffscreenCanvas` as described above.
```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);
```
### Asynchronous display of frames produced by an `OffscreenCanvas`
Another way to use the `OffscreenCanvas` API, is to call {{domxref("HTMLCanvasElement.transferControlToOffscreen", "transferControlToOffscreen()")}} on a {{HTMLElement("canvas")}} element, either on a [worker](/en-US/docs/Web/API/Web_Workers_API) or the main thread, which will return an `OffscreenCanvas` object from an {{domxref("HTMLCanvasElement")}} object from the main thread. Calling {{domxref("OffscreenCanvas.getContext", "getContext()")}} will then obtain a rendering context from that `OffscreenCanvas`.
The `main.js` script (main thread) may look like this:
```js
const htmlCanvas = document.getElementById("canvas");
const offscreen = htmlCanvas.transferControlToOffscreen();
const worker = new Worker("offscreencanvas.js");
worker.postMessage({ canvas: offscreen }, [offscreen]);
```
While the `offscreencanvas.js` script (worker thread) can look like this:
```js
onmessage = (evt) => {
const canvas = evt.data.canvas;
const gl = canvas.getContext("webgl");
// Perform some drawing using the gl context
};
```
It's also possible to use {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} in workers:
```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);
};
```
For a full example, see the [OffscreenCanvas example source](https://github.com/mdn/dom-examples/tree/main/web-workers/offscreen-canvas-worker) on GitHub or run the [OffscreenCanvas example live](https://mdn.github.io/dom-examples/web-workers/offscreen-canvas-worker/).
## Specifications
{{Specifications}}
## Browser compatibility
{{Compat}}
## See also
- {{domxref("CanvasRenderingContext2D")}}
- {{domxref("OffscreenCanvasRenderingContext2D")}}
- {{domxref("ImageBitmap")}}
- {{domxref("ImageBitmapRenderingContext")}}
- {{domxref("HTMLCanvasElement.transferControlToOffscreen()")}}
- {{domxref("Window.requestAnimationFrame()", "requestAnimationFrame()")}}
- [WebGL Off the Main Thread – Mozilla Hacks](https://hacks.mozilla.org/2016/01/webgl-off-the-main-thread/) (2016)