canvas drawImage() 并不总是可见

canvas drawImage() not always visible

20% 的时间显示图像,80% 的时间 canvas 为空白(纯红色)。通过查看控制台,您可以看到图像在渲染函数中始终可用。

您可以通过单击 Run code snippet 然后 Hide Results 几次来复制它。

我在这里错过了什么?

如果您取消注释 window.requestAnimationFrame(render);,图像将在 100% 的时间内显示。但显然我不想继续迭代静态图像。

const canvas = document.querySelector('canvas');
      canvas.width = 500;
      canvas.height = 500;

const context = canvas.getContext('2d');

const image = new Image();
      image.onload = window.requestAnimationFrame(render);
      image.src = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/49240/2.jpg';

function render() {
  console.log('render', image);
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.drawImage(image, 0, 0, image.width, image.height);

  // window.requestAnimationFrame(render);
} 
canvas {
  background: red;
}
<canvas></canvas>

requestAnimationFrame(render) is being invoked immediately, and its return value is not a function, it's a handle that can be passed to cancelAnimationFrame()。您没有为 image.onload.

分配任何有意义的内容

你想做的是在调用 image.onload 时调用 render(),在这种情况下你应该使用 image.addEventListener('load', render);

const canvas = document.querySelector('canvas');
      canvas.width = 500;
      canvas.height = 500;

const context = canvas.getContext('2d');

const image = new Image();
      image.addEventListener('load', render);
      image.src = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/49240/2.jpg';

function render() {
  console.log('render', image);
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.drawImage(image, 0, 0, image.width, image.height);
} 
canvas {
  background: red;
}
<canvas></canvas>

您的代码行为不一致的原因是您不小心创建了一个竞争条件。由于 render() 在一定延迟后被调用,通常是 requestAnimationFrame() 的 1/60 秒,它的成功取决于该延迟是大于还是小于下载图像或服务的网络延迟它来自缓存。