I'm continuing with my canvas hobby a-a-and hit another problem while trying to offload most of the things with web workers. This is the current design: [creating and starting the core web worker core.js from index.html]
var canvas = document.getElementById('testcanvas');
canvas.imageSmoothingEnabled = false;
const offscreenCanvas = canvas.transferControlToOffscreen();
const core = new Worker('core.js');
//transfer offscreenCanvas just ONCE or will get a 'An OffscreenCanvas could not be cloned because it was detached' error
core.postMessage({canvas: offscreenCanvas, msg: 'start'}, [offscreenCanvas]);
[in the core.js I'm creating two web workers]
'use strict'; //meh
const render = new Worker('render.js');
const mainloop = new Worker('mainloop.js');
onmessage = function(ev) {
if (ev.data.msg === 'start') {
mainloop.postMessage({msg: 'start'});
}
if (ev.data.canvas) {
render.postMessage({canvas: ev.data.canvas}, [ev.data.canvas]);
}
if (ev.data.posX && ev.data.posY) {
render.postMessage({posX: ev.data.posX, posY: ev.data.posY});
}
}
each web worker sends the results to the core worker [mainloop.js]
'use strict';
var canvas;
var ctx;
var speed = 100;
var currentTime = 0; var timeDiff = 0; var lastTime = 0;
var timeProduct = 0; var dTime = 0; var timeScale = 1; var timeStep = 0.01;
var posX = 10; var posY = 10;
function main() {
currentTime = performance.now();
timeDiff = (Math.abs(currentTime - lastTime) * 0.001);
dTime += Math.min(timeDiff, 1);
timeProduct = timeStep * timeScale;
while (dTime > timeProduct) {
postMessage({posX: posX, posY: posY});
dTime -= timeProduct;
}
lastTime = currentTime;
posX += speed * timeDiff;
posY += speed * timeDiff;
if (posX > 500) posX = 10;
if (posY > 500) posY = 10;
requestAnimationFrame(main);
//setTimeout(main, 0);
}
onmessage = function(ev) {
if(ev.data.msg === 'start') {
main();
}
}
[render.js]
'use strict';
var canvas;
var ctx;
function draw(posX, posY) {
//clear
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, canvas.width, canvas.height);
//draw
ctx.beginPath();
ctx.moveTo(posX, posY);
ctx.ellipse(posX,
posY,
5,
5,
0.7854,
0,
2 * Math.PI,
false);
ctx.strokeStyle = "white";
ctx.stroke();
}
onmessage = function(ev) {
if(ev.data) {
if (!canvas) canvas = ev.data.canvas;
if (!ctx) ctx = canvas.getContext('2d');
draw(ev.data.posX, ev.data.posY);
}
}
The problem is that when requestAnimationFrame(main)
is called in the mainloop.js I'm receiving 'requestAnimationFrame not supported in this Worker' though offscreenCanvas
has been transfered between core and render workers. When changed with setTimeout(main, 0)
error disappears but nothing is drawn on the canvas ...