多次将屏外画布发送给Webworker [英] Send offscreencanvas to webworker more than once

查看:73
本文介绍了多次将屏外画布发送给Webworker的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够多次将我的画布从屏幕外发送给Webworker.

I want to be able to send my canvas offscreen to a webworker more than once.

这是示例代码:

render() {
  const worker = new Worker("some url");
  const offscreen = this.canvasRef.current.transferControlToOffscreen();
  this.worker.postMessage({
    offscreen
  }, [offscreen]);

  return (
    <canvas ref={this.canvasRef} height="800" width="1000" />
  );
}

这个想法是,如果用户决定取消绘图,则可以杀死网络工作者.当我将消息重新发布到新的网络工作者时,出现以下错误:

The idea is to be able to kill the web worker if user decides to cancel the drawing. Put when I repost the message to a new web worker, I get the following error:

DataCloneError: Failed to execute 'postMessage' on 'Worker':
An OffscreenCanvas could not be cloned because it was detached.

推荐答案

您可以发送多次,但是为此,您需要将其从工作人员处转移回去,这可能会破坏您的目的,因为该工作人员将需要自由地能够处理该请求,如果是,则无需杀死"该请求.

You could send it more than once, but for this, you'd need to transfer it back from the worker, which kind of defeats your purpose I guess since the worker would need to be free to be able to handle that request, and if it is, there is no need to "kill" it.

因此,您可能更愿意使用同名的

So instead, you may prefer to create a standalone OffscreenCanvas, using the eponymous constructor that will stay in the Worker and to draw it on a BitmapRenderingContext:

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('bitmaprenderer');

const stop_btn = document.getElementById('stop_btn');

document.getElementById('start_btn').onclick = e => {
  console.log( 'starting a new drawing' );
  const worker = new Worker(getWorkerURL());
  worker.onmessage = e => {
    console.log('drawing complete');
    // pass it to the visible canvas
    ctx.transferFromImageBitmap(e.data);
    start_btn.disabled = false;
    stop_btn.disabled = true;
  };
  stop_btn.onclick = e => {
    console.log('drawing canceled');
    worker.terminate();
    start_btn.disabled = false;
    stop_btn.disabled = true;
  };
  start_btn.disabled = true;
  stop_btn.disabled = false;
};

function getWorkerURL() {
  const el = document.getElementById('worker_script');
  const blob = new Blob([el.textContent]);
  return URL.createObjectURL(blob);
}

<button id="start_btn">start</button>
<button id="stop_btn">stop</button><br>

<canvas id="canvas" width="500" height="500"></canvas>
<script id="worker_script" type="ws">
  const canvas = new OffscreenCanvas(500, 500);
  const gl = canvas.getContext('webgl');
  gl.viewport(0, 0,
      gl.drawingBufferWidth, gl.drawingBufferHeight);
  gl.enable(gl.SCISSOR_TEST);
  // make some slow noise (we're in a Worker)
  for(let y=0; y<gl.drawingBufferHeight; y++) {
    for(let x=0; x<gl.drawingBufferWidth; x++) {
      gl.scissor(x, y, 1, 1);
      gl.clearColor(Math.random(), Math.random(), Math.random(), 1.0);
      gl.clear(gl.COLOR_BUFFER_BIT);
    }
  }
  // make it last a bit longer than really needed
  const start = Date.now();
  while ( Date.now() - start < 5000 ) { }

  const img = canvas.transferToImageBitmap();
  postMessage(img, [img]);

</script>

这篇关于多次将屏外画布发送给Webworker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