October 14th, 2010
BSS Actionscript : The Display Package
This article explains the base concepts and functionality of the com.bigspaceship.display package which is part of the Big Spaceship actionscript package we recently made available on github. The name was chosen on the basis of the flash.display package and therefore contains core classes that Big Spaceship uses to build visual displays. It describes Big Spaceships standardized way of connecting library assets and animated timelines with coded functionality. All classes are made to work in any framework (PureMVC, Robotlegs, etc) and any coding environment (Flash IDE, FlashBuilder, Textmate, FDT, etc).
A bit of history: while working on timeline heavy flash sites, we noticed that a lot of animations and interactive components have a similar structure. For example, a lot of display symbols animate in, do something and then animate out. To make our lives easier we created a class called BigScreen which handled that functionality. We slowly created more and more classes that were little helpers in organizing timeline animation for display components like Buttons, Sliders, Preloaders, etc. This was beneficial for coders and designers equally, as it helped to speed up the process and left more time to concentrate on details. Over time each one of those classes evolved by itself until we started to notice overlapping functionality. So we decided to clean, combine, extend and standardize all classes that handle the timeline. We created a single base class – Standard. So turned BigScreen into StandardInOut.
Quick Overview:
The Standard class creates general access to the timeline and adds base properties like id. AnimationEvent and AnimationState classes standardize animation events, states and frame label names. All other classes extend Standard and add specific functionality for various display components like StandardInOut, StandardButton etc.
Pass a MovieClip, dont extend it.
Every display class needs access to the artwork that is a DisplayObject, usually a MovieClip. To make our classes work in every work flow we decided to generally not link library assets directly to existing classes. We are using an Object-Composition like approach instead of inheritance, and pass the artwork as a parameter to the constructor of a class. The class itself extends EventDispatcher to dispatch and listen to specific events. The main timeline and all library assets are just artwork that arent directly connected to any additional functionality through the linkage properties.
Why do we do this? One of the pillars to our code philosophy is that the process is designed around allowing as many people as possible to work at the same time. We want to keep our code and our artwork completely separate because if we had everything in one FLA file, changes would take forever to compile – even if we were making a minor code change that had nothing to do with the intense timeline animations. You can read more about making our workflow more efficient in this post, but for the scope of this article, all that matters is that its critical to the way we work that Standard classes access the artwork, it isnt the artwork itself.
The following code snippet describes the main functionality of Standard.as
public class Standard extends EventDispatcher{ protected var _mc:MovieClip; public function get mc():MovieClip{ return _mc; } public function Standard($mc:MovieClip){ _mc = $mc; } }
In addition to this basic principle we add the following often used properties to Standard:
state: a property that saves the current AnimationState
id: a property to give each instance a unique id
useWeakReference: a property that determines to use or not use weak event listener references.
We use Standard as the base class for all classes that deal directly with artwork, namely a MovieClip.
AnimationEvent, AnimationState: Communication between code and timeline.
To control timeline animations its important to know in which state the current animation is, as well as being able to tell a timeline what to do next. In AS3 the communication between a Standard derived class and the timeline is as simple as using frame labels and dispatching events on the timeline. The Standard classes automatically listen for these timeline events.
We standardized frame labels and animation events and created two classes called AnimationEvent and AnimationState. The two classes have the exact same constants and values and you could argue if both classes are necessary. We choose to keep the two classes because it makes code more readable e.g. in a statement like if(currentState == AnimationState.IN){};
All AnimationEvent and AnimationState values usually match the framelabel, e.g. AnimationEvent.START, has the value START and is dispatched on a frame with the frame label START.’
| Here is a quick overview of the most used Events and States | corresponding Framelabel | |
| public static const INIT | : String = “INIT”; | INIT |
| public static const IN_START | : String = “IN_START”; | IN_START |
| public static const IN | : String = “IN”; | IN |
| public static const OUT_START | : String = “OUT_START”; | OUT_START |
| public static const OUT | : String = “OUT”; | OUT |
| public static const START | : String = “START”; | START |
| public static const COMPLETE | : String = “COMPLETE”; | COMPLETE |
Example for a simple custom timeline animation using Standard and AnimationEvent.
A simple timeline looks like this:

