CoreTween Programming Guide

Note: This page is heavily under construction. Please be patient while the CoreTween team is hard at work to finish the documentation for this page.

Introduction

This document describes CoreTween, a high-performance, low-latency tweening engine for the Flash Platform. CoreTween currently supports Flash Player 6, 7, 8 and 9 and is implemented in ActionScript versions 1, 2, 3 and the haXe programming languages.

CoreTween provides the user with not only a high performance tweening engine but also with a sequencer and an effects model. The sequencer can be used to play successive tweens in a row creating an animation of linear tweens. The effects model provides a system for animated filters or other special effects, some of which are included in the CoreTween package by default. The CoreTween architecture allows you to create your own custom effects built on top of the CoreTween base classes.

Whenever possible, CoreTween tries to keep a unified interface over all languages it supports without compromising the implementation specifics of the language functionality. This means that there might be small differences between implementations of CoreTween over different languages. One example of these differences is Event handling. In the languages that target Flash Player 8 and lower, event handling it not native to the Flash Player and therefore event handling is implemented in the form of callbacks. On the other hand, languages that target Flash Player 9 or higher, like ActionScript 3.0 and haXe for Flash 9, do support native event handling and therefore utilizing native events rather than callbacks.

Getting started

This section describes a quick start guide to get you up and running with CoreTween as soon as possible. All the examples in the section will be given using the ActionScript 2 programming language and should be approachable for most programmers with basic ActionScript programming knowledge.

Installing CoreTween

TODO: Explain installing CoreTween (extract from zip or checkout from SVN).

The Tween class

The Tween class is the most basic and primitive element of CoreTween. It is the Tween class that gives you control over CoreTween’s powerful tweening capabilities.

To get started with the Tween class, create a new Flash document (for ActionScript 2) and in the publishing settings of this document, set it to publish for Flash Player 8. Next, create a new MovieClip symbol in the library named Circle and draw a circle inside the newly created symbol with a width and height of 50 and centre the graphic around the origin.

After you have created the symbol in the library, place an instance of the Circle symbol on the stage, name it circle_mc and place it at position x50 and y50. The last thing to do is to place the following code on frame 1 of the newly created Flash document and test your movie.

import org.coretween.Tween;
import org.coretween.easing.Expo;
							
var tween : Tween;
tween = new Tween(circle_mc, { _x:250 }, 1.5, Expo.easeOut);
tween.start();

If everything went as expected, you should see the instance of the Circle symbol, that you created, move across the screen. If this is not the case then go back and revisit the steps from the start and try again.

Let’s see what the above code is doing. The first thing it does is import two classes from the CoreTween package. The first class is the Tween class from the org.coretween package and the second is the Expo class from the org.coretween.easing package that contains the easing equation, or formula, that gives this specific easing motion its specific signature.

The next thing the above code does is to define a variable called tween, which is of type Tween (notice the capitalizations?). Then, the code creates a new Tween object and stores a reference to this Tween object in the tween variable.

Let’s look at the parameters that the Tween class constructor takes. The first parameter is a reference to an object that needs to be tweened or operated on. In this case it’s the circlel_mc instance that we placed on the stage. Next, we need to specify which properties we want to tween. We do this, in this example, by specifying a nameless object (using the { } compound definition). The nameless object can specify one or more property/value pairs of the target object, of circle_mc in this example, that need to be tweened and the target values they need to tween to. Then, as a third parameter, the duration of the tween is given in seconds. In this example the tween is going to take 1.5, or one and a half, seconds to fully execute the tween. And last but not least, we define the easing equation that the tween uses to calculate its specific easing motion. In this case it’s the easeOut method of the Expo equation set, which is a nice and general-purpose ease out motion. Finally, we tell the tween to start tweening by calling the start method of the tween object.

That’s all there is to it. This is the basics of using CoreTween. If you’re a hardcore coder you’d probably know enough by now and you’d probably be more interested in the CoreTween API reference although you might need to check back on this text later. For those who need a bit more explanation, in the next sections we’re going to look at some more detailed information on how to use CoreTween.

Specifying delay

When a tween is started it is possible to specify a delay value. The delay value indicates how long a tween must pause, or wait, before the tween actually starts tweening.

import org.coretween.Tween;
import org.coretween.easing.Expo;

var tween : Tween;
tween = new Tween(circle_mc, { _x:250 }, 1.5, Expo.easeOut, 0.5);
tween.start();

The example above is the same code example as in the previous section. However, it specifies a delay of half a second (0.5) as the last parameter in the Tween class constructor. Delays can be very powerful. You could e.g. use delays to create successive playback of multiple tweens by pausing a second tween the time it takes a first tween to finish. However, CoreTween does provide a better way for successive playback then using delays, as we will see shortly when we discuss the CoreTween class (CoreTween’s sequencer). All in all, delays will come in handy from time to time and are a great asset to CoreTweens functionality.

Render method

CoreTween gives you the option to specify one of two render methods for every individual tween. The two options are either to render through frame based updates or through time based updates. You can specify an optional render method as the sixth parameter of the Tween class constructor.

import org.coretween.Tween;
import org.coretween.easing.Expo;

var tween : Tween;
tween = new Tween(circle_mc, { _x:250 }, 1.5, Expo.easeOut, 0.5, Tween.TIME);
tween.start();

Frame based rendering

Frame based rendering (Tween.FRAME) is based on the native Flash Player rendering system and is controlled by setting the FPS (Frames Per Second) property of your published swf. CoreTween selects frame based rendering as the default when no rendering method is specified for a tween. The higher you set the frame rate of your movie the smoother your tween will be executed. However, keep in mind that setting a higher frame rate means that the Flash Player will generate more frames per second, therefore increasing overall CPU usage per second while playing your movie. Most swf files use a FPS setting of somewhere between 20 and 30. A common default for this property is to set it to 24 FPS, which creates a reasonable illusion of smooth animation.

Time based rendering

Time based rendering (Tween.TIME) on the other hand bypasses the internal Flash Player rendering system and makes it possible to have a much higher update rate of frames for a specific tween which are independent of the swf’s FPS setting. Keep in mind that when using time based rendering your movie can use a lot more CPU speed, similar as to setting a higher FPS rate for your swf. However, time based rendering allows you to have a normal overall movie frame rate, like e.g. 24, and still have certain individual tweens, that need special attention, to be rendered at a higher FPS rate. Time based rendering should be used with caution because of this CPU utilization impact. Time based rendered tween are ideal for small and low impact tweens that, e.g., travel only a short distance, and that do not look smooth when executed in the default movie frame rate setting. Tweens that are rendered using time based rendering are rendered by default at 60 FPS (although this number is not guaranteed).

Please install or upgrade Flash Player to view this sample.
If you are sure you do have a suitable version of Flash Player installed then you're free to bypass the dectection.

The example above demonstrates the difference between frame based and time based rendering. In the example, the frame rate of the movie is set to 12 fps. As you you can see, the top animation is very choppy. This is because the animation is only updated with the movie defined frame update interval. The lower animation is much smoother. In CoreTween, a time based animation will have a fps of 60. However, in most cases the Flash Player will never be able to actually keep up with this fps. The reason for this can be different factors. Mostly this has to do with the limitations or CPU usage restrictions that the browser lies on the plugin. Even if the Flash Player can't guarantee the 60 fps, it will usually be higher than the overall frame rate of the movie (unless the default fps for time based rendering is set to a lower value).

The following code is the script that is the above demonstration:

import org.coretween.Tween;
import org.coretween.TweenStack;
import org.coretween.easing.Expo;

var prevTime : Number;

// create the top animation as a looping TweenStack object.
var stack1 : TweenStack;
stack1 = new TweenStack();
stack1.push( new Tween(ball1_mc, { _x:500 }, 1.5, Expo.easeOut, 0.5, Tween.FRAME ) );
stack1.push( new Tween(ball1_mc, { _x:150 }, 1.5, Expo.easeOut, 0.5, Tween.FRAME ) );
stack1.start();

// create the bottom animation as a looping TweenStack object.
var stack2 : TweenStack;
stack2 = new TweenStack();
stack2.push( new Tween(ball2_mc, { _x:500 }, 1.5, Expo.easeOut, 0.5, Tween.TIME ) );
stack2.push( new Tween(ball2_mc, { _x:150 }, 1.5, Expo.easeOut, 0.5, Tween.TIME ) );
stack2.start();

prevTime = getTimer();

this.onEnterFrame = function()
{
	var time : Number = getTimer();
	
	fps_txt.text = "FPS " + int( 1000 / (time - prevTime) );
	
	prevTime = time;
};

About events

One of the most common tasks when dealing with tweens is to wait for them to finish so that a next action can be taken. Depending on the language, Coretween implements event handling differently. The reason CoreTween breaks its unified interface in this regard is because CoreTween finds it more important to use native functionality than to force compliance to the least common denominator. Practically this means that all languages that target Flash Player 8 or lower (ActionScript 1, 2 and haXe for Flash) use callbacks whereas the languages that target Flash Player 9 or higher (ActionScript 3 and haXe for Flash9) use the native Flash Player event handling that was introduced with Flash Player 9.

Even though the different language variations use different methods of event handling, they do try to apply a common theme and that is the naming convention of the callbacks and events. If we take for e.g the complete event for Flash Player 9, which is triggered when a tween is finsihed executed, we see that the callback name for this event is onComplete whereas the event name is TweenEvent.COMPLETE.

import org.coretween.Tween;
import org.coretween.easing.Expo;

var tween : Tween;
tween = new Tween(ball_mc, { _x:250 }, 1.5, Expo.easeOut);
tween.onComplete = function()
   {
      trace(“Tween done!”);
   };
tween.start();

The above ActionScript 2 example demonstrates how an onComplete callback could be implemented for Flash Player 8 or lower. The following example demonstrates how an event handler could be implemented for ActionScript 3.0:

import org.coretween.Tween;
import org.coretween.TweenEvent;
import org.coretween.easing.Expo;

var tween : Tween;
tween = new Tween(ball_mc, { _x:250 }, 1.5, Expo.easeOut);
tween.addEventListener(TweenEvent.COMPLETE, onComplete);
tween.start();

function onComplete(event : TweenEvent)
   {
      trace(“Tween done!”);
   };

For more information on events, callbacks and a complete list of all the events that CoreTween supports see the section Event handing.

Tween more

Lets see what it takes to make CoreTween do more sophisticated things and let the Tween class do more work for us instead of tweening just one property at the time.

import org.coretween.Tween;
import org.coretween.easing.Expo;

var tween : Tween;
tween = new Tween(circle_mc, { _x:250, _y:250 }, 1.5, Expo.easeOut);
tween.start();

The above example is the same as used in the previous sections. However, in this example we added the _y property to the nameless object where we specify the properties we want to tween. When specifying more than one property the Tween object will tween all those properties within the same timeframe of the given duration. In the above example it will tween both the _x and _y properties at the same time. Both property values will be calculated using the same easeOut method of the Expo equation formulas.

Now you say, “Well that’s all nice, but what if the _x and _y properties are meant to tween with different equations?”. CoreTween has, of course, a solution for this.

import org.coretween.Tween;
import org.coretween.easing.Expo;
import org.coretween.easing.Back;

var tween : Tween;
tween = new Tween(circle_mc, { _x:250, _y:250 }, 1.5, [ Expo.easeOut, Back.easeOut] );
tween.start();

First, notice how we imported the Back equations class by importing it from the org.coretween.easing package. The Back equations give us other easing methods than the Expo equations do. The second difference is the fourth parameter of the Tween class constructor. Instead of specifying a single easing equation we specify an array of equations. As you might al ready guess, the first equation in the array applies to the first property listed in the nameless properties object. The second equation in the array applies to the second property and so on… If you do not specify the same amount of equations in the array as there are properties specified in the nameless object, then the properties for which no equation was specified will use the last equation specified in the array list.

Tween smarter

