Wait/Loading Animation

Site Map Feedback


←Previous Index Next→
Up Button Noise Wait Wall

The last tutorial created a circular shading over an HTML5 canvas. This will now be extended to draw a shaded circle.

The following picture is drawn, it is not a downloaded html image: This browser doesn't support the canvas element :-( As with all of these tutorial pages, you can see how the image is drawn simply by viewing the source for this page on your browser but be aware that this page draws two canvases (the extra one shows the jaggies).

The first thing to try is to avoid drawing pixels that are further away from the middle than the specified Radius:

  if(Distance>Radius) continue;
As you can see, this leaves black 'jaggies' around the 'circle':

The following picture is drawn, it is not a downloaded html image: This browser doesn't support the canvas element :-(

The edge needs to be blended from the pixels being drawn to those in the background and at the moment, there is no background! The background can be anything but for now it will be filled white before drawing using canvas context drawing methods:

ctx.rect(0,0, c.width,c.height);
To blend with the background, the background pixel data is read and mixed with the foreground pixel data that is to be written. That mix will vary from transparent (all background) to opaque (all foreground) and as usual this will be represented using an Unsigned Unit Interval [0,1]. The change from foreground to background only needs to happen over a couple of pixels and can use the difference between the Radius of the circle (the real edge) and the radius to the pixel being drawn (which has been called Distance in the existing code). (Radius-Distance)/2 describes the sloping line in the blend section which will cover two pixels:
Opaque 1 Transparent 0 Foreground Blend Background
To keep the result as an Unsigned Unit Interval it is clamped to the range [0,1] using a simple function culturally named Saturate:
function Saturate(t) {return t<0 ? 0 : (t>1 ? 1 : t);} // Ensure t is in the interval [0,1]
function Antialias(P,R) {return Saturate((R-P)/2);}   //  Returns the Foreground Opacity when given Real and Pixel positions (R and P)
The Antialias function gives the fraction of Foreground to mix; the rest of the unit is background. For example, if Antialias returns 0.8 then the blend is 0.8*Foreground + 0.2*Background. The 0.2 is simply 1-Antialias; you can see that the result will also be an Unsigned Unit Interval. Putting all that together results in the following code:
    var Foreground=Antialias(Distance, Radius);
    var Background=1-Foreground;
    var i=4*(c.width*y+x);   // locate the point (x,y) in the imgData array
    imgData.data[i+0]=imgData.data[i+0]*Background+255*t*Foreground; // Red scaled up to byte size varying between [0,255]
    imgData.data[i+1]=imgData.data[i+1]*Background+255*t*Foreground; // Green
    imgData.data[i+2]=imgData.data[i+2]*Background+255*t*Foreground; // Blue

The Antialiasing function will be used again later for other edges but it's time to get the circle to rotate. This will be developed in the next tutorial.