Ron
Ron

Reputation: 23466

HTML 5 Canvas - Dynamically include multiple images in canvas

I need to include multiple images in a canvas. I want to load them dynamically via a for-loop.

I tried a lot but in the best case only the last image is displayed. I check this tread but I still get only the last image.

For explanation, here's my latest code(basically the one from the other post):

 for (var i = 0; i <= max; i++)
{
    thisWidth = 250;
    thisHeight = 0;
    imgSrc = "photo_"+i+".jpg";
    letterImg = new Image();
    letterImg.onload = function() {
        context.drawImage(letterImg,thisWidth*i,thisHeight);
    }
    letterImg.src = imgSrc;
}

Any ideas?

Upvotes: 1

Views: 4478

Answers (2)

corazza
corazza

Reputation: 32354

Here's an alternative way of solving your problem...

letterImg is just a reference to an image. So, the for loop gets executed n times, and each time, letterImg is changed into a new image. Therefor, you only get the latest image drawn.

Here's the code (of course, change the maxImg number to a correct value.):

images = []; //An array where images are stored.
thisWidth = 250; //This doesn't need to be inside the for-loop.
thisHeight = 0;
maxImg = 342;

//Attach an onload event to an image, that will draw it at (x, y) coordinates.
attach = function(img, x, y)
{
    img.onload = function()
    {
        context.drawImage(img, x, y);
    }
}

for (var i = 0; i <= maxImg; i++)
{
    imgSrc = "photo_" + i + ".jpg";

    images[i] = new Image();
    images[i].src = imgSrc;

    attach(images[i], thisWidth*i, thisHeight);
}

Upvotes: 1

WojtekT
WojtekT

Reputation: 4775

The problem is that onload event happens asynchronously and by then the loop variable is already at last value. You can use closures to fix it:

for (var i = 0; i <= max; i++)
{
   thisWidth = 250;
   thisHeight = 0;


   (function(j){
      var imgSrc = "photo_"+j+".jpg";
      var letterImg = new Image();
      letterImg.onload = function() {
        context.drawImage(letterImg,thisWidth*j,thisHeight);
      }
      letterImg.src = imgSrc;
   })(i);

}

Upvotes: 5

Related Questions