You might remember that when we talked about delays earlier, we mentioned the TweenStack class. The TweenStack class can be seen as a sequencer, in that it is basically built to play back successive tweens in a row, creating linear animations. Besides playing back tweens one after another, you can set the TweenStack object to loop a certain number of times or to even make it loop indefinitely. All in all, the TweenStack class adds a powerful tool to your toolbox.

Lets see how we can use the TweenStack class and how it makes it different from the normal Tween class.

import org.coretween.Tween;
import org.coretween.TweenStack;
import org.coretween.easing.Expo;

var stack : TweenStack;
stack = new TweenStack();
stack.push( new Tween(circle_mc, { _x:250 }, 1.5, Expo.easeOut ) );
stack.push( new Tween(circle_mc, { _x:50  }, 1.5, Expo.easeOut ) );
stack.start();
				

The above example creates a new TweenStack object and demonstrates how two tween objects are pushed onto its stack using the push method. As you might have noticed, the Tween objects that are pushed onto the CoreTween stack are exactly the same as we used them in the previous examples. You could say that a TweenStack object is composed of Tween objects.

Again the Tween objects used in the above example are fairly simple. Remember that everything that applies to the normal Tween class also applies to the Tween objects you’ll push onto a TweenStack. This means that you can create very complicated TweenStack animations animating multiple properties at once.

In-depth CoreTween

The previous chapter gave us a quick overview of how CoreTween works and it should have given you a quick start in how to use CoreTween. This section will go much deeper into how CoreTween works and we will discuss more of CoreTween’s advanced options and the alternative ways of using CoreTween.

The Tween class

In the previous sections we created new Tween objects and supplied all the details of the tween characteristics as parameters to the Tween constructor. Another way of specifying details about a tween is to use the tween properties instead.

import org.coretween.Tween;
import org.coretween.easing.Expo;

var tween : Tween;
tween = new Tween()
tween.target = ball_mc;
tween.values = { _x:250 };
tween.duration = 1.5;
tween.equations = Expo.easeOut;
tween.delay = 0.5;
tween.type = Tween.TIME;
tween.start();

The above example demonstrates how to create a new Tween object without specifying any of the details in the Tween class constructor. Instead all the details are specified with properties of the Tween object. Even when you use the Tween class constructor to specify the details of a tween, you can still read or write these properties to check what value they have or to simple change their value after you’ve instantiated the Tween class.

Reusing your tweens

One important aspect of CoreTween is to understand that CoreTween does not do any behind the scenes checking or management as other tween engines do. The most obvious problem that newcomers to CoreTween run into is the fact that CoreTween does not automatically stop or reset tweens when new a tween is started that operates on an object whose properties are already tweened by another tween object. From CoreTweens perspective, it’s the programmers’ responsibility to address these issues.

Often this means that tweens must be stopped or cancelled before another tween is started. It’s therefore wise to always store the reference to a tween object in a reference variable. A positive side effect of this is that it doesn’t only give you future control over the tween object, but it also let’s you reuse the tween object, saving resources.

Lets look at the most common problem that illustrates this issue. Imagine we want to scale an object on screen up when the mouse hovers over it and when the mouse stops hovering the object, or leaves it, we want the object to return to its normal state. So, we could write something like this:

import org.coretween.Tween;
import org.coretween.easing.Expo;

// assuming circle_mc is a MovieClip object on stage

circle_mc.onRollOver = function()
{
   var tween : Tween;
   tween = new Tween(this, { _xscale:150, _yscale:150 }, 1.0, Expo.easeOut);
   tween.start();
};

circle_mc.onRollOut = function()
{
   var tween : Tween;
   tween = new Tween(this, { _xscale:100, _yscale:100 }, 1.0, Expo.easeOut);
   tween.start();
};

At first glance it looks like there is nothing wrong with this example. In practice this could also be the case. However, when we look more closely we notice that when we hover the mouse over the object a new tween is created and executed which will scale up the object. If we move the mouse off the object it will create another tween object that scales down the object again to its normal size. As long as we always wait for the tweens to complete, there shouldn’t be any issues. The problem however, starts when we remove the mouse from the object while the up-scaling tween is still in progress. Because, when we roll over the object a new Tween object is created and started and within the time that tween is finished a new Tween object is created and started that does the opposite of the previous tween (which is still being executed). If this happens, there will be two tweens operating on the same object and the same properties of that object. The tweens will collide and its results are unpredictable.

