4

There are several questions about this in the forum, but I couldn't get a good answer for what I need.

I am getting into Canvas and Javascript, and I want to preload some images as soon as the game opens. I made an example of the method I wanted to build (and didn't work)

I have 3 files: "main.html" where the canvas (there is only one in this example) is declared and I try to load an image, "ImagePreloader.js" where I preload all the images and "Variables.js" where I have my variables.

Could anyone please help me with this image preloading metod, or suggest me a viable one? I think the image is not loading because I am not using an onLoad() function, which I couldn't understand in the tutorials I read so far (I know how to apply it to an image, but not to an array of images)

main.html:

<!DOCTYPE HTML>
<html>
  <body>
    <canvas id="myCanvas" width="800" height="600"></canvas>

    <script type="text/javascript" src="Variables.js"></script>
    <script type="text/javascript" src="ImagePreloader.js"></script>
    <script>
    // Basic canvas info
    var canvas = document.getElementById('myCanvas');
    var context = canvas.getContext('2d');

    // Draw one of the images. Somehow it doesn't work :(
    context.drawImage(imageArray[3], x, y, width, height);
    </script>
  </body>
</html>

ImagePreloader.js

// This should preload the images in imageArray[i] with 0 <= i <= 5 ... right?
function preloader() 
 {
     for(var i=0; i<5; i++) 
     {
          imageArray[i].src=images[i];
     }
 } 

Variables.js

// array of sources of my images
images = new Array();
images[0]="img1.jpg"
images[1]="img2.jpg"
images[2]="img3.jpg"
images[3]="img4.jpg"
images[4]="img5.jpg"

// Stuff to draw the image
var x = 50;
var y = 50;
var width = 256;
var height = 256;

// Is this actually an array of images?
imageArray = new Image();

Thanks in advance!

Igor
  • 33,276
  • 14
  • 79
  • 112
CookieGuy
  • 63
  • 1
  • 2
  • 7

3 Answers3

8

Well, you will want to use a function which loads the images at a certain point, so you might as well try to understand onLoad. It's not that hard to grasp.

"onload" is a javascript event that occurs immediately after something is loaded. In other words: onLoad is like a javascript-native function which triggers when something is loaded. That something can be a window (eg: window.onload) or a document. What you want is the document onLoad event, as it triggers when your document is loaded.

Let's provide you with a simple example...

<body onload="preloadMyImages();">

This tells the browser "when you've loaded the document, run the preloadMyImages function".

All you have to do is then use that function to load your images into the client's browser cache.

function preloadMyImages() 
{
    var imageList = [
        "image.gif",
        "example/image.jpg",
        "whatever/image.png"
    ];
    for(var i = 0; i < imageList.length; i++ ) 
    {
        var imageObject = new Image();
        imageObject.src = imageList[i];
    }
}

That practically wraps it up and provides you with a fully working example. Enjoy!

EDIT

Since - according to your comment - you are looking for some more help, I would like to point you to https://stackoverflow.com/a/1038381/2432317 which (as one of many examples) shows how that you can (and probably should - depending on what you're planning do draw on your canvas) use img.onload too.

Yet, as I stated in my comment: it will all depend on where you want to take it. The more you dive into Javascript coding, the more you will understand what's going on. There are several good (partly free) books out there explaining how to code Javascript, use the HTML5 canvas, create preloaders, animations, talk about scopes etc.

A quick check at the big G of search engines turns up ample examples and tutorials too which will be helpfull for you. One of many examples: "How To Draw Images Onto Your HTML5 Canvas" which shows you preloading and looping an animation in a short and crisp tutorial.

But please, don't expect us to code it all for you - it's not going to happen. This is one of the not-so-rare cases where "learning by doing" will actually make you smarter. And if you hit another problem on your way to your final goal, you can always post a new question related to that new problem.

Community
  • 1
  • 1
e-sushi
  • 13,786
  • 10
  • 38
  • 57
  • In this example I can't use imageObject outside this function... or am I understanding wrong the scope in JavaScript? – CookieGuy Jul 03 '13 at 14:59
  • Yes, you're right. The example shows you what "onload" does and how to use it for a preloader that works, which is what you asked. The rest of your code depends on where you want to take it. If you need variables in another scope, define and use them accordingly. Mind you that no one here will code your website for you. And if you need to learn about the scope within Javascript, I would advise you to grab one of the several good Javascript books out there. But looking at your question again: you asked how to code a working preloader in JS and you got it. Now take that code and *use the force*! – e-sushi Jul 03 '13 at 16:48
  • 1
    @CookieGuy Added an **EDIT** to give you a little helping hand on your next question. – e-sushi Jul 03 '13 at 17:08
  • Thanks a lot, I would add a +1 here but I don't have enough rep yet – CookieGuy Jul 03 '13 at 19:09
  • 1
    @CookieGuy No worries. Knowing I could help someone is "+1" enough for me. ;) – e-sushi Jul 03 '13 at 19:40
2

You have to make sure these 5 images are loaded (downloaded doesnt alwaysmean its loaded and ready to use, only onload guarantees that image is ready to use) before you use it.

So add onload for the images, then count from the onload function and trigger the draw after 5 of them are loaded

function prefetchImages(sources){
        var images = [];
        var loadedImages = 0;
        var numImages = sources.length;
        for (var i=0; i < numImages; i++) {
            images[i] = new Image();
            images[i].onload = function(){
                if (++loadedImages >= numImages) {
                    //ready draw with my images now
                    drawThePainting();
                }
            };
            images[i].src = sources[i]; //bind onload before setting src bug in some chrome versions
        }
    };

prefetchImages(["1.jpg", "2.jpg", "3.jpg", "4.jpg", "5.jpg"]);

function drawThePainting(){
        // Basic canvas info
    var canvas = document.getElementById('myCanvas');
    var context = canvas.getContext('2d');

    // Draw one of the images. Somehow it doesn't work :(
    context.drawImage(imageArray[3], x, y, width, height);
}
sabithpocker
  • 15,274
  • 1
  • 42
  • 75
1

try this

put this script in head section
<script type="text/javascript">
    function preload(arrayOfImages) {
      for(i = 0 ; i < arrayOfImages.length ; i++)
         {
     var img = new Image();
             img.src = arrayOfImages[i];
         }
    }

 preload(['img1.png','img2.png']);
</script>
Shinov T
  • 862
  • 5
  • 9
  • Does putting this code in the head section guarantee I can load the images whenever I want in a canvas declared in the body? – CookieGuy Jul 03 '13 at 19:04
  • I have done this prefetch for a slider having many images.before slider starts the first two images i preloaded using this and it works fine for me.. i think this will work for canvas also. U can try this.. – Shinov T Jul 04 '13 at 06:38