我正在尝试使用实验性 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();
}
这里一切正常,我在 Canvas 上绘制了简单的矩形。现在 - 如何使用 postMessage 传递附加信息?例如 - 是否可以发送具有矩形坐标的对象?
喜欢
const obj = {
x: 0,
y: 0,
}
我尝试通过创建新的 Int8Array 来使用可转移对象:
const bufferObj = new Int8Array([obj.x, obj.y]);
老实说,我不知道如何将它发送给工作人员并从事件对象中读取它。我在想
worker.postMessage(offscreenCanvas, bufferObj, [offscreenCanvas, bufferObj]);
但是这会抛出错误 Value at index 1 does not have a transferable type。知道如何解决这个问题吗?
最佳答案
首先,如果您不需要转移对象的所有权,而只是将其发送给工作人员,您可以这样做:
const obj = {
x: 0,
y: 0,
}
worker.postMessage({offscreenCanvas, obj}, [offscreenCanvas]);
然后从 worker 访问 e.data.obj
没有问题。对于简单的对象,我认为这不是主要问题,因为 postMessage
使用 Structured clone algorithm
但是,如果您需要优化,并且传递了大量数据(作为屏幕外 Canvas ),您希望将对象转移到另一侧。
在这种情况下,您的错误是使用了未实现 Transferable
接口(interface)的 Typed Array
。相反,您必须传递 ArrayBuffer
。例如:
const buff = new Uint8Array([obj.x, obj.y]).buffer;
worker.postMessage({offscreenCanvas, buff}, [offscreenCanvas, buff]);
那应该行得通。
关于JavaScript postMessage 和多个可传输对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50840096/