简体   繁体   English

如何在 Web Worker 中使用 PixiJS

[英]How to use PixiJS in web worker

I need to display a quite complex 2D shape in a canvas using PixiJS and to do so I'd like to create and define all graphic elements in a separate thread (web worker) to not block the rest of the UI.我需要使用 PixiJS 在画布中显示一个非常复杂的 2D 形状,为此我想在一个单独的线程(网络工作者)中创建和定义所有图形元素,以免阻塞 UI 的其余部分。

The problem is that when I import PixiJS in the web worker file like this问题是当我像这样在 web worker 文件中导入 PixiJS 时

importScripts('https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.5.2/pixi.js');

it gives me an error because it accesses DOM elements (like window and document) and this is not allowed in web workers.它给了我一个错误,因为它访问 DOM 元素(如窗口和文档),这在网络工作者中是不允许的。 How can I solve this?我该如何解决这个问题?

This is the error:这是错误:

Uncaught ReferenceError: window is not defined
at Object.179../Math.sign (Object.assign.js:3)
at s (_prelude.js:1)
at _prelude.js:1
at Object.<anonymous> (WebGLPrepare.js:101)
at Object.187../accessibility (index.js:44)
at s (_prelude.js:1)
at e (_prelude.js:1)
at _prelude.js:1
at _prelude.js:1
at _prelude.js:1

Well I guess you cannot.好吧,我想你不能。 Webworkers have their own DedicatedWorkerGlobalScope with no access to the DOM, window, etc. If you have heavy computations, for instance to calculate animations, all you can do is let the webworker do the number crunching and the main thread do the rendering. Webworker 有自己的DedicatedWorkerGlobalScope ,不能访问 DOM、窗口等。如果你有大量计算,例如计算动画,你所能做的就是让 webworker 做数字运算,主线程做渲染。

The Worker and the main thread cannot share objects. Worker 和主线程不能共享对象。 Even if the following explanation is not 100% technically correct, you can imagine that if you:即使以下解释在技术上不是 100% 正确,您也可以想象,如果您:

var obj = { a: { b: 100 } };
worker.postMessage(obj);

It will be more like:它会更像:

                   //really dirty object clone here
worker.postMessage(JSON.parse(JSON.stringify(obj)));

With that I want to point out, that you cannot share objects with the worker and vice verca.我想指出的是,您不能与工人共享对象,反之亦然。

Find a tecnically correct explaintion here:在这里找到技术上正确的解释:

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Transferring_data_to_and_from_workers_further_details https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers#Transferring_data_to_and_from_workers_further_details

Philipp is right on his answer, I just want to elaborate this a bit further, from the games and web workers point-of-view. Philipp 的回答是正确的,我只是想从游戏和网络工作者的角度进一步详细说明这一点。

In my experience, it is ofter hard to take advantage of web workers in games.根据我的经验,在游戏中利用网络工作者通常很困难。 Especially if you use a library to handle canvas / webGL, since that does most of the number crunching anyway.特别是如果您使用库来处理画布/webGL,因为无论如何它都会处理大部分数字。 Web workers are designed for number crunching as philipp mentioned.正如 philipp 所提到的,Web Workers 是为数字运算而设计的。 And passing data between web worker and main thread is quite expensive, so passing data and doing tiny operations on them, will not be beneficial.并且在 web worker 和主线程之间传递数据是非常昂贵的,因此传递数据和对它们进行微小的操作将没有好处。

Without providing a direct link, I read already long while ago that some game engines (I think construct) used web workers for their pathfinding module.在没有提供直接链接的情况下,我很久以前就读到过一些游戏引擎(我认为是构造)使用网络工作者作为他们的寻路模块。 So nothing related to direct graphic handling, but numerical operations.所以与直接图形处理无关,而是与数值运算有关。

Also there is a proposal for possibility to use canvases in web worker contexts, so it is clearly an issue with others too.还有一个关于在 web worker 上下文中使用画布的可能性的建议,所以这显然也是其他人的问题。 If my memory serves right, I believe it was this: https://developer.mozilla.org/fi/docs/Web/API/OffscreenCanvas如果我没记错的话,我相信是这样的: https : //developer.mozilla.org/fi/docs/Web/API/OffscreenCanvas

You can include PixiJS in your Web Worker, although you can not perform graphics operations.可以在你的 Web Worker 中包含 PixiJS,但你不能执行图形操作。

Although the other two answers are technically correct, there are legitimate use cases for including Pixi's code in your Worker's scope without actually rendering graphics.尽管其他两个答案在技术上是正确的,但在不实际渲染图形的情况下将 Pixi 的代码包含在您的 Worker 范围内是合法的。 An example is using Pixi's Point and Rectangle classes.一个例子是使用 Pixi 的PointRectangle类。 In my case, I wrote several modules that rely on definitions exported by Pixi and perform heavy calculations based on them.就我而言,我编写了几个依赖 Pixi 导出的定义并基于它们执行大量计算的模块。

The errors you had were because Pixi relies on the globals window and document to define some graphics-related constants.您遇到的错误是因为 Pixi 依赖于全局windowdocument来定义一些与图形相关的常量。 In order to allow Pixi to finish loading you can provide mock values for window and document with empty methods with the same names as the ones used by Pixi.为了让 Pixi 完成加载,您可以使用与 Pixi 使用的名称相同的空方法为windowdocument提供模拟值。

As an example, while using PixiJS 4.8.6 the following code worked for me:例如,在使用 PixiJS 4.8.6 时,以下代码对我有用:

window = self
document = {
    createElement () {
        return {
            getContext () {
                return {
                    fillRect () {},
                    drawImage () {},
                    getImageData () {},
                }
            },
        }
    },
}

importScripts('pixi-4-8-6.js');

/* Web Worker code follows */
// ...

Depending on Pixi's version you may need to adjust this boilerplate.根据 Pixi 的版本,您可能需要调整此样板。 An alternative would be to try one of those packages that mock document and Canvas for headless browsers.另一种方法是尝试为无头浏览器模拟documentCanvas的那些包之一。 I haven't tried that since the code above worked well enough.我还没有尝试过,因为上面的代码工作得很好。

Pixi 5 came out recently and it may have changed this completely. Pixi 5 最近问世,它可能已经完全改变了这一点。 I skimmed the code and it looks like they removed the constant definition that was causing problems so it's also possible that this new version just works out of the box.我浏览了代码,看起来他们删除了导致问题的常量定义,因此这个新版本也有可能开箱即用。 I know they have been looking into letting people use Workers more easily and they have been exploring OffscreenCanvas like Hachi said.我知道他们一直在研究让人们更轻松地使用 Workers,并且他们一直在探索像 Hachi 所说的 OffscreenCanvas。

pixi team is working on adding headless environments support like web workers; pixi 团队正在努力添加无头环境支持,如 Web Workers; see https://github.com/pixijs/pixijs/issues/7123https://github.com/pixijs/pixijs/issues/7123

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM