I am most pleased to be able to show you how to create an analog clock in Flash using ActionScript only.
You won't be touching any tools whatsoever. This is just about programming in Flash. Also, there is no timeline animation involved and no layers. And, this works in Flash MX, Flash MX 2004 and Flash 8.
Just look at the flash example below to see what is possible with actionscripting only.
That's right, even the shine on the left side of the clock frame was made with actionscript, just like the lines marking the hours and the minutes, and the clock hands too.
In this tutorial, you will make a simpler clock (but completely functional like the one above). At the end, I will briefly explain you how the stylish details were made and you will have the source for both clocks available for download.
1. Open a new Flash document. Save it immediately so that you can just press CTRL+S later.
2. Name the first layer (and only one in this project) actions.

3. Select the first keyframe. This will be the only one, too - remember, there is no timeline animation here.
Select Window > Actions to open up the Actions panel for the frame you just selected. If you are new to actionscripting, know that all actions placed on this (first) keyframe will be executed immediately upon loading of this movie.
4. Enter in the following code:
this.createEmptyMovieClip("clock", 3);
clock._x = 150;
clock._y = 150;
The above piece of code creates a new movie clip out of nothing. The keyword
this designates the object this piece of code is placed upon. As in
this particular case the code is placed on the main timeline, the keyword
this denotes the main timeline - this means the flash movie itself.
The createEmptyMovieClip command creates a new movie clip,
obviously. There are two parameters between the parentheses which must be
included if everything is to function as intended.
The first one is the instance name - "clock". That means the
name of the movie clip you are creating. You need to specify it, because you
wouldn't be able to manipulate the movie clip later if it has no name by which
you can reference it. And, you have to put the name between quotation marks,
otherwise flash will think that it is a variable and not an instance name you
are talking about.
The second parameter is the depth of the movie clip. Think of that as a layer created with actionscript. The bigger the number, the higher the stack position of the movie clip. It means that the movie clip with, say, a depth of 50, will be in front of (on the screen) a movie clip with a lesser depth, like 40 or 6, or 11, etc. I put the depth 3 arbitrarily.
REMEMBER When creating a movie clip with the
createEmptyMovieClip method, always give it a unique depth
parameter. If you were to create a new movie clip after that, with the same
depth as the previous one, that new movie clip would erase completely the
previous one. Also, if any of the two parameters are missing (instance name or
depth, or both), the creation of the movie clip will fail completely.
The next two lines are positioning the newly made movie clip on the stage.
This is necessary because when you create a new movie clip using the
createEmptyMovieClip method, it is by default positioned in the upper
left corner of the stage, with the coordinates (0,0).
So the clock._x = 150; line positions the clock movie
clip 150 pixels to the right from the left stage edge. The second one positions
it 150 pixels down from the top edge of stage (the positive Y coordinates are
below the top stage edge in flash). There is no this keyword at the
beginning of the two lines because the movie clip was created on the main, or
root, timeline in the first line of code, so you just write its name (clock)
and flash will look for it on the root timeline.
If you test your movie at this point, you won't see anything, but the movie clip is created and positioned on stage. If you are still not convinced :) then select Debug > List Objects while in the test movie mode. Flash will nicely list the movie clip.
5. Add this actionscript code after the existing one:
clock.createEmptyMovieClip("circle", 1);
clock.circle.lineStyle(4, 0x000066, 100);
clock.circle.moveTo(100, 0);
circleRadius = 100;
for (a=0; a<361; a++) {
radAngle = a*Math.PI/180;
xCoord = Math.cos(radAngle)*circleRadius;
yCoord = Math.sin(radAngle)*circleRadius;
clock.circle.lineTo(xCoord, yCoord);
}
Test
your movie. You should have a circle drawn by flash like the one below showing
up.
Looks nice, huh? :) And how does this work? Let me explain you.
First, you created a new movie clip using the createEmptyMovieClip
command. This new movie clip is created inside the clock movie clip.
Now why do that instead of repeating the same thing as you did in the beginning,
using the this keyword?
Because if you move the original, the base movie clip clock, to another position on the stage (let's say you changed the layout of your flash site), the newly created circle would stay on the old position.
But, when you create the circle movie clip inside the clock movie clip by using the line
clock.createEmptyMovieClip("circle", 1);
this problem is solved. Now, if you decide to move the clock, the circle will follow it. In that way, you have all things situated inside the clock movie clip.
The line
clock.circle.lineStyle(4, 0x000066, 100);
sets the style of the line before the drawing starts. You always have to do this. If you're not familiar with actionscript drawing commands, I suggest you go and read the basic drawing with actionscript tutorial.
The line clock.circle.moveTo(100, 0); moves the circle
movie clip's starting position for drawing. Note that the starting position of
drawing for a movie clip is its registration point, which is the zero point of
its own coordinate system. The stage is no longer used as a reference.
Why did you have to move the starting position for drawing? I will explain it in a moment.
The line circleRadius = 100; is where the circleRadius
variable is defined and its value is 100. This value defines the radius of your
clock's frame.
Now comes a for loop that actually draws the circular frame for
your clock.
for (a=0; a<361; a++) {
radAngle = a*Math.PI/180;
xCoord = Math.cos(radAngle)*circleRadius;
yCoord = Math.sin(radAngle)*circleRadius;
clock.circle.lineTo(xCoord, yCoord);
}
This loop repeats 360 times. That's because there are 360 degrees in a circle and this piece of code is drawing the circle from point to point.
The first line inside the loop defines the radAngle variable.
This variable's purpose is to store the angle for calculating the drawing points
of the circle, in radians. This is necessary since the
next two lines of code use flash's built-in math trigonometric functions which
work with radians instead of degree
values.
So the expression a*Math.PI/180 is a
simple mathematical formula used to convert degree values into radians. Here is
a little basic math reminder:
This angle increases every time as the loop increments. It stops when it comes full circle (pardon the pun) from 0 to 360 degrees.
Now comes the interesting part in which I will explain to you how the trigonometrical functions are used to draw the circle.
The X coordinate is found with this piece of actionscript:
xCoord = Math.cos(radAngle)*circleRadius;
It is stored in a variable called xCoord.
What does the right side of the expression do? I'll explain a little bit of high school math now. Wait. Wait! Don't run away :) It IS easy. And it is fun once you see the possibilities and creativity it offers you. I pretty much shunned away all the math after my studies, but once I lay my hands on Flash and saw that I had to implement it if I wanted to do some advanced actionscripting, I quickly remembered and looked up what I needed. So will you! Continue and you'll see how interesting and cool math is!
So, you need to know the coordinates of every point on the circle to draw it. How do you find a point on a circle? Simple, with two pieces of data you already have. The angle and the radius. Look at the diagram below.
I
took an angle of 30 degrees arbitrarily for the purpose of explaining this
calculation. So, you're looking for the X and Y coordinates of the T point on
the circle.
The X coordinate of the T point equals to the distance a on the diagram, which is the distance from the starting point (0,0) to the x point on the diagram. How to find the value of this distance? With trigonometry.
The triangle formed with the sides a, b and c in the diagram is a right triangle. It means there is a right angle (90°) inside it. It is found between the sides a and b. There are some great trigonometrical functions that can be used with this kind of triangle.
The cosine of an angle (the angle is marked with the greek letter lambda - λ) is the ratio of the length of the triangle side adjacent to the angle (a in the diagram) to the length of the hypotenuse (the hypotenuse being the side opposite the right angle, c in the diagram). So, the formula goes like this:

