MoveThis: Another AS3 Tweening / Animation Engine

– taterboy | February 1st, 2011

Filed under: ActionScript 3, Flash, Flex, Free Components/Classes, Games, Tutorials

UPDATE 1.20, 4/21/11 : new source files below

Animation is the primary reason our clients choose Flash based applications over HTML or any other language. Creating applications that dance is the “Rich” in RIA development.

Great animation or tween engines are plenty, GTween, TweenLite and Tweener are just a few. They provide a simpler way of animating with code. The Flash IDE team has also gone to great lengths to make working with animation in code easier for the designers. Even Flash Builder 4, which one could argue is a programmers tool, has new animation classes that are far more powerful than their predecessors.


Interactive Demos below…

Animation is what makes Flash, Flash:
MoveThis has been around in many different forms as my personal tween engine for the last 8 years. I think it’s finally in a condition that it can be shared. The idea has always been one line of code to make something move, it’s extremely simple to use, yet supports many great features.

This latest incarnation has focused on performance. Something that would work great for building mobile applications. It isn’t perfect, or the only solution, but it works with my approach to building applications and games that require a great deal of animation.

Most tween engines work on the theory that a tween is something to keep around and run backwards and forwards, something like a video file with a play and pause function. MoveThis is based on an idea that there are so many tweens in an application, trying to manage pausing, reversing, playing and completion events gets too complicated or resource heavy.

Using MoveThis has 4 requirements:
1. know the display object to move.
2. know which property of the display object to animate.
3. know that target value of the display object property.
4. know how many frames the tween will span.

The resulting code looks like this:

?View Code ACTIONSCRIPT
MoveThis.startTween(foo,{x:500},30);

…which animates the x property of “foo” to a value of 500 over 30 frames. There are no start methods to call or instances to manage. Once the tween is complete it is nulled out and garbage collected.

Performance:
MoveThis is fairly light and very good on performance. MoveThis can run about 5000 tweens simultaneously at 24 frames per second and create *6500 new tweens in 1 second at 20 frames per second. MoveThis will add about 9k to your application.

*Note: One of the benefits of MoveThis is that it eliminates duplicate tweens, this constant cleaning can cause performance lags when adding a large amount ( > 250 ) of tweens on one frame. To get the type of performance claimed above, set ignoreDupes to true.

?View Code ACTIONSCRIPT
MoveThis.ignoreDupes = true;

Pros:
MoveThis uses 1 EventListener for all tweens, also onComplete, onStart and onFrame events use callbacks instead of Events which is better for mobile application performance. Optimized to work with thousands of tweens without worrying about duplicates or stopping tweens.

Cons:
Maybe not the best solution for a project with just a few animations that need to loop, stop, pause, play and rewind.

Now lets talk features!

Standard Features:
1. MoveThis is frame based, I have found that even the Timer class is not consistent from client to client based on processor speed, so we might as well use frames which is more accustom to animation. At some point I may add getTime and audio syncing.

2. onComplete, onStart, onFrame as callbacks instead of events, which preserves performance. Returns a references to the object being animated.

3. The pause tween: for when you want to call a function later, after a few frames, again without adding new events or timers.

4. visible = true: if something is animating, then it is probably meant to be seen, MoveThis automatically turns the visible property to true when the tween begins. (can be overridden)

5. One tween per object property at a time: This is one of the main reason MoveThis was created the way it was. Users changes there minds without waiting for tweens to complete. MoveThis will replace older, in progress tweens with a new one, picking up where the last tween left off.

6. Plugins: animate non-numeric properties, such as matrix, color, brightness, volume with custom plugins. (color and brightness plugins included)

7. queue tweens: when limiting one tween per property at a time, tweens can be queued for later, without overwriting a current tween. Just like startTween, except the first argument sets how many frames the tween will remain in the queue.

?View Code ACTIONSCRIPT
MoveThis.queueTween(30, foo,{x:500},30);

8. pause: pause a current tween or all tweens

9. stop an individual tween or stop all current tweens for each display object.

10. When a tween is completed it is nulled out, freeing up memory for other stuff.

11: based on standard easing functions: includes Reverse and Arch easing functions, as well as, standard easing functions by Robert Penner.

How it Works:
Arguments:
1. targObject: (Object) A reference to the object that is to be animated.
2. propValues: (Object) An object containing all the numeric properties or plugins of the object that are to be tweened.
3. frames: (int) The amount of frames the tweens will span.
4. extras: (Object) Many features such as onComplete, easingFunction, loop and delay are set in the extras object.

?View Code ACTIONSCRIPT
MoveThis.startTween(foo,{x:500},30,{onComplete:completeHandler,easing:"Sine.EaseIn",delay:30});


Get Adobe Flash player


Extras (and how they work):
1. delay: (int) the frame count before the tween starts.

2. ease: (Number, 0 – 1) Adds an ease percentage to any easing function. designers like to add verity and subtlety to their animations, easing functions are no longer all or nothing.

