Use WebWorker
Welcome to the alpha version! Please feel free to use it and share your feedback with us 🎉
Compatibility: Only Chrome 69+ browsers are supported
The purpose is to meet the complex scenario of playing multiple PAG animations on the same screen and avoid blocking the main thread when the PAG is rendering.
Starting from libpag@4.2 + version, libpag.js is allowed to run in WebWorker, and libpag.worker.js is added as the main thread entry of WebWorker version in the packaging product.
Enrty
Initialization
libpag.worker.js serves as the main thread entry and can be initialized by introducing its createPAGWorker
.
import { createPAGWorker } from 'libpag.worker.esm.js';
const worker = await createPAGWorker({
locateFile: (file) => {
if (file === 'libpag.wasm') {
return 'lib/libpag.wasm';
}
if (file === 'libpag.js') {
return 'lib/libpag.min.js';
}
return file;
},
});
The parameters received by createPAGWorker
are consistent with those of PAGInit
. In addition to the initialization parameters of Emscripten, it includes a locateFile
hook for developers to specify the path of the wasm file and the JS file that the worker runs.
It should be noted that createPAGWorker
returns a Worker
object, not a PAG
object.
It is also recommended to avoid initializing more than 4 PAGViews in one WebWorker, as there can only be a maximum of 4 WebGL Active Contexts in the same WebWorker. However, you can bypass this limitation by using the useCanvas2D
attribute.
Quick Start
To facilitate rapid adoption of the WebWorker version, we encapsulate the WebWorker-specific WorkerPAGFile
WorkerPAGImage
and WorkerPAGView
classes in the libpag.worker.js file.
These classes include common interfaces such as play, text replacement, and image replacement. For more advanced usage, see Advanced Usage below.
Play:
import { WorkerPAGFile, WorkerPAGView } from 'libpag.worker.esm.js';
const buffer = await fetch('../assets/test.pag').then((res) => res.arrayBuffer());
const canvas = document.createElement('canvas');
canvas.width = 300;
canvas.height = 300;
document.body.appendChild(canvas);
const pagFile = await WorkerPAGFile.load(worker, buffer);
const pagView = await WorkerPAGView.init(pagFile, canvas);
if (pagView) {
pagView.play();
}
Text Replacement:
import { WorkerPAGFile } from 'libpag.worker.esm.js';
const pagFile = await WorkerPAGFile.load(worker, buffer);
const textData = await pagFile.getTextData(0);
textData.text = "Hello World!"
await pagFile.replaceText(0, textData);
Image Replacement:
import { WorkerPAGImage } from 'libpag.worker.esm.js';
const image = await new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve(img);
img.src = '../assets/cat.png';
});
const pagImage = await WorkerPAGImage.fromSource(worker, image);
pagFile.replaceImage(0, pagImage);
pagImage.destroy();
Complete example: https://github.com/libpag/pag-web/blob/main/pages/web-worker.html
Advanced Usage
Libpag.worker.js encapsulates commonly used simple APIs. If developers have more complex requirements, it is recommended to write the logic in libpag.js in WebWorker. This helps to prevent performance loss from duplicated communication between the main thread and WebWorker, and also avoids redundant volume when re-encapsulating all interfaces into libpag.worker.js.