📜 ⬆️ ⬇️

Preloading Images

Those who use HTML5 Canvas know that the image cannot be used via the URL to it. The image must first be loaded either via the img tag, or via the Image object, or via data: url .
In order not to think about loading each picture, they load all the necessary pictures before drawing the scene itself. In this topic, I will give an example of my image loader, which uses Mootools from its mechanisms for working with classes.

What should such a class look like in terms of design? It should receive the addresses of the images that should be loaded, and in some way, notify about the download process.
Fortunately, Mootools provides some tools for convenient work with events.

The class implements onload, onerror, onabort Image object handlers , and when the percentage of total load has changed, its own are generated.
The class generates three events:

var Imageloader = new Class({
// Options Events
Implements : [Options, Events],
options : {
//
//
onStart : $empty,
//
onUpdate : $empty,
//
onComplete : $empty,
// .
//{
// "url" : url,
// "key" : key,
// "size" : size
//}
images : []
},
initialize : function (options) {
this .setOptions(options);
//
this .images = {};

//
this .totalCount = this .options.images.length;
this .successCount = this .failureCount = this .loadedCount = 0;
this .successSize = this .failureSize = this .loadedSize = this .totalSize = 0;
this .progress = 0;

},
start : function () {
// Image,
//
$each( this .options.images, function (obj) {
this .totalSize += obj.size;
var image = new Image();
image.onload = this .onComplete.bind( this ,obj);
image.onerror = this .onFailure.bind( this ,obj);
image.onabort = this .onFailure.bind( this ,obj);
image.src = obj.url;
this .images[obj.key] = image;
}.bind( this ));
this .fireEvent( 'start' );
},
// Image
getImage : function ( key ) {
return this .images[key];
},
//
onComplete : function ( image ) {
//
this .successCount++;
this .successSize += image.size;

this .onImageEvent(image);
},
//
onFailure : function ( image ) {
//
this .failureCount++;
this .failureSize += image.size;
//
this .images[image.key] = new Image();
this .onImageEvent(image);
},
onImageEvent : function ( image ) {
//
this .loadedCount++;
this .loadedSize += image.size;

//
var progress = Math.round( this .loadedSize*100/ this .totalSize);
if ( this .progress != progress ) {
this .progress = progress;
// update
this .fireEvent( 'update' ,progress);
}
//
if ( this .totalCount == this .loadedCount ) {
this .fireEvent( 'complete' );
}

}
});


* This source code was highlighted with Source Code Highlighter .

Example of use:

var il = new Imageloader({
onUpdate : function (percent) {
//
alert(percent);
},
onComplete : function ( ) {
//
alert( "done" );
alert(d.getImage( "winter2010" ).complete);
},
//
images : [{
'url' : 'http://www.google.com/intl/en_ALL/images/srpr/logo1w.png' ,
'key' : 'main_logo' ,
'size' : 7
},{
'url' : 'http://www.google.com/logos/winter2010_1-hp.jpg' ,
'key' : 'winter2010' ,
'size' : 32
},{
'url' : 'http://www.google.com/logos/komensky10_hp.gif' ,
'key' : 'komensky' ,
'size' : 26
}]
});
//
il.start();


* This source code was highlighted with Source Code Highlighter .

')
As a presentation of progress, I wrote another class that draws a progress bar through Canvas.

An example of the implementation can be found here (it loads somewhere 100kbyte Google logos)

PS I plan to write a cycle of articles about game-building through Html5 Canvas. This is the first, although it is a bit banal. In the next article I will try to describe the principle of constructing a landscape in isometric projection (by tiles).

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


All Articles