Animation in a Nutshell

The fundamental element of an animation is time, and in most cases a transition from one state to another. This state can be anything, such as a position, color, scale, transparency, volume, intensity, and so on.

In Adobe Flash, you can use either the timeline - or a combination of timelines - or ActionScript to create an animation.

In this example, ActionScript is used to create an animation.

You need the Adobe Flash plugin to see the animation.

Interpolation

Interpolation is a technique that provides an easy way to calculate the transition between two states over a period of time.
In ActionScript - or any other programming language - a state is most of the time represented by a number. For example, a color, volume, position, rotation angle, and so on.

In this example, the position of a sphere which moves from 'a' to 'b' is used to explain interpolation.

The interpolation formula is relative simple:


 position = a + (lambda * (b-a));

Interpolation and Actionscript

Let's take a closer look at the interpolation formula:


 position = a + (lambda * (b-a));

'b-a' is also known as delta. Delta is the value you have to add to 'a' to get value 'b'.
Delta can be positive or negative, depending on the value of 'a' and 'b'.

This formula allows you to calculate all positions between position 'a' and position 'b'. This is done by simply changing the value of the variable 'lambda' from 0.0 to 1.0.
If the value of lambda is equal to 0.0, the calculated position is equal to the value of position 'a', if the value of lambda is equal to 1.0, the calculated position is equal to position 'b'.
If lambda is equal to 0.5, the calculated position is exactly in the middle between position 'a' and 'b'.

If values below 0.0 or above 1.0 are used for lambda, the technique is referred to as extrapolation.

Suppose you want to make an animation that moves from position 'a' to position 'b' in twenty frames.
Instead of using time, a variable 'frame' is used. The value of this variable is increased by one every time Flash renders a new frame.

The code within the ActionScript command 'onEnterFrame' is executed every time Adobe Flash renders a new frame. Depending on the frame rate of the animation, the value of the variable 'frame' is updated 24 times a second if the frame rate is equal to 24; or if 31 is used as the frame rate, 31 times a second, and so forth.

The length of the animation measured in frames is used to calculate the value of lambda at a specific frame during the animation.

animation

The first frame of the animation is frame zero and the last frame is frame nineteen (not frame twenty!).
The value of lambda is equal to 0.0 at the start (frame 0) and 1.0 at the end (frame 19).
Lambda is calculated by multiplying the frame number by one nineteenth.
During the animation the value of lambda will increase from 0.0 to 1.0, and the animation will move smoothly from position 'a' to position 'b'.

keyframes of linear animation, all steps have the same length

In this example, 'a' is equal to the horizontal position 0, and 'b' is equal to the horizontal position 475.


 position = a + (lambda * (b-a));

The next table shows the result of the calculation per frame.

frame lambda position
0 0.0000 (0/19) 0
1 0.0526 (1/19) 25
2 0.1052 (2/19) 50
3 0.1578 (3/19) 75
4 0.2105 (4/19) 100
5 0.2631 (5/19) 125
6 0.3157 (6/19) 150
7 0.3684 (7/19) 175
8 0.4210 (8/19) 200
9 0.4736 (9/19) 225
frame lambda position
10 0.5263 (10/19) 250
11 0.5789 (11/19) 275
12 0.6315 (12/19) 300
13 0.6842 (13/19) 325
14 0.7368 (14/19) 350
15 0.7894 (15/19) 375
16 0.8421 (16/19) 400
17 0.8947 (17/19) 425
18 0.9473 (18/19) 450
19 1.0000 (19/19) 475



If the value of the positions 'a' and 'b' doesn't change and the length of the animation is increased, the animation will be slower. If the length of the animation is decreased the animation will be faster.

The variable 'total_frames' is used to store the length of the animation in the next example.


 var frame        : Number = 0;
 var total_frames : Number = 20;
 var a            : Number = 0.0;
 var b            : Number = 475.0;

 /**************************************************************/
 /*                                                            */
 /**************************************************************/

 onEnterFrame = function() : Void
 {var lambda, position : Number;

  lambda   = frame*(1.0/(total_frames-1.0));
  position = a+lambda*(b-a);
  frame    = (frame+1)%total_frames;
 }

The last line of code looks a little bit cryptic.


 frame = (frame+1)%total_frames;

The value of the variable 'frame' is increased by one. A so-called modulus operation (%) is used to limit the value of this addition. A modulus operation calculates the remainder of the division of the first value by the second value, which in this example is the value of the variable 'total_frames'.
The modulus operation can only be performed on so-called integers; variables like -1, 0, 1, and 2; in other words, natural numbers.

The next table shows the result of the modulus calculation.

frame frame%20
0 0 (0%20)
1 1 (1%20)
2 2 (2%20)
3 3 (3%20)
4 4 (4%20)
5 5 (5%20)
6 6 (6%20)
7 7 (7%20)
8 8 (8%20)
9 9 (9%20)
frame frame%20
10 10 (10%20)
11 11 (11%20)
12 12 (12%20)
13 13 (13%20)
14 14 (14%20)
15 15 (15%20)
16 16 (16%20)
17 17 (17%20)
18 18 (18%20)
19 19 (19%20)
frame frame%20
20 0 (20%20)
21 1 (21%20)
22 2 (22%20)
23 3 (23%20)
24 4 (24%20)
25 5 (25%20)
26 6 (26%20)
27 7 (27%20)
28 8 (28%20)
29 9 (29%20)



