Search code examples
javascriptimage-loading

can someone explain this Image loader function involving callback


The Code:

function loadImages(sources, callback){
    var images = {};
    var loadedImages = 0;
    var numImages = 0;
    for (var src in sources) {
        numImages++;
    }
    for (var src in sources) {
        images[src] = new Image();
        images[src].onload = function(){
            if (++loadedImages >= numImages) {
                callback(images);
            }
        };
        images[src].src = sources[src];
    }
}
window.onload = function(images){
    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
    var sources = {
        darthVader: "darth-vader.jpg",
        yoda: "yoda.jpg"
    };
    loadImages(sources, function(images){
        context.drawImage(images.darthVader, 100, 30, 200, 137);
        context.drawImage(images.yoda, 350, 55, 93, 104);
    });
};

The Confusion

function loadImages(sources, callback){

3: two parameters are passed to this function, one being a function in of itself : callback

    var images = {};

4: finally, images is set to ... nul(?)

    var loadedImages = 0;
    var numImages = 0;
    // get num of sources
    for (var src in sources) {
        numImages++;
    }
    for (var src in sources) {
        images[src] = new Image();
        images[src].onload = function(){
            if (++loadedImages >= numImages) {
                callback(images);

5: my brain is confused at this point....

            }
        };
        images[src].src = sources[src];
    }
}
 
window.onload = function(images){

As I understand,

1: the parameter "images" is empty.

    var canvas = document.getElementById("myCanvas");
    var context = canvas.getContext("2d");
 
    var sources = {
        darthVader: "darth-vader.jpg",
        yoda: "yoda.jpg"
    };
 
    loadImages(sources, function(images){

2: now its being passed as a parameter to this inline functions -- still without pointing to anywhere... it now supposedly calls loadImages method which is defined above...

        context.drawImage(images.darthVader, 100, 30, 200, 137);

where doe it get context to darthvader? i only see "sources" have darthVader above

        context.drawImage(images.yoda, 350, 55, 93, 104);
    });
};

source: http://www.html5canvastutorials.com/tutorials/html5-canvas-image-loader/

EDIT: QUESTIONS::

from step 4: to 5: (specifically in the second for loop), a new array (images[src]) is being created and is passed to the callback() function which is defined as inline just before step 2:. Where does it actually gets images from which were in source?


Solution

  • The Loader

    function loadImages(sources, callback){
        //images is set to an object literal
        //this is the same as writing "var images = new Object();
        var images = {};
    
        //the counter for the number of images loaded
        var loadedImages = 0;
    
        //the total number of images
        var numImages = 0;
    
        //count the total number of images to load
        for (var src in sources) {
            numImages++;
        }
    
        //iterate through every image in sources
        //"src" will be the key used in the object passed to the function (i.e. "yoda")
        for (var src in sources) {
            //set image[*keyname*] to a new Image object
            //i.e. images.yoda = new Image(), images.darthVader = new Image();
            images[src] = new Image();
    
            //attach an onload event listener to the image
            images[src].onload = function(){
                //add one to the number of images loaded
                //if the number of images loaded is equal to the total number of images, call the callback
                if (++loadedImages >= numImages) {
                    //pass the object containing the images to load as a parameter of the callback function
                    callback(images);
                }
            };
            //set the source of the created image to the src provided in the sources object
            //i.e. images.yoda.src = sources.yoda
            images[src].src = sources[src];
        }
    }
    

    The Usage

    window.onload = function(images){
        //get the canvas
        var canvas = document.getElementById("myCanvas");
    
        //get the drawing context of the canvas
        var context = canvas.getContext("2d");
    
        //initialize a new object with two sources
        //accessible as sources.darthVader and sources.yoda
        var sources = {
            darthVader: "darth-vader.jpg",
            yoda: "yoda.jpg"
        };
    
        //load the images in sources using the provided callback function
        loadImages(sources, function(images){
            //draw the images that were loaded on the canvas
            context.drawImage(images.darthVader, 100, 30, 200, 137);
            context.drawImage(images.yoda, 350, 55, 93, 104);
        });
    };