getImageData/putImageData 未绘制预期输出

getImageData/putImageData not drawing expected output

我有这个变量保存 canvas 到 getImageData() 之前的状态,但是当我画过它然后尝试用 putImageData() 恢复到旧状态不工作:

window.onload = async () => {
  const canvas = document.getElementById('canvas');
  const ctx = canvas.getContext('2d');
  let map;

  const drawPicture = async (image) => {
    const img = new Image();

    img.src = `assets/${image}.png`;
    img.onload = () => {
      ctx.drawImage(img, 0, 0, 60, 60);
    }
  }

  await drawPicture('log');
  map = ctx.getImageData(0, 0, 60, 60);
  await drawPicture('box');
  await ctx.putImageData(map, 0, 0);
}

罪魁祸首是 drawPicture 函数中的 onload 处理程序。仅使用 async 前缀将函数标记为异步是不够的。在您的情况下,该函数应该等到图像加载完毕,然后立即将其绘制到 canvas 上。

按照现在的写法,onload 处理程序会在您最后一次函数调用后的某个时间触发:

await ctx.putImageData(map, 0, 0);

所以正确的方法是让函数 return 成为 Promise,它在 onload 处理程序触发时立即完成。

window.onload = async () => {
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    let map;

    const drawPicture = async (image) => {
        return new Promise(resolve => {
            const img = new Image();
            img.onload = () => {
                ctx.drawImage(img, 0, 0, 60, 60);
                resolve();
            }
            img.src = `assets/${image}.png`;
        });
    }

    await drawPicture('a');
    map = ctx.getImageData(0, 0, 60, 60);
    await drawPicture('b');
    await ctx.putImageData(map, 0, 0);
}