To solve this issue we need to create a reference variable that holds a reference to a single tween object. This single tween object will replace the creation of the local tween objects that where created every time a roll-over or roll-out event handler was triggered. Not only provides this more control over the tweens (because its not just a local object anymore which is lost once the event handler exits) but we can also reuse the actual tween object which will result in better performance and memory usage.

import org.coretween.Tween;
import org.coretween.easing.Expo;

// assuming circle_mc is on stage

var tween : Tween;
tween = new Tween(circle_mc, { _xscale:100, _yscale:100 }, 1.0, Expo.easeOut);

circle_mc.onRollOver = function()
{
   tween.values = { _xscale:150, _yscale:150 };
   tween.start();
};

circle_mc.onRollOut = function()
{
   tween.values = { _xscale:100, _yscale:100 };
   tween.start();
};

The above example demonstrates how a single tween object is created which, from then on, can be reused every time the mouse hovers over or leaves the object. When the mouse hovers the object, the new target values are applied to the tween object and the tween is then again started. Starting a tween, or restarting it, will cause the tween to abandon its current operation and stop. Then the tween will start again and will tween towards the new set target values. This way, the two tweens will not interfere with each other.

Tween events

When working with tweens, you will probably want to be able to listen or wait for certain events to happen regarding the tween. The Tween class provides a range of events that can be used to react to a variety of states the tween can enter and we’ll discuss them in this section.

Event name Flash Player 8 and below Flash Player 9 and up
start onStart START
stop onStop STOP
pause onPause PAUSE
resume onResume RESUME
rewind onRewind REWIND
updateEnter onUpdateEnter UPDATE_ENTER
updateLeave onUpdateLeave UPDATE_LEAVE
complete onComplete COMPLETE

The above table shows the events that are supported by the Tween class. The first column lists the generic event names. The column with the header “Flash Player 8 and below” lists the names of the callbacks for ActionScript 2.0 and haXe for Flash whereas the column with the header “Flash Player 9 and up” lists the constants that are used to identify the events for native Flash Player event handling.

When implementing events for Flash Player 8 and below you need to implement the actual callback functions. The reason for this is that Flash Player 8 and below does not support native event handling.

import org.coretween.Tween;
import org.coretween.easing.Expo;

var tween : Tween;
tween = new Tween(circle_mc, { _x:250 }, 1.5, Expo.easeOut);
tween.onComplete = function()
   {
      circle_mc._x = 50;
      tween.start();
   };
tween.start();
				

The above example shows a typical implementation of an event callback. By simply assigning a function to the onComplete member of the tween you can take action whenever the tween is finished or completed. In the above example the circle_mc movieclip will its _x property reset to 50 and the tween will start again, making the tween repeat indefinitely.

To implement the same event in ActionScript 3.0, we would do the following:

import org.coretween.Tween;
import org.coretween.TweenEvent;
import org.coretween.easing.Expo;

var tween : Tween;
tween = new Tween(circle_mc, { _x:250 }, 1.5, Expo.easeOut);
tween.addEventListener(TweenEvent.COMPLETE, onComplete);
tween.start();

function onComplete(event : TweenEvent)
{
   circle_mc._x = 50;
   tween.start();
}

As you can see, first we import the TweenEvent class. This class does not only implement the event class for ActionScript 3.0 but it also defines the event mnemonics that are used to identify the events.

Start event

The start event is send whenever a tween is started through the start() method.

Stop event

The stop event is send whenever a tween is stopped trough the stop() method.

Pause event

The pause event is send whenever a tween is paused though the pause() method.

Resume event

The resume event is send whenever a tween is resumed through the resume() method.

Rewind event

The rewind event is send whenever a tween is rewind through the rewind() method.

updateEnter event

The updateEnter event is send before a tween is updated. You can use this event to take action before the object the tween operates on is affected the the tween.

