Use WebWorker
当前为 alpha 版本,欢迎使用与反馈🎉
兼容性:仅支持 Chrome 69+ 浏览器
为满足同屏播放多个 PAG 动效的复杂场景,与避免 PAG 进行渲染时阻塞主线程。
从 libpag@4.2 + 版本开始,libpag.js 允许在 WebWorker 中运行,并且打包产物中新增 libpag.worker.js 为 WebWorker 版本主线程入口。
入口
初始化
libpag.worker.js 做为主线程入口,可以引入它的 createPAGWorker
进行 libpag
的初始化。
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;
},
});
createPAGWorker
接收的参数与 PAGInit
一致,除 Emscripten 的初始化参数外,包括一个 locateFile
钩子,以供开发者自行指定 wasm 文件和 worker 运行 JS 文件的 path。
需要注意的是,createPAGWorker
返回的是一个 Worker
对象,并不是一个 PAG
对象。
并且同个 WebWorker 中只能存在 4 个 WebGL Active Context,所以请避免在一个 WebWorker 中初始化 4 个以上 PAGView。当然上述条件可以搭配 useCanvas2D
属性,进行规避。
快速开始
为了开发者能快速地开始使用 WebWorker 版本,我们在 libpag.worker.js 文件中封装了 WebWorker 专用的 WorkerPAGFile
WorkerPAGImage
和 WorkerPAGView
类。
这几个类中,包括了如播放,替换文字,替换图片等常见的接口,更高级的用法见下文进阶开发。
播放:
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();
}
替换文字:
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);
替换图片:
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();
完整示例:https://github.com/libpag/pag-web/blob/main/pages/web-worker.html
高级用法
libpag.worker.js 中封装了比较常用的简单 API,如果开发者有更多复杂需求,建议将逻辑写在 WebWorker 中的 libpag.js 中。这样不但减少主线程与 WebWorker 的重复通信,造成性能损失,也避免将所有 libpag.js 中的接口二次封装到 libpag.worker.js 中出现冗余体积。