Note that on frame 1, 7 and 30 theres some timeline ActionScript. The code there is this:
| Frame | Layer 1: //Labels | Layer 2: //Actions |
| 1 | INIT | stop(); import com.bigspaceship.Events.AnimationEvents; |
| 5 | START | dispatchEvent(new AnimationEvent(AnimationEvent.START)); |
| 50 | COMPLETE | stop(); dispatchEvent(new AnimationEvent(AnimationEvent.COMPLETE)); |
The Standard derived class will listen for that AnimationEvent and know how to handle it.
public class StandardExample extends Standard{ public function StandardExample ($mc:MovieClip){ super($mc); // add event listeners to the timeline _mc.addEventListener(AnimationEvent.START, _onAnimationStart_handler); _mc.addEventListener(AnimationEvent.COMPLETE, _onAnimationComplete_handler); } public function startAnimation(){ _mc.gotoAndPlay(START); // or _mc.gotoAndPlay(AnimationState.START); } private function _onAnimationStart_handler($evt:Event):void{ _curState = AnimationState.START; trace(animation state: +state); } private function _onAnimationComplete_handler($evt:Event):void{ _curState = AnimationState.COMPLETE; trace(animation state: +state); } }
Designers can then go into this timeline and change it to whatever, with as many frames in between the start and end as they want, so long as it dispatches that event at the right time.
The Mother of all Timeline Animations: StandardInOut extends Standard.
A traditional animation at Big Spaceship follows a simple flow: Animate In, Animate Out. Many projects have dozens – sometimes hundreds of clips that follow this simple concept. Standard is perfect for handling this. Enter: StandardInOut. StandardInOut simply allows you to animate a timeline in or out and then receive AnimationEvents when it starts and completes these animations. StandardInOut is written in a way that it can be extended very easily or be used as is. Weve built many of our Flash sites, AIR applications, games and experiences entirely by just extending and managing instances of StandardInOut.
All classes in the package that extend Standard, like StandardInOut or StandardButton, are directly tied to a specific timeline set up.
The basic timeline setup for StandardInOut looks like this:

Note the AS3 code on frame 1, 6, 20, 25 and 35:
| Frame | Lables | Actions |
| 1 | INIT | import com.bigspaceship.events.AnimationEvent; dispatchEvent(new AnimationEvent(AnimationEvent.INIT)); stop(); |
| 6 | IN_START | dispatchEvent(new AnimationEvent(AnimationEvent.IN_START)); |
| 20 | IN | stop(); dispatchEvent(new AnimationEvent(AnimationEvent.IN)); |
| 25 | OUT_START | dispatchEvent(new AnimationEvent(AnimationEvent.OUT_START)); |
| 35 | OUT | stop(); dispatchEvent(new AnimationEvent(AnimationEvent.OUT)); |
The class adds all the necessary listeners and manages all possible AnimationStates.
To animate the timeline In/Out you call one of the following two functions:
public function animateIn($forceAnim:Boolean=false):void{}; public function animateOut($forceAnim:Boolean=false):void{};
The functions check in what state its in and only animate if the timeline needs to switch states. For example if you call animateIn(), the animation only happens if the current state is not AnimationState.IN. In other words – it wont gotoAndPlay(IN_START) if you called animateIn() three times in a row… unless you wanted to do that, in which case you could call animateIn(true); to force the animation to play.
If you want to add more functionality when an animation starts or ends you can either add an EventListener directly to a StandardInOut instance like
myInOut.addEventListener(AnimationEvent.IN, doSomething);
(StandardInOut redispatches all basic Events from the timeline) or override one of the following functions:
protected function _onAnimateIn():void{}; protected function _onAnimateInStart():void{}; protected function _onAnimateOutStart():void{}; protected function _onAnimateOut():void{};
Usually we use those methods to set a localized text or trigger other animations in _onAnimateInStart. The _onAnimateIn method is often used to add more user interaction functionality.
StandardinOut has two handy properties:
isAnimating returns true if the StandardInOut is in between states.
dispatchCompleteOnUnchangedState, which defaults to true, is probably the longest variable name in the whole package but its functionality is hard to explain otherwise. It controls if an AnimationEvent is dispatched on an animateIn/Out call although there was no changes in states. This functionality was mostly added to use with SimpleSequencer. If set to true the sequencer can call animateIn() and receives a complete event right away to go to the next step if the StandardInOut class is already animated in.
Example of basic StandardInOut use:
If your MovieClip doesnt have any additional functionality, if all you want is a pretty animation to play in and out via the timeline you can go straight ahead and simply write:
var myStandardInOut:StandardInOut = new StandardInOut(myMovieClip); myStandardInOut.animateIn();
If you wanted to know when the animation is finished, you could write this:
var myStandardInOut:StandardInOut = new StandardInOut(myMovieClip); myStandardInOut.addEventListener(AnimationEvent.IN, _onAnimateIn_handler); myStandardInOut.animateIn(); function _onAnimateIn_handler($evt:AnimationEvent) { trace(In Animation Complete); }
Simple example to how to extend StandardInOut:
public class CustomInOut extends StandardInOut{ public function CustomInOut($mc:MovieClip):void{ super($mc); } override protected function _onAnimateInStart() : void{ trace(In Animation Started); } override protected function _onAnimateIn() : void{ trace(In Animation Complete); } }
Example file including source
Click into the flash movie above to add a random MovieClip from the library. All MovieClips are set up to work with the StandardInOut class. You can download the fla right here. Don’t forget download and add the Big Spaceship as3 package when you test it. For a better understanding, here is the code that i used on the main timeline:
var people:Array = ['street.general.people.shannon', 'street.general.people.matt', 'street.general.people.jarrod', 'street.general.people.daniel', 'street.general.people.dan', 'street.general.people.ayaka']; stage.addEventListener(MouseEvent.CLICK, _onMouseClick_handler); var myInOut:StandardInOut; function _onMouseClick_handler($evt:Event):void{ if(myInOut && myInOut.state == AnimationState.IN){ myInOut.animateOut(); myInOut.addEventListener(AnimationEvent.OUT, _onAnimateOut_handler); }else if(!myInOut){ var libItem:String = people[MathUtils.getRandomInt(0, people.length-1)]; myInOut = new StandardInOut(Lib.createMovieClip(libItem, this)); myInOut.mc.x = mouseX; myInOut.mc.y = mouseY; addChild(myInOut.mc); myInOut.animateIn(); } } function _onAnimateOut_handler($evt:Event){ $evt.target.removeEventListener($evt.type, _onAnimateOut_handler); StandardInOut($evt.target).destroy(); myInOut = null; }
I hope this post was useful for you. Enjoy using Big Spaceship’s Standard and StandardInOut classes.
