JavaScript

Using a progress bar to load assets

It's inevitable. Images take a longer time to load then anything else on your page. If you are trying to load an image gallery for example, you have to give the user some feedback to let him know that something is happening in the background.

That's when you can use an all too familiar progress bar.

But how do you make sure the progress bar is accurately showing how far you are in the process. In my early days, I would just set an arbitrary time of let's say 10 seconds even if my files load faster. But don't worry, that's not what we will be doing today. Today, we do it the right way; by progressing every time an image is loaded.

Luckily for us, HTML5 comes with a <progress> tag. If we want to support older browsers, it's not difficult either. But we will leave that for another day.

Scenario

So our scenario is we want to load 10 images from our image gallery. We want to let the user know that we are doing something in the background so they don't think that the website has crashed.

The images source are coming from the server, either through an ajax request, or directly printed on the page.

var imagePaths = [
    "path/image01.jpg","path/image02.jpg","path/image03.jpg","path/image04.jpg",
    "path/image05.jpg","path/image06.jpg","path/image07.jpg","path/image08.jpg",
    "path/image09.jpg","path/image10.jpg"
];

Progress.loadImages(imagePaths);

We want this code to work. So we will have to create the Progress object first. The Progress object will take an array of image paths and load them in memory. While loading them, it will increase the progress. When everything is loaded, it will append the images on the page.

To detect when an image is loaded, we use the image.onload method.

var Progress = {
    bar : null,
    index : 0,
    imgList : [],
    init: function(){
        var box = document.getElementById("progressBox");
        var prog = document.createElement("progress");
        box.appendChild(prog);
        console.log(prog)
        this.bar = prog;
    },

    loadImages: function(paths) {
        var self = this,
            i, length = paths.length;
        this.bar.max = length;
        for (i=0;i&lt;length;i++){
            var img = new Image();
            img.onload = function() {
                self.increase();
                if (self.index >= length){
                    self.done();
                }
            };
            img.src = paths[i];
            this.imgList.push(img);

        }
    },

    increase: function(){
        this.index++;
        this.bar.value = this.index;

    },

    done : function() {
        console.log("I am done loading");
        this.bar.style.display = "none";
        var showBox = document.getElementById("show");
        for (var i =0, l = this.index;i&lt;l;i++) {
            showBox.appendChild(this.imgList[i]);
        }
    }

};

In the loadImages, we assign a load event to each image, which increments the progress. When The progress is complete, we run the done method, which appends the images to the page.

The done method can easily updated to run a call back function. This way you can run your own custom code when the images are loaded.


You can use the same technique to create a progress bar. Another example is to use the same concept when loading assets into your game. You can use the onload event to load sound, images, or videos to your game.

Feel free to share when you create something cool with this method.

Originally Posted on Feb 18, 2015 @ 00:59


Comments(2)

Ibrahim Hassan Muhammad :

Great!

Cloudsdale :

Yeah, but what if one of the images is large and all the others are small? Then the progress will hang on the large one without showing any actual progress. A better way would be to show the progress depending on how much of each of the images has been loaded so far (as their sizes in bytes are most likely know as soon as they start loading).

Let's hear your thoughts

For my eyes only