3. easingFunction: (Function) Use standard or custom easing functions.

4. easing: (String, “Bounce.easeIn” ) Standard easing functions can be declared as a string, which elevates the need to import easing classes which helps in testing out a few different easing functions, trying to find that perfect ease.

5. loop: (Boolean) An animations can loop infinitely or just a few times.

6. visibility: (Boolean, false) Sets an object’s visible property to false after a tween.

7. startVisible: (Boolean, false) Override the default behavior of automatically setting an object’s visible property to true on the first frame of the tween.

8. remove: (Boolean) Automatically remove a display object or element after the tween is completed.

9. uid: (int ) A unique identifier, used for pause tweens, so they can be overwritten.

10. onStart, onFrame, onComplete: (Function) Callback functions, returns a reference to the animated object.

11. smartRotation: (Boolean) Forces the tween to rotate in the direction of the closest angle.

12. removeDupes: (Boolean, true) Default behavior is to remove all duplicates, but to save performance, you may want to turn this feature off and manage it on a per tween basis.

One Tween at a time:
Not to be stuck in an endless loop here, but this has a huge impact of how MoveThis is used, so one last time; I promise. Once a tween is completed in the MoveThis engine, it is removed and nulled out. If you need to reverse a tween or replay a previous tween, the best procedure is to start a new tween. MoveThis only allows one tween per property per object to occur at a time. If a tween is started on the x property of a displayObject named foo over 30 frames, when another tween is started just a few frames later for the same object’s x property, the first tween will be replaced by the new tween. Once the new tween is finished, it will be removed forever, unless a loop count was added.

One Tween for each property:
When a tween is started, an object (MoveThisObject) is created for each property to be animated. Each tween object is then animated separately. This allows you to start one tween with multiple properties, then update the animation by starting a new tween with of single property value.

Example:

?View Code ACTIONSCRIPT
	//initial tween
	MoveThis.startTween(foo,{x:500,y:400,:alpha:1},30);
 
	//something in our app changes, that require foo to fade out.
	MoveThis.startTween(foo,{alpha:0},30);

The x and y properties will continue to tween while the alpha property tween for foo will be replaced and the new fade out tween will began.

The repercussions are that if you have onComplete, onStart, onFrame callbacks assigned to that tween, the callbacks will be called for each property. In the following example, the function “completeHandler” will be called twice, once on complete of the x tween and once on the complete of the y tween.

Example:

