TransitionManager Events

I recently used the TransitionManager class to get some ready-made animation in a project I am working on. The problem was I needed to know when the tween ended so I could dispatch an event to tell my application to allow user interfacing again. I checked the Adobe API on TransitionManager and there were no events to respond to be found there. Not even a useful inherited event. So I decided to poke around in the class file itself just to see what was going on in there. In case you don’t know, never edit these classes. They are essentially part of the Flash application. If you need extra functions it’s always better to make a subclass extending the class and write your own methods and properties. That what OOP is all about.

There are 2 events that can be responded to in their without editing the code to do so. The two strings that you can add a listener for are these.

const ALL_TRANSITIONS_IN_DONE:String = "allTransitionsInDone";
const ALL_TRANSITIONS_OUT_DONE:String = "allTransitionsOutDone";

Of course, these events don’t carry any TransitionManager specific properties, it just dispatches the generic Event telling the application that it happened. I don’t know why this wasn’t included in the API, as it is something that is useful for this the implementation of this class. Maybe I’ll get around to writing a TransitionManagerEvent class one day. Until then, this works.

import fl.transitions.*;
import fl.transitions.easing.*;
 
const ALL_TRANSITIONS_IN_DONE:String = "allTransitionsInDone";
const ALL_TRANSITIONS_OUT_DONE:String = "allTransitionsOutDone";
 
var currentSlide:Slide = new Slide();
addChild(currentSlide);
 
var tm:TransitionManager = new TransitionManager(currentSlide);
tm.startTransition({type:Blinds, direction:Transition.OUT, duration:2, easing:None.easeNone, numStrips:10, dimension:0});
tm.addEventListener(ALL_TRANSITIONS_OUT_DONE, outTransitionsDone);
 
function outTransitionsDone(event:Event):void
{
	trace("done");
}

You can get the FLA example file here.

Associative Arrays

An Associative Array can be made in ActionScript 3 by using an Object instead of an Array. You use the Object to make a name/value pair. Name/Value pairs consist of a name and a value and are separated by a colon. The name is what you use to reference the value. When you reference what is in the Associative Array you just write the name as if it was a property on the Object. Here is an example of how to make an Associative Array.

var info:Object = {name:"Tony", occupation:"Bouncer", iq:80};
 
trace("My name is " + info.name + " and I am a " + info.occupation + " with an IQ of " + info.iq + "." );

You could also write it out long-handed and the effect would be the same. Below is the same thing but the names are added as dynamic properties of the newly instantiated Object.

var info:Object = new Object();
info.name = "Tony";
info.occupation = "Bouncer";
info.iq = 80;
 
trace("My name is " + info.name + " and I am a " + info.occupation + " with an IQ of " + info.iq + "." );

They only problem with this is that you lose the length property on this Associative Array. If you try getting the length property it will come up as undefined. I looked this up and found that Senocular actually has a class that fixes this. That class is called AssociativeArray and it can be found here. When I first tried it I got an error at line 32. I didn’t read the class to figure out what was wrong, but I commented out the line throwing the error and it seems to work fine. Here is an example of that class in action.

var info:AssociativeArray = new AssociativeArray();
 
info.name = "Tony";
info.occupation = "Bouncer";
info.iq = 80;
 
trace("My name is " + info.name + " and I am a " + info.occupation + " with an IQ of " + info.iq + "." );
trace(info.length);

Referencing the Document Class

Referencing the document class can be done in two ways. The first example uses brackets and a string. The brackets allows whatever is inside it to be ignored at compile time and used at runtime. If dot notation was used the compiler would try to find the function. It wouldn’t find the function and you would get a compiler error. The brackets hide it from the compiler and this is taken care of at runtime instead. The string, or the text in quotes, inside means that it is handled literally, letter for letter. This technique can also be used with a variable. This could be helpful if getting information at runtime. For example, if you are retrieving the name of a function from an external data source such as a XML file.

//example 1
root["functionReference"]();

The second example uses the Document Class name. This is very similar to dot syntax except the root keyword is put in parenthesis after the Document Class name. This technique can be used with properties and methods in the Document Class.

//example 2
DocumentClass(root).functionReference();

Loading… Please wait…

The Loader class is the Actionscript class made specifically to get JPG, GIF, PNG and SWF files from a remote source and load it into the main SWF file. The LoaderInfo class gives you specific information about the file being loaded. By using the bytesLoaded and bytesTotal properties of the LoaderInfo class it is possible to display the information in a number of ways.

Before it is displayed in these ways the preloader has to be written. Below is the step by step of a simple preloader. Two objects are required to start. A URLRequest and a Loader. The Loader is a new Loader instance. The URLRequest object accepts a string. The string is the file path to the file.

var myLoader:Loader = new Loader();
var myURLRequest:URLRequest = new URLRequest("images/image.jpg");

