var c=document.getElementById("cvs");
var ctx=c.getContext("2d");
var imgArray = [];
for (var i=0;i<data.length;i++){
var drawRepeat = Math.floor((data[i]/divider));
imgArray[i] = [];
for (var j=0;j<drawRepeat;j++){
//alert(j);
var xPos = ((i*30)+10);
var yPos = 250-((j*30)+30);
imgArray[i][j] = new Image();
imgArray[i][j].src="assets/orange.png";
imgArray[i][j].onload = function(){
ctx.drawImage(imgArray[i][j],xPos,yPos);
};
}
}
I want to draw multiple images with a for loop. weirdly when i place an alert() with the for loop it works? but if i comment it away it will only display 1 of the image.
Is there any solution to this?
That’s the problem related to closures. I’ll explain after giving the code.
UPDATE:
The reason I am doing this weird stuff is that the function registered to
onloadevent will be called asynchronously – that is the loop will continue and the function will be called when the image loads, and not at that very moment. So what happens is that this loop continues, and once it’s completed (note that this may occur even before completion),i‘s value will bedata.length - 1. Now, some image is loaded, and then the function is called. This function refers toi(in the code you gave), which by now isdata.length - 1. And so, only the last image gets drawn. I know this is confusing – even I felt it confusing when I first stumbled upon closures. I recommend you read some good article on them and you’ll see what the problem is.What we did was to create a scope (experts might find a problem with this expression) by creating an anonymous function which is called immediately, and is passed the values of
iandjas it’s parameters –_iand_j(Note that we could’ve used the same names, but to avoid confusion, I didn’t use the same names). Now, these are local to the function and aren’t altered. So, whenith image is loaded, it’s onload function is called which draws the_ith image in the array.I have failed to explain it well, so as I said, please read some article on closures.