Thursday, March 1, 2012

HTML5: How to ensure images are loaded before rendering them

Okay, so I have been busy developing HTML5 games for a company so cannot share it here... but what I can share is a small trick that helps to make sure that my images are loaded before I go about rendering them

Why and where do you need it?
Well, "why" is just to put things in context but "where you need it is more important".
It is a good idea to ensure the images are uploaded before rendering them because unless you have scoped all your code with a try catch block, it is difficult to find where the error is, esp. when you have tens of images being displayed and only a couple of them missing.

Although the technique is useful for all the browsers, its requirement is more pronounced in the case of mobile browsers which are the primary targets if your are building mobile games that run across the platforms with same code base.

And finally, the main thing - "HOW"
The basic idea is this:
  • Make a list of all the images you want to upload
  • Create image objects for all the images listed above
  • Add "onLoad" event listener to each one of them such that the listener calls the same function, lets call it onImgLoad
  • Now comes our onImgLoad function which will be fired every time an image gets loaded enough that it can be rendered or at least that when trying to render the image all the basic image data will be available so that no error is thrown.
    • Every time this function is called we increment a variable i.e. imgLoaded by 1
    • If the imgLoaded becomes equal to total number of images to be loaded i.e. imgToLoad, we can now safely draw them.
Here is the code snippet where I'm loading 10 images 1.png to 10.png from images folder

var imgLoaded = 0;
var imgToLoad = 10;
var onImgLoad = function()
{
   imgLoaded++;
   if(imgLoaded == imgToLoad)
   {
      drawImage()             //Call to our draw function
   }
}
 
for(var i = 0; i < 10; i++)
{
  images[i] = new Image();
  images[i].onload = onImgLoad;
  images[i].src = 'images/'+i+'.png';
}

Also a key point to note here is that
 images[i].onload = onImgLoad;
is assigned before providing the image source.

This is done as a hack for IE (That's something I read in some post while I was hunting to solve this problem of mine)