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?
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?
Share Improve this question edited May 23, 2017 at 12:07 CommunityBot 11 silver badge asked Sep 26, 2012 at 15:20 RonRon 23.6k33 gold badges115 silver badges214 bronze badges 4- Ummm, can letterImg onload() hold more than one function pointer? – thatidiotguy Commented Sep 26, 2012 at 15:23
- dunno... how can i avoid this? – Ron Commented Sep 26, 2012 at 15:25
-
@thatidiotguy you can only have one
.onload
, but in this case it's being put on a different element each time so it doesn't matter. If you want more than one on an element I think you can useaddEventListener('load', ...)
. – Alnitak Commented Sep 26, 2012 at 15:29 - That's not the problem, @thatidiotguy and Alnitak. – corazza Commented Sep 26, 2012 at 15:30
2 Answers
Reset to default 5The 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);
}
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);
}