Animated Arc Drawing
A recent comment on my Oval Drawing Tutorial asks how to “give the appearance that an oval is being drawn slowly”. Hmmm… this sounds like a job for my handy Arc Drawing Function.
Slowly drawing (or revealing) a circle can be achieved by drawing arcs of an ever-increasing size until the arc is so big that it comes back to the beginning and makes a full circle. The same is true with ovals. First let’s take a look at the basic code for drawing an arc of a circle:
function drawArc(centerX, centerY, radius, startAngle, arcAngle, steps){
var twoPI = 2 * Math.PI;
var angleStep = arcAngle/steps;
var xx = centerX + Math.cos(startAngle * twoPI) * radius;
var yy = centerY + Math.sin(startAngle * twoPI) * radius;
moveTo(xx, yy);
for(var i=1; i<=steps; i++){
var angle = startAngle + i * angleStep;
xx = centerX + Math.cos(angle * twoPI) * radius;
yy = centerY + Math.sin(angle * twoPI) * radius;
lineTo(xx, yy);
}
}
lineStyle(20, 0xFF0000);
drawArc(250, 250, 200, 45/360, -270/360, 100);
//
That's sort of helpful, but we want to animate the drawing of an oval, not a circle, so we need to modify the DrawArc function to draw segments of an oval rather than segments of a circle. Here's what the new ActionScript looks like:
// Split "radius" variable into "xRradius" and "yRradius" varianbles.
function drawArc(centerX, centerY, xRadius, yRadius, startAngle, arcAngle, steps){
var twoPI = 2 * Math.PI;
var angleStep = arcAngle/steps;
//
// Scale X and Y radius separately.
var xx = centerX + Math.cos(startAngle * twoPI) * xRadius;
var yy = centerY + Math.sin(startAngle * twoPI) * yRadius;
moveTo(xx, yy);
for(var i=1; i<=steps; i++){
var angle = startAngle + i * angleStep;
//
// Scale X and Y radius separately.
xx = centerX + Math.cos(angle * twoPI) * xRadius;
yy = centerY + Math.sin(angle * twoPI) * yRadius;
lineTo(xx, yy);
}
}
lineStyle(20, 0xFF0000);
//
// Call function with new X and Y radius variables.
drawArc(250, 150, 200, 100, 45/360, -270/360, 100);
//
Now that we can handle drawing small segments of an oval, we need to animate the process by drawing a series of larger and larger arc segments until they come together to form a complete oval. To do this we'll use an "onEnterFrame" event and a new "animateArc" function to increment a variable and draw a series of expanding arcs. Read the comments to follow along:
//
///////////////////////////////////////////////////////////////
// H O W T O D R A W A N O V A L S E G M E N T /////
///////////////////////////////////////////////////////////////
function drawArc(centerX, centerY, xRradius, yRadius, startAngle, arcAngle, steps){
var twoPI = 2 * Math.PI;
var angleStep = arcAngle/steps;
var xx = centerX + Math.cos(startAngle * twoPI) * xRradius;
var yy = centerY + Math.sin(startAngle * twoPI) * yRadius;
moveTo(xx, yy);
for(var i=1; i<=steps; i++){
var angle = startAngle + i * angleStep;
xx = centerX + Math.cos(angle * twoPI) * xRradius;
yy = centerY + Math.sin(angle * twoPI) * yRadius;
lineTo(xx, yy);
}
}
//
//
///////////////////////////////////////////////////////////////
// O V A L P R O P E R T I E S //////////////////////////////
///////////////////////////////////////////////////////////////
var cntrX = 250; // Center of the oval on the X axis.
var cntrY = 150; // Center of the oval on the Y axis.
var radiusX = 200; // Width of the oval.
var radiusY = 100; // Height of the oval.
var angle = -70/360;// Angle of the first point on the oval.
var arc = 360/360; // How big the arc will be when it's done.
var endSides = 100; // How many sides the arc will have when complete.
var lineWidth = 20; // Width of the line.
var lineColor = 0xFF0000;// Color of the line.
//
//
///////////////////////////////////////////////////////////////
// A N I M A T I O N P R O P E R T I E S ////////////////////
///////////////////////////////////////////////////////////////
var count = 0; // Tracks how long the animation has been going.
var frames = 150; // Sets how long the animation will last.
//
//
///////////////////////////////////////////////////////////////
// A N I M A T E G R O W I N G O V A L S E G M E N T ///
///////////////////////////////////////////////////////////////
function animateArc(){
//
// Remove old arc segment.
clear();
//
// Reset line width and color after being cleared.
lineStyle(lineWidth, lineColor);
//
// Note that a frame has passed.
count++;
//
// Determine how far along the animation is.
var ratio = count/frames;
//
// Determine how big the arc is.
var arcRatio = arc * ratio;
//
// Determine how many sides the arc segment has.
var sidesRatio = Math.floor(endSides * ratio);
//
// Draw the arc with its newly determined properties.
drawArc(cntrX, cntrY, radiusX, radiusY, angle, arcRatio, sidesRatio);
//
// Stop animating if the arc is complete.
if(count == frames){
onEnterFrame = null;
}
}
//
// Start animating the drawing of the oval.
onEnterFrame = animateArc;
//
//
///////////////////////////////////////////////////////////////////
// R E S E T A N I M A T I O N O N M O U S E C L I C K ///
///////////////////////////////////////////////////////////////////
onMouseDown = function (){
count = 0;
onEnterFrame = animateArc;
}
//
//
And there you have it, one animation of an oval being drawn.
This is great information. Thanks a lot for taking the time to present this information. This will help me greatly.
That’s really great. Nice code, and comments. Is it possible to have multiple on the Flash stage at the same time (animating)? Thank you!
Berry Nice.