“未捕获引用错误:未定义窗口”p5.js web worker

polkgigr  于 2021-09-13  发布在  Java
关注(0)|答案(1)|浏览(410)

我有一个javascript代码,其中我将web worker与p5.js库一起使用。它不允许我使用任何p5函数,所以我必须使用 importScripts("p5.js") 函数在使用任何p5函数之前导入p5.js库。

onmessage = (e)=>{
    importScripts("p5.min.js")
    // other scripts
}

但即便如此,它也给了我另一个错误,即“未捕获引用错误:未定义窗口”。我找到了它,似乎p5无法使用名为“window”的全局变量。我在互联网上搜索了一个解决方案,但到目前为止没有找到。我想知道是否有办法解决这个问题。非常感谢。

mzillmmw

mzillmmw1#

这里的问题是,web工作人员在一个非常孤立的环境中运行,在这个环境中,网站上运行的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发送的所有内容都会被序列化和反序列化。
我已经在glitch上发布了这个示例的工作版本。

相关问题