user1328174
user1328174

Reputation: 543

Cannot create images in a canvas with for loop

I have the following code which is suppose to do the following:

  1. Create 2 Canvas elements on the html page dynamically (this works fine)
  2. For each Canvas element, examine the allSteps variable which is a representation of what images should appear in what position of the canvas element. In this hard coded example, it should display two black boxes at the bottom of the first canvas and two brown boxes at the bottom of the 2nd canvas. (this doesn't work properly). All images are 50x50.

For some reason, it is only loading one image at the end of the 2nd canvas.

<!DOCTYPE html>
<html>
<head>
   <script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
   <script type="text/javascript" language="javascript">
   $(document).ready(function() {

        var boxImages = ['img/white.jpg', 'img/blue.jpg', 'img/black.jpg', 'img/brown.jpg', 'img/green.jpg', 'img/red.jpg'];
        var IMAGE_WIDTH=50;
        var MAX_COLS = 7;
        var MAX_ROWS = 8;
        var numberOfSteps = 2;
        var allSteps = [];
        allSteps[0] = '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2';
        allSteps[1] = '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 3';

        $('#result_div').html('<p>All Steps : ' + allSteps + '</p>');

        for (count=0; count < numberOfSteps; count++)
        {
            $('#result_div').append('<h3>Step : ' + count + '</h3>');
            $('#result_div').append('<p><canvas id="resultCanvas' + count + '" width="350" height="400" style="border:1px solid #c3c3c3;" ></p>');
            resultCanvas=document.getElementById('resultCanvas'+count);
            resultCtx = resultCanvas.getContext("2d");  

            currentSolution = allSteps[count].split(" ");
            for (r=0; r < MAX_ROWS; r++)    
            {
                for (c=0; c < MAX_COLS; c++)
                {
                    imgNumber=currentSolution[((r)*MAX_COLS)+c];
                    if (imgNumber != 0)
                    {                   

                        boxX = (c*IMAGE_WIDTH);
                        boxY = (r*IMAGE_WIDTH);
                        cimg=new Image();
                        cimg.onload = function(){resultCtx.drawImage(cimg,boxX,boxY);};
                        cimg.src=boxImages[imgNumber];  
                    }                           
                }
            }
        }
   });
   </script>
<body>

<div id="result_div"></div>


</script>
</body>
</html>

Upvotes: 0

Views: 269

Answers (1)

Zeta
Zeta

Reputation: 105886

I haven't tested this yet, but I guess you overwrite your cimg.src and cimg.onload faster than the images are actually loaded. Have you tried using an array of images instead?

    var cimgs = [];

    var IMAGE_WIDTH=50;
    /*
        ...
    */

            if (imgNumber != 0)
            {                   

                boxX = (c*IMAGE_WIDTH);
                boxY = (r*IMAGE_WIDTH);
                cimgs.push(new Image());
                cimgs[cimgs.length - 1].onload = (function(img,x,y){
                    return function(){resultCtx.drawImage(img,x,y);};
                })(cimgs[cimgs.lenght - 1],boxX,boxY);
                cimgs[cimgs.length - 1].src = boxImages[imgNumber];  
            }                           
        }

Upvotes: 1

Related Questions