
Page 3 of 3
Patrick Mineault
Freelancer behind 5 1/2 math and physics enthusiast Patrick has a knack for making seemingly simple things overly complicated. Perfect for a tutorial writer.
View all articles by Patrick MineaultMovie 3: Pie preloader
So far we've only used the drawing API to draw squares. Certainly there are other things we can draw with it! In this movie we'll create a portion of circle (pie slice) in order to create a pie preloader. It should look something like this in the end:

Here the double arcs on the right represents the percentage of movie loaded (in this case about 45%).
Some background would be useful before presenting the script. Drawing a pie slice turns out to be a pain because it involves curves which are not nearly as simple to work with as lines in the drawing API. Now instead of creating "real" pie slices we will add a series of small triangles with a relative angle between them so as to create a section of a regular polygon. We'll use triangles with a side length greater than the radius of the masked circle and a sharp angle of 3.6 degrees (1/100 of a circle). What we need is a way to transform these angle and radius coordinates to more traditional Cartesian x and y pairs. A diagram will certainly help:

Convince yourself that the following relations hold:
x1 = r*sin(O)
x2 = r*sin(O+dO)
y1 = r*cos(O)
y2 = r*cos(O+dO)
With that in mind we may create our pie preloader. Create a circle with no interior and with a large outline (donut shape). Convert to movie clip (F8), assuring that that you select the center as the registration point (this is very important). Name the instance maskee. Now place it anywhere on the stage.
Select the movie clip and add this action to it (once again, not to the frame but to the clip itself):
onClipEvent(load)
{
_root.stop();
dO = 3.6;
r = 75;
function addSlice(O)
{
x1 = r*Math.sin(O*Math.PI/180);
x2 = r*Math.sin((O+dO)*Math.PI/180);
y1 = r*Math.cos((O)*Math.PI/180);
y2 = r*Math.cos((O+dO)*Math.PI/180);
trace(x1 + ":" + y1);
with(_root.mask)
{
moveTo(0,0);
beginFill(0x000088);
lineTo(x1,y1);
lineTo(x2,y2);
endFill();
}
}
_root.createEmptyMovieClip("mask",0);
this.setMask(_root.mask);
_root.mask._yscale = -100;
_root.mask._x = this._x;
_root.mask._y = this._y;
oldLoaded = 0;
}
onClipEvent(enterFrame)
{
loaded = Math.ceil(_root.getBytesLoaded()/_root.getBytesTotal()*100);
for(i = oldLoaded; i < loaded; i++)
{
addSlice(dO*i);
}
oldLoaded = loaded;
}
Now in order to better see the effect of the script you should add a second frame to your movie and put a large image file so that you have the time to watch it load. Press Ctrl+Enter twice in order to simulate loading using the Show Streaming feature.
We've approximated our circle mask with a collection of 100 triangles with a sharp angle of 3.6 degrees. In order to keep track with what we've drawn and what we have not we set up two vars: loaded and oldLoaded. Then on each frame the enterFrame event is called: all triangles with numbers between the value oldLoaded and loaded are the drawn.
The drawing takes place inside the addSlice function. It uses the relations derived above to get the coordinates of each of the corners of the triangle. It then draws it using the same functions as before. By now you should be familiar with the standard procedure: set up an empty movie clip, set it as the mask of a target, then draw some shapes in it. Before I finish I should mention the use of _root.mask._yscale = -100. On a computer screen the positive y-axis does down, while in the Cartesian system it goes up. Therefore a reflection about the horizontal axis is necessary in order to keep our angle relations valid.
Conclusion
You now have plenty of tools for creating all kinds of masking effects. In this tutorial I've willfully avoided the more complex aspects of the drawing API such as drawing curves. This was done in order to show you that using the drawing API in drawing masks was really quite simple and natural.
If you need professional help with ActionScript, please visit http://www.5etdemi.com for my portfolio and contact info. Happy flashing!

