2

我继续我的画布爱好aa-在尝试用网络工作者卸载大部分事情时遇到了另一个问题。这是当前的设计:[从 index.html 创建和启动核心 web worker core.js]

  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]);

[在 core.js 中我创建了两个网络工作者]

'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});
  }
}

每个网络工作者将结果发送给核心工作者 [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();
  }
}

[渲染.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);
  }
}

问题是,当requestAnimationFrame(main)在 mainloop.js 中调用时,我收到“此 Worker 不支持的 requestAnimationFrame”,尽管offscreenCanvas已在核心和渲染工作者之间转移。当更改setTimeout(main, 0)错误消失但没有在画布上绘制...

4

0 回答 0