仅在加载后在HTML5 Canvas中显示数百个微小图像

时间:2016-10-22 09:59:02

标签: javascript html5 image canvas

我有一个画布和100个小图像,我想以网格形式添加到画布上。

我已经实现了这一点,但是图像正在画布上逐一绘制,有时第40个位置的图像可能会在第10个位置的图像之前绘制。

这需要几秒钟,然后我得到了我想要的结果,但我想知道如何在他们重新加载后才能显示图像?

我知道还有其他类似问题的问题,但我已经阅读了所有这些问题并尝试了他们的解决方案,但还没有成功。

我有这段代码,使用嵌套for循环在画布上的正确位置逐个绘制图像:

for(...) {
  for(..) {
    add_image(source, row, column, width, height);
  }
}

现在add_image实际创建了一个图像对象并将其绘制为onload

function add_image(...) {
  let image = new Image();
  image.src = source;

  image.onload = function() {
    context.drawImage(img, row, col, width, height);
  }
}

在这种情况下,首先加载所有图像的最佳方法是什么?" draw"他们?我尝试创建一个数组并用所有图像对象填充它,然后当所有图像都被加载时,我会运行for循环来绘制图像,但它不会工作,我也没有看到控制台错误让我无能为力。

提前谢谢!

2 个答案:

答案 0 :(得分:0)

将图像添加到数组并按原样计算每个图像。在图像onload事件中减少计数器。当计数为零时,所有图像都已加载并可以绘制。

示例:

var images = [];
var loading = 0;
function add_image(url,xpos,ypos) {
  var image = new Image();
  image.src = url;
  images.push({
     image : image,
     xpos : xpos,
     ypos : ypos,
  });
  loading += 1;
  image.onload = function() {
      loading -= 1;
      if(loading === 0){
         drawImages(); // call function to draw all the images.
      }
  }
}
function drawImages(){
   for(var i = 0; i < images.length; i ++){
       // draw the image
       ctx.drawImage(images[i].image,images[i].xpos,images[i].ypos);
   }
}

答案 1 :(得分:0)

或使用Promise.all ...

function preloadImage(source) {
  return new Promise((resolve, reject) => {
    const image = new Image();

    image.addEventListener('load', resolve.bind(null, image));
    image.src = source;
  });
}

const images = []; // Array of image sources

Promise.all(images.map(preloadImage)).then((imgs) => {
  // Draw them :)
});

这是demo on jsfiddle