网络工作者和画布

IT技术 javascript html html5-canvas web-worker
2021-02-28 02:16:57

是否允许网络工作者访问画布对象?

3个回答

小更新,因为这个问题现在已经半年多了:

在 Chrome/Chromium 6 中,您现在可以将画布的 ImageData 对象发送给网络工作者,让网络工作者对该对象进行更改,然后使用putImageData(..)将其写回画布

谷歌的Chromabrush就是这样做的,源代码可以在这里找到:

更新:

Opera (10.70) 和 Firefox (4.0b1) 的最新开发快照也支持将 ImageData 对象传递给 web worker。

2017 年更新:

来自 Github 的实际链接(更容易从 中找到所需文件Chromabrush):

或者它真的保证某些数据类型通过引用传递吗?
2021-04-18 02:16:57
使用 imageData 作为 TransferableObject 对我有用(如果支持)。这避免了创建整个数组的副本,但请注意:一旦它被“转移”到工作线程(通过引用),它就不再能在主线程中访问
2021-04-25 02:16:57
让我猜IE是不同的?
2021-05-03 02:16:57
@DeusProx 是的,已制作副本。您可以尝试使用Transferable Objects
2021-05-07 02:16:57
它可能会在将整个内容发送给网络工作者的同时复制整个内容,并将转换后的数据复制回主线程以将其绘制到画布中?那么两次复制整个解密图片,包括速度损失?
2021-05-13 02:16:57

不。

几个月前更新了 postMessage 规范以允许您发布 ImageData 对象,但目前还没有人实现这种行为(我们都在那里)。画布本身的问题在于它是一个 DOM 元素,因此在工作器中不起作用(没有 DOM)。

这是最近在 whatwg 或 web-apps 邮件列表上提出的,所以我怀疑我们将开始研究是否可以在工作人员中提供类似 CanvasRenderingContext2D 的 api。

问题是 DOM 没有并发的概念,所以 Worker 不允许任何共享状态。与 worker 通信的唯一方法是使用 postMessage,并根据“内部结构化克隆算法”执行克隆,该算法基本上可以认为是 JSON,但额外支持一些关键类型(文件、文件列表、图像数据、 Blob、日期和正则表达式)
2021-04-18 02:16:57
我的印象是 WebWorker 不允许与 DOM 进行任何交互,因为如果多个 WebWorker 进行更改,这可能会遇到问题。
2021-04-25 02:16:57
这个答案已经过时了。另一个答案现在更好了。
2021-05-02 02:16:57
给 webworker 自己的 DOM,然后允许 API 切换部分 DOM 是有意义的。考虑到一个原因是允许多线程,现在这是一个非常不可用的功能。画布绘图可能非常昂贵,所以我不明白 WHATWG
2021-05-09 02:16:57

较新的浏览器支持OffscreenCanvas(请参阅该文档中的浏览器兼容性),这是一个在 Web Worker 中运行的画布 2d 上下文,但会自动绘制到主线程。

以下是该 MDN 文档的基本示例。

在主线程中,创建一个 OffscreenCanvas,然后将其发送给一个工作线程:

var htmlCanvas = document.getElementById("canvas");
var offscreen = htmlCanvas.transferControlToOffscreen();

var worker = new Worker("offscreencanvas.js"); 
worker.postMessage({canvas: offscreen}, [offscreen]);

在工作线程中,使用屏幕外画布引用创建一个上下文,就像您通常在主线程上所做的那样,并执行您想要的任何绘图命令:

onmessage = function(evt) {
  const canvas = evt.data.canvas;
  const gl = canvas.getContext("webgl");

  function render(time) {
    // ... some drawing using the gl context ...
    requestAnimationFrame(render);
  }

  requestAnimationFrame(render);
};

requestAnimationFrameAPI 存在于工作线程内部。)