updateAfter event

The updateAfter event is send after a tween is updated. You can use this event to take action after the object the tween operates on is affected. This event is useful to create hitchhikers.

Complete event

The complete event is send whenever a tween is finished tweening. Keep in mind that when a tween is stopped before its target values are reached, no complete event is send.

The TweenManager class

TODO

The CoreTween class

TODO

Using effects

Effects are a very powerful feature of CoreTween. With effects you can create complex tweens that you can use over and over again. The most obvious application for effects are probably filters that where introduced with Flash Player 8. By default, CoreTween includes a small number of effects like a GlowEffect and a BlurEffect. Of course, effects that use filters are only available for Flash Player 8 and up.

When using effects, there is not a real difference from using normal Tween classes. In fact, effects are in reality just tweens themselves in a sense that the Effect class (which is a base class for all effects) inherits actually from the Tween class which implements the Tweenable interface. Therefore you can also push effects onto a CoreTween stack to create a linear animation of effects and even interleave them with other tweens. The following example demonstrates a number of effects that are part of the default CoreTween package.

Please install or upgrade Flash Player to view this sample.
If you are sure you do have a suitable version of Flash Player installed then you're free to bypass the dectection.

Now, lets have a look at how we go about using these effects in our code.

The BlurEffect

Lets look at how to use the BlurEffect. As said before, using effects is not much different than using normal tweens and the same general techniques apply to effects. The following code demonstrates how you could implement the BlurEffect.

import org.coretween.Tween;
import org.coretween.easing.Expo;
import org.coretween.effects.BlurEffect;

// assuming circle_mc is on stage

var effect : BlurEffect;
effect = new BlurEffect(circle_mc, { xblur:0, yblur:0 }, 0, Expo.easeOut);
effect.start();

circle_mc.onRollOver = function()
{
	tween3.duration = 1.5;
	tween3.values = { xblur:20, yblur:20 };
	tween3.start();
};

circle_mc.onRollOut = function()
{
	tween3.duration = 1.5;
	tween3.values = { xblur:0, yblur:0 };
	tween3.start();
};

As you can see, in the first section of the code the BlurEffect class is imported. In the next section the actual effect object is created by instantiating the BlurEffect class and storing the reference in the effect variable. After the effect is created the mouse roll over and roll out handlers are created which will be triggered when the mouse hovers over or leaves the circle_mc MovieClip. As you can see, the effect instance is re-used which is considered good practice because it will prevent problems as discussed earlier in the section "Reusing your tweens" (TODO - Link).

As you might notice, when the effect object is created, in the constructor a 0 (zero) is passed for the duration of the effect and the effect is started right after it was created. You might wonder what the purpose of this is. Because the effect uses a Flash Player 8 bitmap filter it somehow needs to be initialized with this filter. When you start an effect that uses a Flash Player 8 bitmap filter the start method will detect if there is already a bitmap filter attached to the MovieClip onto which you want to apply the effect. If this is not the case then the effect object will create a default bitmap filter for the MovieClip (in this case a BlurFilter instance) with default variables. The default variables might be different than what you, as a user of the effect, might consider default values. Therefore by setting a duration of 0 (zero) and starting the effect we are forcing the creation of a BlurFilter object (if it didn't exist already) and we tween in a zero time frame to what we consider the default values for our effect.

The GlowEffect

Event handing

TODO

Effects programming

TODO

CoreTween internals

This section discusses CoreTween’s internal mechanics and is aimed at those who wish to learn more about what makes CoreTween tick and those who wish use CoreTween as a base product to build more sophisticated libraries.

Naming conventions

Before we start of discussing CoreTween’s internals we need to discuss the naming conventions that are used in CoreTween’s code. The following table lists CoreTween’s basic naming conventions:

Member variables

Class member variables are prefixed with an m_ to indicate these variables belong to the class. Variables that are not prefixed are considered local variables and belong to the function in which they were defined.

Constants

Constants that identify static variables are capitalized.

Arrays

Arrays are always defined in plural notation. So, an array that holds a list of tween objects would be named ‘tweens’.