这里的问题是,Web Worker 在一个非常孤立的上下文中运行,其中许多用于在网站(窗口、文档等)上运行的 javascript 存在的标准全局变量并不存在,不幸的是,如果没有这些变量,p5.js 就无法加载变量。您可以尝试用假版本来填充它们。这是一个基本示例:
let loadHandlers = [];
window = {
performance: performance,
document: {
hasFocus: () => true,
createElementNS: (ns, elem) => {
console.warn(`p5.js tryied to created a DOM element '${ns}:${elem}`);
// Web Workers don't have a DOM
return {};
}
},
screen: {},
addEventListener: (e, handler) => {
if (e === "load") {
loadHandlers.push(handler);
} else {
console.warn(`p5.js tried to added an event listener for '${e}'`);
}
},
removeEventListener: () => {},
location: {
href: "about:blank",
origin: "null",
protocol: "about:",
host: "",
hostname: "",
port: "",
pathname: "blank",
search: "",
hash: ""
}
};
document = window.document;
screen = window.screen;
// Without a setup function p5.js will not declare global functions
window.setup = () => {
window.noCanvas();
window.noLoop();
};
importScripts("/p5.js");
// Initialize p5.js
for (const handler of loadHandlers) {
handler();
}
postMessage({ color: "green" });
onmessage = msg => {
if (msg.data === "getRandomColor") {
// p5.js places all of its global declarations on window
postMessage({
color: window.random([
"red",
"limegreen",
"blue",
"magenta",
"yellow",
"cyan"
])
});
}
};
这仅适用于 p5.js 函数的有限子集。任何绘制到画布上的函数肯定都不起作用。我会谨慎尝试来回传递对象(即 p5.Vector、p5.Color 等),因为通过 postMessage 发送的所有内容都会被序列化和反序列化。
我已经发布了此示例的工作版本关于故障 https://glitch.com/edit/#!/p5js-web-worker.