The image is not drawn on the canvas until the user clicks?

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

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

I read that I need to wait for the image to load 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 draw, but then nothing is drawn, since I call my draw function every few milliseconds as part of the animation loop for a simple game.

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

I am assuming something like:

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

Should it work? Unless I need to add the timeOut function to continue calling init () until the true_loaded value is true?

+4
source share
2 answers

I created a simple and small library to make image loading easier.

Check out the demo

See the library code below:

 // Simple Image Loader Library window.Loader = (function () { var imageCount = 0; var loading = false; var total = 0; // this object will hold all image references var images = {}; // user defined callback, called each time an image is loaded (if it is not defined the empty function wil be called) function onProgressUpdate() {}; // user defined callback, called when all images are loaded (if it is not defined the empty function wil be called) function onComplete() {}; function onLoadImage(name) { ++imageCount; console.log(name + " loaded"); // call the user defined callback when an image is loaded onProgressUpdate(); // check if all images are loaded if (imageCount == total) { loading = false; console.log("Load complete."); onComplete(); } }; function onImageError(e) { console.log("Error on loading the image: " + e.srcElement); } function loadImage(name, src) { try { images[name] = new Image(); images[name].onload = function () { onLoadImage(name); }; images[name].onerror = onImageError; images[name].src = src; } catch (e) { console.log(e.message); } } function getImage(/**String*/ name){ if(images[name]){ return (images[name]); } else{ return undefined; } } // pre-load all the images and call the onComplete callback when all images are loaded // optionaly set the onProgressUpdate callback to be called each time an image is loaded (useful for loading screens) function preload( /**Array*/ _images, /**Callback*/ _onComplete, /**Callback <optional>*/ _onProgressUpdate) { if (!loading) { console.log("Loading..."); loading = true; try { total = _images.length; onProgressUpdate = _onProgressUpdate || (function(){}); onComplete = _onComplete || (function(){}); for (var i = 0; i < _images.length; ++i) { loadImage(_images[i].name, _images[i].src); } } catch (e) { console.log(e.message); } } else { throw new Error("Acess denied: Cannot call the load function while there are remaining images to load."); } } // percentage of progress function getProgress() { return (imageCount / total)*100; }; // return only the public stuff to create our Loader object return { preload: preload, getProgress: getProgress, getImage: getImage, images: images // have access to the array of images might be useful but is not necessary }; })(); 

How it works

To ensure that images are uploaded and can be used by your application, the library has a Loader.preload method.

The preload method will get an array of objects, each object containing the name and src properties of the image you want to load. Optionally, you can configure the onComplete callback (which will be called when all images are loaded) and the onProgressUpdate (which will be called every time the image is loaded). The onProgressUpdate is useful if you want to create a loading screen for your application.

Use Loader.getProgress() to get the percentage of downloaded images at any time.

To get a link to the downloaded image, call Loader.getImage(name) , where name is the name property (String) of the image.

If for some reason you need to Loader.images over all the images, use Loader.images . This is an object containing all links to images in its properties.

Use this:

 var images = [{name: "img1", src: "http://...a.."}, {name: "img2", src: "http://...b.."}, ... {name: "imgN", src: "http://...N.."}]; function onProgressUpdate(progress){ ... drawProgressBar(progress); // just an example of what you can do ... } function onComplete(){ ... // get an Image from Loader object var texture = Loader.getImage("img2"); // or use this: var texture = Loader.images.img2; // or still Loader.images["img2"] ... // iterate over the images for (var img in Loader.images){ console.log(Loader.images[img].src); } .... } Loader.preload(images, onComplete, onProgressUpdate); 

Check out the demo if you haven’t.

+3
source

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 something else. Basically what you do is have all your images in an array and add an onload to each of them. When they load me through them into another array that contains all the downloaded images. Once the length of the two arrays matches all the images, they are ready to use.

Another way would be to increase the counter at boot time and check its value with respect to the length of the array. When the counter variable is equal to the length of the image array, this means that they are all loaded and ready to use.

+4
source

Source: https://habr.com/ru/post/1480882/


All Articles