多次将屏外画布发送给Webworker [英] Send offscreencanvas to webworker more than once
问题描述
我希望能够多次将我的画布从屏幕外发送给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屋!