By using 'total_frames' in the modules operation, the result of the formula is always a number between 0 and 19 ('total_frames' minus one).
The animation starts again as soon as the last frame is drawn. Once the value of the frame becomes 20, the modulus operation reduces this number to 0 (see table).

Linear Interpolation

During the animation, the value of lambda increases with the same value of 1/19.
This type of interpolation is called linear interpolation.

keyframes of linear animation, all steps have the same length

By raising the value of lambda to a power - in ActionScript: Math.pow (number, exponent) - lambda increases or decreases during the animation, depending on the value of the exponent.

The code to calculate the position with lambda raised to a power:


 position = a + (Math.pow(lambda, 2.0) * (b-a));

Depending on the exponent value, the result is a so-called ease in or ease out animation.
An ease in animation starts slowly and ends relatively fast. The exponent has a value above 1.0.
An ease out animation starts relatively fast and ends slowly. The exponent has a value less than 1.0.

If the exponent is equal to 1.0, the result is a linear animation. The extra Math.pow command is in this case a waste of computation power, since the result of Math.pow (lambda, 1.0) is equal to the value of lambda.

An ease in or ease out animation looks less mechanical/more natural than a linear animation.

Ease In

keyframes of ease in animation, all steps have different lengths


 position = a+Math.pow(lambda,2.0)*(b-a);

frame lambda position
0 0.0000 Math.pow(0/19,2.0) 0
1 0.0027 Math.pow(1/19,2.0) 1
2 0.0110 Math.pow(2/19,2.0) 5
3 0.0249 Math.pow(3/19,2.0) 11
4 0.0443 Math.pow(4/19,2.0) 21
5 0.0692 Math.pow(5/19,2.0) 32
6 0.0997 Math.pow(6/19,2.0) 47
7 0.1357 Math.pow(7/19,2.0) 64
8 0.1772 Math.pow(8/19,2.0) 84
9 0.2243 Math.pow(9/19,2.0) 106
frame lambda position
10 0.2770 Math.pow(10/19,2.0) 131
11 0.3351 Math.pow(11/19,2.0) 159
12 0.3988 Math.pow(12/19,2.0) 189
13 0.4681 Math.pow(13/19,2.0) 222
14 0.5429 Math.pow(14/19,2.0) 257
15 0.6232 Math.pow(15/19,2.0) 296
16 0.7091 Math.pow(16/19,2.0) 336
17 0.8005 Math.pow(17/19,2.0) 380
18 0.8975 Math.pow(18/19,2.0) 426
19 1.0000 Math.pow(19/19,2.0) 475




 var frame        : Number = 0;
 var total_frames : Number = 20;
 var a            : Number = 0.0;
 var b            : Number = 475.0;

 /**************************************************************/
 /*                                                            */
 /**************************************************************/

 onEnterFrame = function() : Void
 {var lambda, position : Number;

  lambda   = frame*(1.0/(total_frames-1.0));
  position = a+Math.pow(lambda,2.0)*(b-a);
  frame    = (frame+1)%total_frames;
 }

Ease Out

keyframes of ease out animation, all steps have different lengths


 position = a+Math.pow(lambda,0.5)*(b-a);

frame lambda position
0 0.0000 Math.pow(0/19,0.5) 0
1 0.2294 Math.pow(1/19,0.5) 108
2 0.3244 Math.pow(2/19,0.5) 154
3 0.3973 Math.pow(3/19,0.5) 188
4 0.4588 Math.pow(4/19,0.5) 217
5 0.5129 Math.pow(5/19,0.5) 243
6 0.5619 Math.pow(6/19,0.5) 266
7 0.6069 Math.pow(7/19,0.5) 288
8 0.6488 Math.pow(8/19,0.5) 308
9 0.6882 Math.pow(9/19,0.5) 326
frame lambda position
10 0.7254 Math.pow(10/19,0.5) 344
11 0.7608 Math.pow(11/19,0.5) 361
12 0.7947 Math.pow(12/19,0.5) 377
13 0.8271 Math.pow(13/19,0.5) 392
14 0.8583 Math.pow(14/19,0.5) 407
15 0.8885 Math.pow(15/19,0.5) 422
16 0.9176 Math.pow(16/19,0.5) 435
17 0.9459 Math.pow(17/19,0.5) 449
18 0.9733 Math.pow(18/19,0.5) 462
19 1.0000 Math.pow(19/19,0.5) 475




 var frame        : Number = 0;
 var total_frames : Number = 20;
 var a            : Number = 0.0;
 var b            : Number = 475.0;

 /**************************************************************/
 /*                                                            */
 /**************************************************************/

 onEnterFrame = function() : Void
 {var lambda, position : Number;

  lambda   = frame*(1.0/(total_frames-1.0));
  position = a+Math.pow(lambda,0.5)*(b-a);
  frame    = (frame+1)%total_frames;
 }