首页 > 解决方案 > 画布 drawImage() 并不总是可见

问题描述

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

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>

标签: javascriptcanvashtml5-canvasdrawimage

解决方案


requestAnimationFrame(render)被立即调用,它的返回值不是一个函数,它是一个可以传递给的句柄cancelAnimationFrame()。您没有为 分配任何有意义的东西image.onload

你的意思是在被调用render()image.onload调用,在这种情况下你应该使用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()在一定延迟后被调用,通常是 1/60 秒requestAnimationFrame(),它的成功取决于该延迟是否大于或小于用于下载图像或从缓存提供图像的网络延迟。


推荐阅读