Next step is to make a text field to display the preloader text. This is done by making a new instance of the TextField class. To make sure all the text is displayed the autoSize property of the TextField class is used. This is set to the TextFieldAutoSize class. The TextFieldAutoSize class is a list of constant values used in setting the autoSize property of the TextField class. The constant value can be either NONE (default), LEFT, RIGHT or CENTER. Then, the text is added to stage for display.

var myTextField:TextField = new TextField();
myTextField.autoSize = TextFieldAutoSize.LEFT;
addChild(myTextField);

The load of the URLRequest object is started with the load method of the Loader class. This line of code can also be put inside a function such as a MouseEvent. When planning out your preloading you usually want to break it up in such a way that the user is not waiting too long for the file or files to load. A rule of thumb is preload every 300 KB. Button clicks serve as natural break points. The reason is that there is a possibility that the user may never make that click. If they don’t click it then there is no reason to ever load that information.

myLoader.load(myURLRequest);

An event listener is added for the completion of the loader. This function will only add the Loader to the display list. The function myAddLoader is listening for myLoader completion.

myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, myAddLoader);
 
function myAddLoader(event:Event):void
{
	addChild(myLoader);
}

An event listener is added for the preloader text. This event listener is a ProgressEvent. It listens to the contentLoaderInfo property of the Loader class. This function is where all the preloading magic becomes visible. This progress event displays the event’s progress in bytes to the TextField instance we set up earlier. The keyword event here refers to the myLoader event. The function myLoaderProgress is listening to myLoader.contentLoaderInfo.

myLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, myLoaderProgress);
 
function myLoaderProgress(event:ProgressEvent):void
{
	myTextField.text = event.bytesLoaded + " bytes";
}

The completed code would look something like this.

var myLoader:Loader = new Loader();
var myURLRequest:URLRequest = new URLRequest("images/image.jpg");
 
var myTextField:TextField = new TextField();
myTextField.autoSize = TextFieldAutoSize.LEFT;
addChild(myTextField);
 
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, myAddLoader);
myLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, myLoaderProgress);
 
myLoader.load(myURLRequest);
 
function myAddLoader(event:Event):void
{
	addChild(myLoader);
}
 
function myLoaderProgress(event:ProgressEvent):void
{
	myTextField.text = event.bytesLoaded + " bytes";
}

Now that the preloader is made, the information can be displayed in any number of ways. To change the way the preloader looks just change the code in the myLoaderProgress function.

For a percentage preloader divide the bytesLoaded by the bytesTotal. This will give a decimal number from 0 to 1. To make it a percent multiply by 100. If it is published now it will give you a whole number while followed by about 100 decimal places. To get rid of that use the Math class round method. It will chop off all the nasty extras. The % sign is concatenated as a string literal after all the other stuff to tell the user that this is indeed a percentage and not going to count up to one billion.

function myLoaderProgress(event:ProgressEvent):void
{
	myTextField.text = Math.round(event.bytesLoaded/event.bytesTotal * 100) + "%";
}

For a kilobyte preloader divide by 1000 because a kilobyte is one thousand bytes. Add the string literals to layout it out however you want. In this example it outputs “Total x KB of Loaded: x KB”.

function myLoaderProgress(event:ProgressEvent):void
{
	myTextField.text = "Total: " + Math.round(event.bytesTotal/1000) + " KB of Loaded: " + Math.round(event.bytesLoaded/1000) + "KB";
}

Beware Auto Format

Flash has some features to make coding easier. Some of the features include code collapse, code hinting, and commenting buttons. One of the other features is auto format which is extremely satisfying if your copy and pasting and your tabbing gets crazy.

If your code has no syntax errors auto format will indent it properly, add spaces and put your curly braces where you would like them to be. For even more control over auto format, you can change how it auto formats under preferences. Go to Flash > Preferences > Auto Format. There you can check off the auto format behaviors that best suit you.

There is one caveat to using auto format that could drive you to near madness if you can not prepared for it’s evil. It could add a line termination “;” to the class definition line. I’ve had it happen several times and I don’t know what makes it happen. I was unable to replicate it in a test. If it happens it will give you a 1084 error code in the Compiler window. It’s easily resolved, but it happened more than a few times to me, so I’d rather just be careful and use the tab key.

Colors and Numbers

There are 2 classes that deal with color. There is the appropriately named Color class and the ColorTransform class. Color is a subclass of the ColorTransform class. The Color class adds a few more features to the ColorTransform class such as control over brightness and tint.

A new instance of the ColorTransform accepts a lot of parameters. There is redMultiplier, redOffset, greenMultiplier, greenOffset, blueMultiplier, blueOffset, alphaMultiplier and alphaOffset. Personally, I find these values very counterintuitive. Give me good old HSB any day. All these crazy, meaningless numbers are additive, which means they are appended to the target’s current color value. If you have an exact color value in mind you can circumvent trying to figure out how to use all this stuff with the color property. The color property can be used with the Color class and the ColorTransform class. Below are simple examples of the usage of this.

