Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ai/offscreen-canvas
Polyfill for OffscreenCanvas to move Three.js/WebGL/2D canvas to Web Worker
https://github.com/ai/offscreen-canvas
Last synced: 20 days ago
JSON representation
Polyfill for OffscreenCanvas to move Three.js/WebGL/2D canvas to Web Worker
- Host: GitHub
- URL: https://github.com/ai/offscreen-canvas
- Owner: ai
- License: mit
- Created: 2019-03-26T17:47:44.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-03T18:35:01.000Z (almost 2 years ago)
- Last Synced: 2024-10-12T00:47:12.289Z (2 months ago)
- Language: JavaScript
- Homepage:
- Size: 1.37 MB
- Stars: 334
- Watchers: 9
- Forks: 13
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-list - offscreen-canvas
- awesome-list - offscreen-canvas
README
# Offscreen Canvas Polyfill
JS polyfill (**375 bytes**) for `OffscreenCanvas` to move **Three.js**,
**WebGL** or 2D canvas to **Web Worker**.It will improve performance in Chrome and will load worker by ``
in Firefox, Safari, and other browsers.The tutorial for this library:
**[Faster WebGL/Three.js 3D graphics with OffscreenCanvas and Web Workers]**.```js
// index.js
import createWorker from 'offscreen-canvas/create-worker'const worker = createWorker(canvas, '/worker.js', e => {
// Messages from the worker
})button.addEventListener('click', () => {
worker.post({ message: 'update' })
})
``````js
// worker.js
import insideWorker from 'offscreen-canvas/inside-worker'const worker = insideWorker(e => {
if (e.data.canvas) {
// Draw on the canvas
} else if (e.data.message === 'move') {
// Messages from main thread
}
})
```[Faster WebGL/Three.js 3D graphics with OffscreenCanvas and Web Workers]: https://dev.to/evilmartians/faster-webgl-three-js-3d-graphics-with-offscreencanvas-and-web-workers-43he
<a href="https://evilmartians.com/?utm_source=offscreen-canvas">
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
alt="Sponsored by Evil Martians" width="236" height="54">
</a>## Usage
Create separated bundle in webpack, Parcel or any other bundler:
```diff js
entry: {
app: './src/app.js',
+ worker: './src/worker.js'
}
```Move all code working with `<canvas>` to `worker.js`. It means to move all WebGL
or Three.js imports and scene related code.```js
import insideWorker from 'offscreen-canvas/inside-worker'
// Move Three.js imports here if you use Three.jsconst worker = insideWorker(e => {
if (e.data.canvas) {
// Move scene building code here
}
})
```Some of Three.js code (mostly loaders) will not work in Web Worker.
Use `worker.isWorker` to switch loaders:```js
if (worker.isWorker) {
loader = new ImageBitmapLoader()
} else {
loader = new ImageLoader()
}
```Put preload link to HTML templates with a URL to `worker.js`.
Your bundle will add cache buster to bundle names, so bundle names will
change every time you deploy application. This is why we need to store
path to `worker.js` in HTML:```diff html
+ <link rel="preload" as="script" href="./worker.js">
</head>
```Load worker in main `app.js`:
```js
import createWorker from 'offscreen-canvas/create-worker'const workerUrl = document.querySelector('[rel=preload][as=script]').href
const canvas = document.querySelector('canvas')const worker = createWorker(canvas, workerUrl)
```Keep all UI interaction code (listeners for clicks, mouse move, etc)
in `app.js`. Send message to Worker when your need to update `<canvas>`
after user actions:```js
button.addEventListener('click', () => {
worker.post({ message: 'move' })
})
```Process this messages in the worker:
```diff js
const worker = insideWorker(e => {
if (e.data.canvas) {
// Move scene building code here
- }
+ } else if (e.data.message === 'move') {
+ // Move object on the scene
+ }
})
```