【问题标题】:Web Workers and Canvas网络工作者和画布
【发布时间】:2010-12-24 07:11:03
【问题描述】:

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

【问题讨论】:

    标签: javascript html html5-canvas web-worker


    【解决方案1】:

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

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

    在主线程中,创建一个OffscreenCanvas,然后发送给worker:

    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);
    };
    
    

    requestAnimationFrame API 存在于 worker 内部。)

    【讨论】:

      【解决方案2】:

      小更新,因为问题已经半年多了:

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

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

      更新:

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

      2017 年更新:

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

      【讨论】:

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

      没有。

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

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

      【讨论】:

      • 我的印象是 WebWorker 不允许与 DOM 进行任何交互,因为如果多个 webworker 进行更改,这可能会遇到问题。
      • 问题是DOM没有并发的概念,所以Workers不允许任何共享状态。与工作人员通信的唯一方法是使用 postMessage,它根据“内部结构化克隆算法”执行克隆,该算法基本上可以被认为是 JSON,但额外支持一些关键类型(文件、文件列表、图像数据、 Blob、日期和正则表达式)
      • 这个答案已经过时了。另一个答案现在更好。
      • 给 webworker 自己的 DOM,然后允许 API 切换部分 DOM 是有意义的。考虑到一个原因是允许多线程,现在这是一个非常不可用的功能。画布绘图可能非常昂贵,所以我不了解 WHATWG
      猜你喜欢
      • 2013-05-18
      • 2020-10-15
      • 2017-07-06
      • 1970-01-01
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      相关资源
      最近更新 更多