Psionman
Psionman

Reputation: 3677

How to draw images on an html canvas in a loop

I am trying to draw images on a canvas in a loop

In the following code, if I click on Next the 5 images appear one after the other. If I click on All only the last image appears

What is wrong?

<html>
<head>
    <style>
        .display-grid{
            display: grid;
            grid-template-columns: auto auto auto auto;
            padding: 10px;
        }
    </style>
</head>
<body>

    <div id="my-grid">
        <div class="display-grid">
            <span><canvas class="canvas" id="display-0"></canvas></span>
            <span><canvas class="canvas" id="display-1"></canvas></span>
            <span><canvas class="canvas" id="display-2"></canvas></span>
            <span><canvas class="canvas" id="display-3"></canvas></span>
            <span><canvas class="canvas" id="display-4"></canvas></span>
        </div>
    </div>
    <button id="next-image">Next</button>
    <button id="all-images">All</button>

<script type="text/javascript">
    last_image = -1
    var next_button= document.getElementById('next-image');
    var all_button= document.getElementById('all-images');
    next_button.onclick = function(){nextImage()};
    all_button.onclick = function(){allImages()};

    function nextImage() {
        last_image ++
        var canvas = document.getElementById('display-'+last_image.toString());
        var context = canvas.getContext('2d');
        var imageObj = new Image();

        imageObj.onload = function() {
            context.drawImage(imageObj, 0, 0);
        };
        imageObj.src = 'image_'+last_image.toString()+'.png';
    }

    function allImages() {
        for (index = 0; index < 5; index++) {
            var canvas = document.getElementById('display-'+index.toString());
            var context = canvas.getContext('2d');
            var imageObj = new Image();

            imageObj.onload = function() {
                context.drawImage(imageObj, 0, 0);
            };
            imageObj.src = 'image_'+index.toString()+'.png';
        }
    }
</script>

</body>
</html>

Upvotes: 0

Views: 764

Answers (1)

Kokodoko
Kokodoko

Reputation: 28128

It happens because the onload function isn't called in the same order as the loop. Some images may take longer to load than others.

You could fix it by checking the image name to know which image is loaded, and then you know in which canvas it should be drawn.

function allImages() {
    for (let index = 0; index < 5; index++) {
        let imageObj = new Image();
        imageObj.name = "display-"+index

        imageObj.onload = function() {
            console.log("loaded : " + this.name)
            let canvas = document.getElementById(this.name);
            let context = canvas.getContext('2d');
            context.drawImage(this, 0, 0);
        };

        imageObj.src = 'image_'+index+'.png';
    }
}

Upvotes: 1

Related Questions