
Hello. Recently, I often deal with JavaScript-canvas, especially writing all sorts of toys that are demanding for traffic due to the need to load a lot of pictures.
Usually, about 50-100kb of compressed JavaScript is loaded first, after which - a certain number of pictures (for example, 500kb, 2mb, 10mb, etc.) and only after that the game starts. You can, of course, download along the way, but the lack of texture is unlikely to please the player.
Therefore, I decided that it was necessary to make some decent, cute, easily-customizable (in order to quickly change from project to project) progress bar, but without having to use pictures. Under the source code under the LGPL license, a small instruction on how to do this and at the bottom of the article is a link to the result.
At once I will say that I do not pretend to any special admiration for the uniqueness and genius of the code. The code is simple and without particularly tricky techniques, but I think beginners can easily find something interesting for themselves.
Intrument
While working with Canvas, there is practically no need to work with the DOM, because the standard powerful JS frameworks, a la Jquery (which I like very much) are unnecessary and, at the same time, do not cover the necessary needs. I use my own mini-framework, which provides a lightweight wrapper over the DOM, extensions to standard primitives and something else;) The file utils.js.
I also have a CanvasExpander.js file, which slightly extends the initial
context . getContext ( '2d' );
context . getContext ( '2d' );
. Some functions we need ...
I want to draw attention to the
utils / Trace class. I needed the output of objects, since firebug does not work in Firefox3.7a. And he, in contrast to Firebag, allows you to display information in the same block, which is quite useful for, for example, outputting the number of FPS. It is disconnected by a single or, sometimes, double click on a block.
var tr = new Trace ();
setInterval (function () {
tr . trace ( fps );
}, 20 );
On its basis the class FpsMeter is made. Just every time before the frame starts, we call the frame () method of the object and it will highlight us the average fps for the last n frames (passed by the parameter when creating it, see the code for an example)
')
Interface
First let's define the interface. As usual, I have a picture download:
var id = new ImageDownloader ({
wallBrick : "/images/walls/brick-512px.png" ,
wallWood : "/images/walls/wood-256px.png" ,
sectoid : "/images/aliens/grey-64-256px.png"
// And So On
});
setInterval (function () {
if ( id . ready ) {
outputMainData ( id . getImages ());
}
}, 20 );
This allows me to not conceive of urles, and in the code to use only the name of the picture. For example,
Images [ 'wallBrick' ]
. But since we want to add progressBar, we need to slightly expand the interface by adding the public property progress (it would be more correct through the getter, of course, but this is not so important now)
setInterval (function () {
if ( id . ready ) {
outputMainData ( id . getImages ());
} else {
progBar . setProgress ( id . progress ). draw ();
}
}, 20 );
The source codes of ImageDownloader are not particularly interesting for us, because I personally wrote a stub that smoothly raises progress from zero to 100% in 3.4 seconds.
Create a progressBar
What do we write in the draw () method?
Calling our class, the programmer does not know what is going on inside, because he expects that nothing will happen to his settings and
context . fillColor
context . fillColor
or
context . fillColor
. stays the same. To do this, we will save the fields using
context . saveValues ();
context . saveValues ();
, and after rendering, restore the original values using
context . loadValues ();
context . loadValues ();
(CanvasExpander.js).
this . drawBorder ();
will draw a wrapper for our progress bar:

Now the line itself. Let's say the pictures will load in 5 seconds. And our canvas is redrawn every 0.02 seconds (50 fps). Thus, the line is regenerated from scratch during this time 250 times. It is much more profitable to create a separate buffer, where to generate this line, and then simply display the corresponding part on the screen. We will create another Canvas element into which we will draw it, and then take it (
ProgressBar . createBuffer ();
method), we can see the result if we uncomment the body attachment line in the method)
Now, when we drew it, you can use it every frame without serious consequences:
ctx . drawImage ( line , 0 , 0 , width * prog , height ,
c . x + 1 , c . y + 1 , width * prog , height );
Where line is the canvas html element.

Recalculation of styles
Every time the style of our progressBar changes, the countSizes method is called, which considers all numbers less than zero as percentages. This will make our progress look the same, no matter how large the Canvas element is. First, the width in pixels is calculated. Suppose Canvas width is 800 pixels and style ['width'] = 0.8. Then the width of the progress bar will be 640 pixels. All other values depend either on the width of the progressBar or on the height ('blendHeight', 'blendVAlign', 'textSize', 'textVAlign'). This will allow you to masturbate with the element, without changing proportions.
All sources are inside, not obfuscated, license: LGPL.