Wait/Loading Animation Animation |
|||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|||||||||||||||||||||
Tutorial:
|
|
||||||||||||||||||||
The last tutorial generated an antialiased circularly shaded image which is ready for animating. This tutorial will use a javascript timer to spin the circle:
The following animation is drawn, it is not a downloaded html image: 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.
It's time to get a spin vector (sdx,sdy) going as suggested when the Dot Product was introduced. An animation hopes to draw a new frame every 30ms. If the system is busy, it may take longer to get back to the timer. If the timer routine takes longer than 30ms to do the drawing, the timer routine may be called again by a new thread before the last timer thread had finished! The newer thread would mess up the parameters used by the older thread so this must be avoided and doing so needs just one boolean to remember if the routine is
Busy
.To implement the spinning, another Unsigned Unit Interval [0,1] will be used to indicate how far round the circle the current frame being drawn is. Since this is a journey it is called SpinJourney; it's the current fraction of a full turn being drawn. A full circle (in Radians) is
2*Math.PI
so to get an Angle which is a fraction of a circle is simply a multiplication with SpinJourneyvar Angle=2*Math.PI*SpinJourney;
But an angle isn't enough: the requirement is a Unit Vector which (unfortunately) requires trigonometry (unpopular because it is slow).
var sdx=Math.sin(Angle); // Use sin and cos to describe a circle var sdy=Math.cos(Angle); // The results are Signed Unit Intervals [-1,1] forming a Unit VectorThe radius of the vector (sdx,sdy) will be one (because it is a Unit Vector): when sdx is one, sdy will be zero. The dot product of this Spin Vector with the vector (dx,dy) from the middle of the circle to the pixel being drawn will bedx*sdy+dy*sdx
. This dot product will vary in the range [-Distance,Distance] because the vector (dx,dy) has the radiusDistance
. To get back to an Unsigned Unit Interval the Dot Product is simply divided by Distance and passed through the Unsigned function:var t=Distance ? Unsigned((dx*sdy+dy*sdx)/Distance) : 0.5;
Javascript provides a method called
setInterval
which sets up a timer call-back function that will be called every few milliseconds (the 30 specified at the end of the following code-block).var SpinJourney=0; // [0,1] var Busy=false; setInterval(function() { // Timer function called every 30ms (hopefully) if(Busy) return; Busy=true; var Angle=2*Math.PI*SpinJourney; var sdx=Math.sin(Angle); // Use sin and cos to describe a circle var sdy=Math.cos(Angle); // The results are Signed Unit Intervals [-1,1] forming a Unit Vector SpinJourney+=0.02; // increment the angle a little if(SpinJourney>1) SpinJourney=0; // keep it in the range [0,1] ... var t=Distance ? Unsigned((dx*sdy+dy*sdx)/Distance) : 0.5; // unit Dot Product using (0,-1) as the second vector ... Busy=false; },30);That is becoming a good grounding for a Wait/Loading Animation, but there is a problem. Over time the animation will get slower and slower... The next tutorial will explain why and correct the problem.