我正在尝试使用实验性的Canvas功能 - offscreenCanvas。
index.html
<html>
<body>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
<script>
const canvas = document.querySelector('#myCanvas');
const offscreenCanvas = canvas.transferControlToOffscreen();
const worker = new Worker('./worker.js');
worker.postMessage({offscreenCanvas}, [offscreenCanvas]);
</script>
</html>
worker.js
onmessage = e => {
const ctx = e.data.offscreenCanvas.getContext('2d');
ctx.fillRect(0 , 0, 100 , 100);
ctx.commit();
}
这里的一切都很好,我在画布上画了一个简单的矩形。现在 - 如何使用postMessage传递其他信息?例如 - 是否可以发送带有矩形坐标的对象?
像
const obj = {
x: 0,
y: 0,
}
我试图通过创建新的Int8Array来使用可转移对象:
const bufferObj = new Int8Array([obj.x, obj.y]);
说实话,我不知道如何将它发送给worker并从事件对象中读取它。我在考虑
worker.postMessage(offscreenCanvas, bufferObj, [offscreenCanvas, bufferObj]);
但这会引发错误索引1处的值没有可转移类型。知道如何解决这个问题吗?
答案 0 :(得分:1)
首先,如果您不需要转移对象的所有权,只需将其发送给工作人员,您就可以这样做:
const obj = {
x: 0,
y: 0,
}
worker.postMessage({offscreenCanvas, obj}, [offscreenCanvas]);
然后只需从工作人员访问e.data.obj
即可。对于简单的对象,我会说这不是一个主要问题,因为postMessage
使用Structured clone algorithm
但是,如果您需要优化,并且传递大量数据(作为屏幕外画布),则需要在另一侧传输对象。
在这种情况下,您的错误是使用未实现Typed Array
接口的Transferable
。相反,您需要传递ArrayBuffer
。例如:
const buff = new Uint8Array([obj.x, obj.y]).buffer;
worker.postMessage({offscreenCanvas, buff}, [offscreenCanvas, buff]);
这应该有效。