Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image not drawn on canvas until user clicks?

I draw several images with a function that performs something similar to:

context.drawImage(img, width / 2 * (-1), height / 2 * (-1), width, height);

I've read that I need to wait for the image to be loaded before I can draw it, with something like this:

img.onload = function() {
    context.drawImage(img, width / 2 * (-1), height / 2 * (-1), width, height);
};

However this causes the image to be drawn but afterwards, nothing is drawn since I call up my draw function every few milliseconds as it's part of the 'animation' loop for a simple game.

Is there a way that I can wait for the onload event before I continue running code in my init() function?

I suppose something like:

var image_loaded = false;
img.onload = function() {
    image_loaded = true;
};
if(image_loaded) {
    animate();
}

Should work? Unless I need to add a timeOut function to keep calling the init() until image_loaded is true?

like image 898
dan2k3k4 Avatar asked Mar 23 '23 23:03

dan2k3k4


1 Answers

Live Demo

var imagesLoaded = [],
    images = [
        'http://www.zombiegames.net/inc/screenshots/The-Last-Stand-Union-City.png', 
    'http://www.zombiegames.net/inc/screenshots/Lab-of-the-Dead.png',
    'http://www.zombiegames.net/inc/screenshots/Zombotron.png',
    'http://www.zombiegames.net/inc/screenshots/Road-of-the-Dead.png'],
    canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d");

canvas.width = 640;
canvas.height = 480;

function init(){
    // just loops through the images.
    if(imagesLoaded.length > 0){
        ctx.drawImage(imagesLoaded[0], 0, 0, 640, 480);
        imagesLoaded.push(imagesLoaded.shift());   
    }
    setTimeout(init,500);
}

function preload(){
    for(var i = 0; i < images.length; i++){
        (function(value){
            return function(){
                var loadedImage = new Image();
                loadedImage.src = images[value];
                loadedImage.onload = function(){
                    imagesLoaded.push(loadedImage);  
                } 
            }();
        })(i);

    }
    checkLoaded();
}

function checkLoaded(){
    if(imagesLoaded.length === images.length){
        console.log(imagesLoaded.length);
        init(); 
    } else{
        setTimeout(checkLoaded,30);
    }
}

preload();

Above is an example of how to preload images and wait to do anything else. Basically what you do is have all your images in an array, and add the onload event to each of them. As they load I through them into another array that holds all the loaded images. Once the length of the two arrays match all of the images are ready to use.

Another way would be to increment a counter as they load and check its value against the length of the array. When the counter variable is equal to the length of the images array it means they've all loaded and are ready to use.

like image 53
Loktar Avatar answered Apr 03 '23 22:04

Loktar