?View Code ACTIONSCRIPT
MoveThis.startTween(foo,{x:500,y:400,:alpha:1},30,{onComplete:completeHandler);

Three Ways to Make Things Happen Later:
1. delay: The simplest way to delay a tween.

?View Code ACTIONSCRIPT
	//wait 20 frames before starting
	MoveThis.startTween(foo,{x:500},30,{delay:20});

Note: If this is used and another tween is added for the x property of foo, it will be replaced, even if the delay has not expired

2. queueTween: When you know you want to move something later, but do not want it to overwrite a current tween.

?View Code ACTIONSCRIPT
	//queue this tween for 30 frames
	MoveThis.queueTween(30,foo,{x:500});

Note: Once the queue time is complete, the queued tween will replace any existing tweens for the same property of the same object.

3. The pause tween: Used when you want to call a function after a certain number of frames. Easier and requires less processor than using the Timer class.

?View Code ACTIONSCRIPT
	//call pauseHandler after 90 frames.
	MoveThis.startTween(null,{pause:90},0,{onComplete:completeHandler});

Note: Frame count is ignored. The pause tween must include an onComplete function.

Note: Replace null with a displayObject reference to have that reference sent to the onComplete function.

Unique ID: By default all pause tweens are persistent, meaning duplicates for the pause property are allowed to exist. If you need to overwrite a pause tween, then give the tween a unique id, when a new pause tween is created with the same id, it will overwrite the previous one.

?View Code ACTIONSCRIPT
	MoveThis.startTween(null,{pause:90},0,{onComplete:completeHandler,uid:1});

onComplete Function Example:

?View Code ACTIONSCRIPT
function completeHandler(obj:Object):void{
	//all target references are returned as objects.
	//this allows you to start a new animation or modify the target when the animation is completed
	if(obj != null)
		obj.visible = false;
}

Easing:
Easing works very similar to all the existing tween/animation engines and works with any standardized easing functions. There are three ways to add eases to your animation.

1. easingFunction: This is the most typical ways of adding ease to a tween. Add a reference to any standardized easing function and you are done.

?View Code ACTIONSCRIPT
//add Sine.easeOut as the easingFunction. (the Sine.EaseOut class must be imported first)
MoveThis.startTween(foo,{x:500},30,{easingFunction:Sine.easeOut});

2. easing: An alternate method of #1 and for lazy people like me or someone that wants to try out a few different easing functions without importing them all. Enter one of the included standard tween function names as a string and MoveThis imports the correct easing function for you.

?View Code ACTIONSCRIPT
//add Sine.easeOut as the easingFunction without importing the class
MoveThis.startTween(foo,{x:500},30,{easing:"Sine.easeOut"});

3. easingStrength: Not every easing function has to be 100% all or nothing. Adding a 0 – 1 value will allow you to have a little less ease if needed.

?View Code ACTIONSCRIPT
//add Quart.easeOut as the easingFunction with only 60% ease.
MoveThis.startTween(foo,{x:500},30,{easing:"Quart.easeOut",easingStrength:0.6});

4. ease: Works just like the Flash IDE, set ease from -1 to 1 to automatically add Sine.easeOut or Sine.easeIn, depending on the value.

?View Code ACTIONSCRIPT
//add Sine.easeIn as the easingFunction with only 60% ease.
MoveThis.startTween(foo,{x:500},30,{ease:-0.6});

Note: There are two easing classes included to enable looping animations that reverse before looping again. (Arch.linear, Arch.easeIn, Arch.easeOut, Reverse.linear, Reverse.easeIn, Reverse.easeOut, Reverse.easeInOut, Reverse.easeOutIn)

Easing Demo:


Get Adobe Flash player


Visibility and Remove:
By default all tweened objects are made visible on frame one of a tween. You can override this functionality by adding startVisible:false to the extras.

?View Code ACTIONSCRIPT
//the object will not automatically turn visible on frame 1 of the tween
MoveThis.startTween(foo,{x:500},30,{startVisible:false});
<pre>
 
MoveThis will also set the visible property to false after a tween is complete or remove that object from the display list. These two features are extremely effective ways to free up memory.
 
<pre lang="actionscript">
//the object's visible property will be set to false at the end of the tween.
MoveThis.startTween(foo,{x:500},30,{visible:false});
 
//the object will be removed from the display list on complete of the tween
MoveThis.startTween(foo,{x:500},30,{remove:true});

Pause and Stop:
Pause and Stop only work on tweens that currently exist in the MoveThis engine. You can make a call to MoveThis to pause or stop a particular tween or you can and stop all the existing tweens for a particular object.

?View Code ACTIONSCRIPT
//finds a tween for the object "foo" and the property "x"
MoveThis.stopTween(foo,"x");
 
//finds all tweens for the object "foo" and stops them
MoveThis.stopAllTweens(foo");
 
//pauses an existing tween for the x property of the object "foo"
MoveThis.pauseTween(foo,"x",true);
 
//resumes an existing tween for the x property of the object "foo"
MoveThis.pauseTween(foo,"x",false);

You can also pause MoveThis using MoveThis.pause(true);

Plugins:
Plugins are a great way to add functionality and new tween-able properties to objects. Included are a couple classes to animate the color or brightness of an object. Plugins can be installed at runtime.

?View Code ACTIONSCRIPT
var plugin:Object = {brightness: com.hdi.animate.Brightness};
MoveThis.install(plugin);

The installedPlugins property of MoveThis is an array of all the currently installed plugins.

?View Code ACTIONSCRIPT
var plugins:Array =  MoveThis.installedPlugins; // [returns an array or objects]

Working with Flex 4 SDK:
To use MoveThis with Flex 4′s Group and Element classes, uncomment 3 snippets of code from com.hdi.animation.MoveThisEngine, to enable remove functionality. (sample snippet)

?View Code ACTIONSCRIPT
/***************************************************************
 * FLEX 4 SDK: UNCOMMENT FOR Group and Element support (2 of 3)	
***************************************************************/
	/*
	try{
            moveObj.targetObj.parent.removeElement(moveObj.targetObj as IVisualElement);
	}
	catch(e:Error){}
	*/
/*** END FLEX 4 SDK ********************************************/

UPDATE 1.20, 4/21/11 :

Updated code to run a little faster, using while loops instead of for each loops.
Added Sound or Mixer volume plugin to fade volume in and out.
Added methods for stopping queued animations

Download Complete Source Files

What tween engines do you like to use and why?

Technorati Tags: , , , , , , , , , , ,

Other Related Articles:

| 2 Comments » | facebook:

2 Comments »

  1. [...] MoveThis: Another AS3 Tweening / Animation Engine | Taterboy.com …Jun 10, 2008 … Turn 14 frames into 88 frames of animated movement by clicking the Tweening button. [...]

    Pingback by Tweening animation | Effectiveimage — July 23, 2011 @ 7:59 am

  2. [...] MoveThis: Another AS3 Tweening / Animation Engine | Taterboy.com …Oct 2, 2001 … Creating motion of objects in a movie. Changing Frame Rate, Dimensions and Background Color of the movie. [...]

    Pingback by Tweening animation | Esicoatings — September 12, 2011 @ 5:17 am

RSS feed for comments on this post. TrackBack URL

Leave a comment