Written in a single line it goes like this:
cos λ = adjacent side / hypotenuse
If you apply the distances from the diagram to the formula, it would turn out this way:
cos λ = a / c
In your actionscript code, the angle λ is defined
in the variable radAngle and the hypotenuse c
is the radius of the circle, defined in the variable circleRadius.
What is left is the adjacent side a, which is the X
coordinate of the T point you're looking for. That coordinate is named
xCoord in your code. So, the formula turned into actionscript looks like
this:
Math.cos(radAngle) = xCoord / circleRadius;
But you're looking for the T point's X coordinate, right? So, the final line of code you need looks like this:
xCoord = Math.cos(radAngle) * circleRadius;
And that's it! The similar explanation goes for the Y coordinate. You're smart so just look at the diagram and apply the same logic to discover the explanation for finding the Y coordinate value.
So after finding both coordinates for each point (360 points in total because that's the number of iterations the loop is going through),
xCoord = Math.cos(radAngle)*circleRadius;
yCoord = Math.sin(radAngle)*circleRadius;
flash finally draws the line by executing the following code:
clock.circle.lineTo(xCoord, yCoord);
OK, the method lineTo draws the line to the coordinates
specified within the parentheses. But where does the line start? Where is it
drawn from?
This was defined in the line
clock.circle.moveTo(100, 0);
before the loop. After that first line is drawn, the loop passes to the next
iteration and draws from the last point (as drawing in flash is set up to do, if
there was no moveTo command in between) to the next one, which is
again calculated with the aid of the cosine and sine functions.
But, you ask again, why did I used the moveTo command to move to
the point (100, 0) and not some other point?
Because the calculation for the first angle is for the 0 degree angle, which is situated at three o'clock in flash. That's why you need to move the starting point for drawing here, so that it continues naturally following the circle.
Look at this diagram explaining it.
I put a lot of distance between the three marked points to make the diagram more easy to read. In reality, these points are right next to one another.

So, the first point (100, 0) is right on the horizontal axis of the circle.
This is where the drawing will begin, this was done with the moveTo
command explained above.
Soon after this line of code, the loop begins and the first point on the
circle (T1) is calculated. A line is drawn from (100, 0) to (T1)
with the lineTo command which follows the calculation of the point.
The loop goes through the next iteration and calculates the coordinates for the
second point (T2). A line is drawn from the previous point (T1)
to this one (T2).
And this goes on until the loop ends, that is, after 358 more iterations. So, I suppose you got the trick by now: the circle is in fact a 360-sided polygon! But the sides of the polygon are so close that it look like a circle. Cool, no? Absolutely cool! :)
The circle with the main concept of advanced drawing with actionscript being thoroughly explained, it's time for you to create the markings for the hours and the minutes.
The method used is the same, with some differences and catches.
6. Type in the following lines right after all the code you entered so far:
clock.circle.lineStyle(3, 0x000000, 100);
clock.circle.moveTo(100, 0);
circleRadius = 100;
smallerCircleRadius = 90;
for (h=0; h<12; h++) {
hourAngle = h*30;
radHourAngle = hourAngle*Math.PI/180;
xCoord1 = Math.cos(radHourAngle)*circleRadius;
yCoord1 = Math.sin(radHourAngle)*circleRadius;
xCoord2 = Math.cos(radHourAngle)*smallerCircleRadius;
yCoord2 = Math.sin(radHourAngle)*smallerCircleRadius;
clock.circle.moveTo(xCoord1, yCoord1);
clock.circle.lineTo(xCoord2, yCoord2);
}
Test your movie. The markings for the hours will appear. Let me quickly explain you how this is done.
The first line changes the style of the drawing line, so that it appears thicker. You can make it any color and thickness that you want, but the important thing is to make it more prominent than the minutes' markings. Remember, the time must be easily redable from the clock. Be nice to your users!
There is the circleRadius variable again, which is listed here
for easier comprehension. There is also a new addition,
smallerCircleRadius. These two circle radiuses will make it possible to
draw a line from the outer circle to the inner circle.
The loop has only 12 iterations now, which makes sense because this is the number of the hours' markings on a standard analog clock.
Inside the loop, the first line of code defines the angle at which the calculations are made. This angle is the loop's iteration multiplied by 30.
I hear you asking: why? :)
Because a full circle has 360 degrees, and there are 12 hours on an analog clock. So by multiplying each iteration number (0, 1, 2... till 11) with 30, you obtain the angles at which the markings for the hours must be positioned.
After the conversion of the angle from degrees to radians (the same formula
as in the previous step), there are two pairs of coordinates calculated,
followed by a moveTo command that defines a new starting drawing
point for each iteration, and then drawing with the lineTo command.
xCoord1 = Math.cos(radHourAngle)*circleRadius;
yCoord1 = Math.sin(radHourAngle)*circleRadius;
xCoord2 = Math.cos(radHourAngle)*smallerCircleRadius;
yCoord2 = Math.sin(radHourAngle)*smallerCircleRadius;
clock.circle.moveTo(xCoord1, yCoord1);
clock.circle.lineTo(xCoord2, yCoord2);
Look
at the diagram on the left to see how easy it is to understand this.
I put the points on another part of the circle, but this is applicable on all of it.
After placing the drawing position on B1, it draws the line to S1, which is found on the inner, smaller circle. The lines are drawn perfectly pointing at the center of the circle because the angle calculated is the same for the small and the big circle in each iteration. Then flash moves the starting drawing position again, this time to B2, and draws the line to S2.
It is easy once the main concept is grasped, isn't it?
You should create the markings for the minutes now, using a thinner line this time.
7. Place the following actionscript at the end of your current code:
clock.circle.lineStyle(1, 0x000000, 100);
clock.circle.moveTo(100, 0);
circleRadius = 99;
smallerCircleRadius = 91;
for (m=0; m<60; m++) {
minuteAngle = m*6;
radMinuteAngle = minuteAngle*Math.PI/180;
xCoord1 = Math.cos(radMinuteAngle)*circleRadius;
yCoord1 = Math.sin(radMinuteAngle)*circleRadius;
xCoord2 = Math.cos(radMinuteAngle)*smallerCircleRadius;
yCoord2 = Math.sin(radMinuteAngle)*smallerCircleRadius;
clock.circle.moveTo(xCoord1, yCoord1);
clock.circle.lineTo(xCoord2, yCoord2);
}
The
only thing that needs to be noted at this step is that I changed the radiuses
for both circles, so that the minutes' markings are a little bit shorter than
the hours' markings.
This loop goes through 60 iterations because there are 60 minutes in an hour. Inside the loop, this number is multiplied by 6, to get the right angle for each minute's marking. Similar calculation as before: 360 degrees in a circle, 60 minutes in an hour. 360 divided by 60 yields 6. The rest (moving and drawing) is as same as for the hours' markings.
Test your movie. Cool! You should have the same result as in the image on the left (the screenshot on the image is scaled down).
You'll now proceed to make the clock's hands. This is a little bit simpler than circle drawing with actionscript :)
8. Add the following code to the existing one:
clock.createEmptyMovieClip("hoursHand", 20);
clock.hoursHand.lineStyle(6, 0x000000, 100);
clock.hoursHand.moveTo(0, 0);
clock.hoursHand.lineTo(0, -50);
Test
your movie. You should see the hours hand appear.
This is simple, you only need to be careful about some details. At first, the movie clip is created. Its depth is set above the circle movie clip's hand, because you want all the hands to be above the circle and other drawings.
A thicker line is chosen for drawing style. Next, the beginning of the drawing is moved to (0, 0). This is very important. This is the registration point of the hours hand movie clip and it is around this point that the hand will rotate.
The lineTo command draws the hand.
9. Add the code that follows:
clock.createEmptyMovieClip("minutesHand", 30);
clock.minutesHand.lineStyle(5, 0x000000, 100);
clock.minutesHand.moveTo(0, 0);
clock.minutesHand.lineTo(0, -81);
clock.createEmptyMovieClip("secondsHand", 40);
clock.secondsHand.lineStyle(0, 0xFF0000, 100);
clock.secondsHand.moveTo(0, 0);
clock.secondsHand.lineTo(0, -90);
This is the code to create the minutes and the seconds hand.
Note that each hand movie clip's depth is bigger than the previous one. In that way, the clock hands are stacked one on top of another. I chose the depths 20, 30 and 40. It could have been 11, 12 and 13 or any other three numbers. But it is always wise to let some "space" between the depths. You never know, you might decide to add something in between later and then you'll be glad you did this.
Test the movie and you'll see the hands stacked one on top of another.
Yes! Finally, you get to start the clock! Just a liiiiittle bit more!
10. Enter the final piece of code:
clock.onEnterFrame = function () {
clockDate = new Date();
seconds = clockDate.getSeconds();
this.secondsHand._rotation = seconds * 6;
minutes = clockDate.getMinutes();
this.minutesHand._rotation = minutes * 6;
hours = clockDate.getHours();
this.hoursHand._rotation = (hours * 30) + (minutes/2);
}
Test your movie. The seconds hand should tick! This is the best way to check if your clock is working.
This portion of code creates a function assigned to the circle movie
clip's onEnterFrame event. This means that the function will get
executed as many times per second as there are frames per second set in your
movie's speed (fps option in your document's properties).
Inside the function, there is a new date object created. This is obligatory if you want flash to tell you what time or date it is. The lines
seconds = clockDate.getSeconds();
minutes = clockDate.getMinutes();
hours = clockDate.getHours();
create variables in which the information on current seconds, minutes and hours are stored.
A little bit more interesting are code lines that govern the rotation of the clock's hands.
this.secondsHand._rotation = seconds * 6;
this.minutesHand._rotation = minutes * 6;
this.hoursHand._rotation = (hours * 30) + (minutes/2);
The this keyword points to the clock movie clip, since
it is situated in a function which is assigned to this same movie clip's
onEnterFrame event. So, this.secondsHand points to the movie
clip secondsHand which is placed inside the clock movie clip.
Just simple actionscript paths.
Now, the _rotation property of these movie clips is what is
found on the right side of these code lines. The _rotation property
value is expressed in degrees.
Why are the minutes and seconds multiplied by 6?
For example, let's say that flash just read the time which said it is exactly 15 seconds now. This means the secondsHand movie clip should be pointing at 3 o'clock. This is 90 degrees in relation to its starting position of 0 degrees. That's why you have to multiply by 6. This is what happens at runtime:
this.secondsHand._rotation = seconds * 6;
this.secondsHand._rotation = 15 * 6;
this.secondsHand._rotation = 90;
NOTE The initial value for the
_rotation property of any movie clip is 0 degrees, which is pointing
straight upwards, in contrast with the sine and cosine values discussed in
previous steps of this tutorial, which point at the right side, horizontally.
OK? Don't confuse these two values, who have nothing to do with one another.
The same is with the clock's minutes hand.
But there is a difference with the hours hand. Its code says
this.hoursHand._rotation = (hours * 30) + (minutes/2);
If you just put in
this.hoursHand._rotation = hours * 30;
it would work, but in a misleading way. The result of the equation on the right side of the expression would be the following: let's say it's 11:50 now. 11 multiplied by 30 would yield 330, which means 330 degrees, which points right to 11 o'clock. This is ok, right?
No. It is not good! The hours hand would point straight at 11 o'clock, while it is 11:50. This means the hours hand should be pointing almost at 12 o'clock at this time. Just look at the image below to see what I mean.
Imagine you have to be somewhere at noon. This particular clock makes you think it's almost 11 o'clock, instead of 12. Now you would miss that great movie, blind date or work interview (hopefully in the web design field). OK. How to correct this?
So, when it's, let's say, 11:30 (I'm not using 11:50 because 11:30 is easier to understand), the hours hand should be positioned right between 11 and 12 hour markings. So that's why you add the minutes divided in half.
Imagine it is 11:30. The calculation would go like this:
this.hoursHand._rotation = (hours * 30) + (minutes/2);
this.hoursHand._rotation = (11 * 30) + (30/2);
this.hoursHand._rotation = 330 + 15;
this.hoursHand._rotation = 345;
That's it - with this addition you get just the small increment you need to make the hours hand point to the right place.
You just finished the actionscript clock! Whoaaaa! Cool!
Just so that you know, the SWF generated from this flash document has a filesize of only 760 bytes!!! Do you realize what this means?
This means you can place this clock in an intro, preloader or in a banner! And it will load instantly, even on slower connections! Now that is radical! With this clock, you rule. Your site rules. Your client's site rules.
And, what's completely cool, this is written in ActionScript 1.0 and compatible with flash player 6 and above. So be sure to set the ActionScript version to 1.0 and the Flash player version to 6.0 in the Publish settings dialog if you are working in Flash 8 or Flash MX 2004.
You can also change the line thickness, colors and alpha of all the elements of the clock with just a few keystrokes. No re-editing or re-drawing. Just change the code! This lesson's source files (both the simple clock and the one with the shining frame) can be downloaded below.
Download the tutorial's zipped source FLA file
You want to be even more cool? Make the shine on the clock as you've seen it at the beginning of this tutorial. What's the catch with the actionscript shine? It is using the same routine as the one used for generating the circle and the hours and the minutes markings. You just have to make smaller the range of the loop for this effect and put in the code that changes the alpha of the thick white line that is drawn. The line is fading at both ends, creating the shining effect. Voila!