Noble-Surfer
Noble-Surfer

Reputation: 3172

Using a JavaScript while loop to draw an array of images to HTML5 canvas

I have the following JavaScript code, which I am using to try and loop through an array of images, and draw each one to the HTML5 canvas at different locations:

/*First, create variables for the x & y coordinates of the image that will be drawn.
                the x & y coordinates should hold random numbers, so that the images will be 
                drawn in random locations on the canvas.*/
                var imageX = Math.floor(Math.random()*100);
                var imageY = Math.floor(Math.random()*100);

                /*Create a 'table' of positions that the images will be drawn to */
                var imagePositionsX = [20, 80, 140, 200, 260, 320, 380, 440, 500, 560];
                var imagePositionsY = [20, 60, 100, 140, 180, 220, 260, 300, 340, 380];
                var randomPositionX = Math.floor(Math.random()*10);
                var randomPositionY = Math.floor(Math.random()*10);

            /*Draw all images from assetsImageArray */
            /*Use a while loop to loop through the array, get each item and draw it. */
            var arrayIteration = 0;
            console.log('Assets Image Array length: ' + assetsImageArray.length); /*Display the length of the array in the console, to check it's holding the correct number of images. */
            while(arrayIteration < assetsImageArray.length){
                context.drawImage(assetsImageArray[arrayIteration], imageX, imageY, 50, 50);
                console.log(arrayIteration); /*Display the current array position that's being drawn */
                arrayIteration = arrayIteration+1;
                /*Now try changing the values of imageX & imageY so that the next image is drawn to a 
                    different location*/
                imageX = imagePositionsX[randomPositionX];  /* imageX+(Math.floor(Math.random()*100)); */
                imageY = imagePositionsY[randomPositionY];  /* imageY+(Math.floor(Math.random()*100));  */

            }

The intended logic behind this code is: first the arrayIteration variable is set to 0, then I display the number of images in my assetsImageArray in the console. Then the while loop starts- while the arrayIteration variable is less than the number of items in the assetsImageArray, the image at position arrayIteration (i.e. position 0 at this point), of the assetsImageArray should be drawn to the canvas at coordinates imageX and imageY.

The imageX and imageY variables both hold random numbers assigned to them by the code Math.floor(Math.random()*100); After drawing the first image to the canvas at the specified location, the console should then log the array element that's just been drawn.

The next line should then increment the arrayIteration variable, and then finally, the values of imageX and imageY should be updated by taking a the value of a random element from the arrays imagePositionsX and imagePositionsY respectively.

The while loop will iterate through this code, drawing each image from assetsImageArray to a new location on the canvas, until all of the images from the array have been drawn.

However, for some reason only the first and last images from my assetsImageArray are being drawn to the canvas. They are being drawn in random locations- which is what I want, and every time I reload the page, they are drawn to new positions on the canvas, but I can't figure out why none of the images in the array positions between first and last are being drawn to the canvas. I assume there's something wrong with my logic somewhere, but can't figure out where.

Is anyone able to spot it?

Upvotes: 2

Views: 1907

Answers (1)

nnnnnn
nnnnnn

Reputation: 150080

On each iteration of the loop the next image is drawn at the coordinates specified by imageX and imageY, but for the second and subsequent iterations imageX and imageY always hold the same values so the second and subsequent images are all drawn on top of each other in the same place. That's why it seems like only the first and last images get drawn.

On the first iteration the first image is drawn at random coordinates between 0 and 99 as per the values assigned to imageX and imageY before the loop starts:

            var imageX = Math.floor(Math.random()*100);
            var imageY = Math.floor(Math.random()*100);

Then within the loop you change imageX and imageY:

         imageX = imagePositionsX[randomPositionX];  
         imageY = imagePositionsY[randomPositionY];

But what values do randomPositionX and randomPositionY hold? They hold a random number between 0 and 9 that is assigned once before the loop starts. So those two lines always select the same positions from the imagePositionX and imagePositionsY arrays.

The simplest fix would be to move the following two lines inside the loop:

            var randomPositionX = Math.floor(Math.random()*10);
            var randomPositionY = Math.floor(Math.random()*10);

It would still be possible for more than one image to end up at the same location purely by chance, but with a ten-by-ten grid that's less likely (depending on how many images you have).

I'd probably simplify the code though, something like this:

 var imagePositionsX = [20, 80, 140, 200, 260, 320, 380, 440, 500, 560];
 var imagePositionsY = [20, 60, 100, 140, 180, 220, 260, 300, 340, 380];
 var i, x, y;

 for (i = 0; i < assetsImageArray.length; i++) {
     x = imagePositionsX[ Math.floor(Math.random()*10) ];
     y = imagePositionsY[ Math.floor(Math.random()*10) ];

     context.drawImage(assetsImageArray[i], x, y, 50, 50);
 }

I don't understand why your current code starts out with a random location with coordinates between 0 and 99 for the first image, while all the other images use coordinates selected at random from the two arrays, so I've removed this difference.

Upvotes: 1

Related Questions