//using color transform
var myColorTransform:ColorTransform = new ColorTransform();
myColorTransform.color = 0xFF0000;
my_mc.transform.colorTransform = myColorTransform;
 
//using color
var myColor:Color = new Color();
myColor.color = 0xFF0000;
my_mc.transform.colorTransform = myColor;

With this technique you can use an unsigned integer, which may look familiar to web designers because it commonly used in web safe colors. Flash’s color palette uses these numbers, so it is easy to make a color in Flash’s GUI and take these numbers to the Actions panel.

If you need to make a transformation with the Multipliers and Offsets, there is a place in Flash where you can visually get these values. When you have a Movie Clip selected in the properties window go to Color > Advanced. Click on settings, there is a dialogue with all the same parameters as in the ColorTransform constructor function. In this dialogue the multipliers are a percentage. The percentage here is written as a value from 1 to -1 in Actionscript. So pretty much add a decimal point. The Offsets to the right in the dialogue remain the same. This way you can visually get the colors right and plug those numbers in the code.

//color transformation from white movie clip to purple
var myColorTransform:ColorTransform = new ColorTransform(.45, -.28, .87, 1, -28, 143, -38, 0);
my_mc.transform.colorTransform = myColorTransform;

The result of this code is purple assuming the Movie Clip started out as white. Change the color of the symbol on the timeline and you’ll see that the resulting color is different. This goes back to the point that this process is additive. So make sure that the starting color is the color that you really want before taking the time to copy down and write the 800 numbers needed to change a color.

Custom Right Click Menu

To make a custom right click menu, you will need to use 3 classes. First, use the ContextMenuItem class to make new contextual menu items. Then, make an empty context menu with the ContextMenu class. Lastly those contextual menu items need to be passed to the Array class.

Create a new variable and data type it to ContextMenuItem. Make as many new contextual menu item vars as you want. The new ContextMenuItem takes 4 parameters. The first is a string, written in quotes. This is the text that will appear in the menu. The rest of the parameters are determined by Booleans, true or false. The next parameter is separator before. False means no separator, true means include one. Then the next is enabled. Default is true or enabled, this parameter is optional. Last parameter is visible, default is true.

var cmItem1:ContextMenuItem = new ContextMenuItem("First Item", false, false, true);
var cmItem2:ContextMenuItem = new ContextMenuItem("Second Item", false, false, true);

Then make a new instance of ContextMenu. That new instance has to be set to be the context menu for the main timeline. Assuming that you are writing this on the main timeline use the keyword this and use the contextMenu property of the ContextMenu class and make it equal to the new ContextMenu variable.

var cm:ContextMenu = new ContextMenu();
this.contextMenu = cm;

Then create an Array object to contain the contextual menu items. An array can be written like any other new instance of a class or it can be written shorthand. In the shorthand use only the brackets [] to contain the array items.

var cmArray:Array = [cmItem1, cmItem2];

Then those custom items in the array have to be added to the menu. This is done by using the customItems property and setting it equal to the array variable. Optionally, you can hide the built in menu items with the hideBuiltInItems method. Below is the completed code for the custom contextual menus.

//custom context menu
var cmItem1:ContextMenuItem = new ContextMenuItem("First Item", false, false, true);
var cmItem2:ContextMenuItem = new ContextMenuItem("Second Item", false, false, true);
var cm:ContextMenu = new ContextMenu();
this.contextMenu = cm;
var cmArray:Array = [cmItem1, cmItem2];
cm.customItems = cmArray;
cm.hideBuiltInItems();

Introduction

I am an Actionscript beginner. I am a novice, a noob if you will. This is all true, but I am going to write about Actionscript anyway. Why you ask? Why would you write about something you are not an authority on? The reason that I am starting this documentation early is for posterity. I want to see my progression from an Actionscript beginner to an Actionscript badass. Notice I didn’t say guru. I am not peddling holistic Tibetan Goji Berries. Badass is the appropriate term. Which is what I would like to be one day.

I am not a total novice. I have background in Web 1.0. I even got the Web 1.0.3 update. Before Actionscript 3.0, I even put together some Flash sites with AS2. Those successes were generally what I would call copy and paste programming. I could find something that someone made close to what I wanted to do and then tweak the code a bit to get it to work. The logic of programming escaped me, but the sites got done and no one got wise to my programmatic fumbling.

Before I begin this documentation I would like to throw out my disclaimers. Currently, I am a beginner at Actionscript 3.0 and perhaps some things that I write might be wrong or there just might be a much better way of doing what I did. By all means, feel free to correct me with a comment. I will learn from it. Also make sure to mention how much more of a badass you are than me in your commentary. I’ll try not to cry myself to sleep at night. The other reason I am writing this down is community. I know there are a lot of you out there tearing out your hair when you can’t find an answer to a problem. I read your blogs. All of them. I even found a few answers on some of them. Maybe one day there will be an answer for you on mine. Who knows, maybe one day you can totally ignore my PayPal tip jar and take some great Actionscript class I made. That is my dream that one day I hopefully will achieve.