I am a Flash programmer based in Phoenix, Arizona. I currently work for Sarkissian|Mason, an interactive marketing agency. My personal web site is Brian.Shaler.nameThe first thing we need to do is get the symbols ready. The first symbol we will create is a movie clip to hold our dynamic textbox. We will call it «letterMC».

In this movie clip, we will place a dynamic textbox right in the center. To get a reasonable size for the textbox, I inserted a capital "W" and gave it plenty of room. You can make the textbox as big as you want, but if it's too small you will have problems. The properties I used for the textbox are below. I assigned it an instance name of "rawLetter". The rest of the properties won't affect functionality.

Ok, this part is VERY important when you are modifying dynamic text. You have to embed the fonts. To do this, click the «Characters...» button in the bottom right corner of the properties panel (shown above). When you click the button, the following dialogue box will appear. Select the characters to embed and click OK.

Next, we will create a symbol that will hold «letterMC». In this symbol, we can animate the letter with tweens on the timeline, but in this tutorial, we are going to do the modifications in ActionScript. We will call this one «letterAni» because it is where all animations will take place. Create the symbol as shown below, with ActionScript identifier set to «letterAni».

Once it has been created, place «letterMC» in the center of it and give it an instance name of «letterMC». (The same way you assigned "rawLetter" to the dynamic textbox, using the properties panel)
And finally, we are ready to begin ActionScripting! We will be writing script in two locations, Frame 1 of the main scene and Frame 1 of the «letterAni» symbol. First, we will script the symbol, then we will move on to the scene. When the script for the symbol is finished, we can drag an instance onto the main stage to test it.
Step 1: Modify the Y Scale for the spinning effect
A basic way to get the spinning effect is to change it a fixed percentage every frame, then when it reaches -100% or 100% it turns around. However, for a little more realism, we need to increase the change when the _yscale is smaller (nearing 0%) and decrease the change when it's larger (nearing -100% or 100%). There are several ways to accomplish this mathematically. Derive your own, or use mine:
scaleDirect will be either -1 or 1, depending on if the symbol is on it's way from 100% to -100% (-1) or from -100% to 100% (+1).
Math.floor is used to ensure that we have an integer. This is because we will feel the _yscale into a decimal->hexadecimal converter that only accepts integers.
The "1+" is to ensure that the change will be at least 1% because we need a constantly moving effect.
The rest is simply inverting the scale (smaller scale, more speed. larger scale, less speed) and keeping it within reasonable boundaries.
When _yscale reaches either -100% or 100%, we need to turn around scaleDirect. So, we add this code:
[as]if ( letterMC._yscale <= -100 || letterMC._yscale >= 100 )Step 2: Modify the textColor for a 3D-ish shading effect
Here's the concept: When the letter is facing the user, it is reflecting the most light. When it is laying flat, it will be dark. For giggles, we're going to make the front a different color from the back. Luckily, the brightness will be directly proportional to the letter's _yscale property. The complicated part of this is converting the decimal (base 10) _yscale value to a hexadecimal (base 16) color code. For those who have done web design in the past, you are probably familiar with RRGGBB hexadecimal color codes. For those who don't know what hexadecimal is, you will have to research it elsewhere, as it would double the length of this tutorial to explain it in detail.
Here is a quick and easy decimal to hexadecimal converter I created. You feed it a decimal number from 0-255 and it will return a hexadecimal number between 00-FF.
[as]hexChars = "0123456789ABCDEF"; function dec2hex (dec) { if ( dec > 15 ) { pos1 = hexChars.charAt( Math.floor ( dec / 16 ) ); pos2 = hexChars.charAt( dec - ( pos1 * 16 ) ); } else { pos1 = 0; pos2 = hexChars.charAt( dec ); } hex = pos1 + pos2; return hex; }[/as]We will create a variable «brightness» that will be double the letter's current _yscale, which is -100 to 100. «brightness» will then be -200 to 200. The decimal to hexadecimal converter handles numbers from 0-255. When brightness is negative, the back of the letter is facing the user, so we will use a different color, then change brightness to a positive number.
[as]brightness = letterMC._yscale * 2; if ( brightness >= 0 ) { newColor = "0x" + dec2hex(Math.floor(brightness*.5)) + dec2hex(Math.floor(brightness*.5)) + dec2hex(brightness); } else { brightness *= -1; newColor = "0x" + dec2hex(Math.floor(brightness*.7)) + dec2hex(brightness) + dec2hex(Math.floor(brightness*.7)); }[/as] For positive values of «brightness», the letter will be a shade of blue (0xrrggBB). For negative values, the letter will be a shade of green (0xrrGGbb). To assign the letter the color value «newColor», we simply add this line of code: [as]letterMC.rawLetter.textColor = newColor ;[/as]With these snippets, we can build the block of code below: (the only thing I didn't show above is the onEnterFrame event)
[as]// this goes in Frame 1 of the letterAni symbol scaleDirect = -1; hexChars = "0123456789ABCDEF"; function dec2hex (dec) { if ( dec > 15 ) { pos1 = hexChars.charAt( Math.floor ( dec / 16 ) ); pos2 = hexChars.charAt( dec - ( pos1 * 16 ) ); } else { pos1 = 0; pos2 = hexChars.charAt( dec ); } hex = pos1 + pos2; return hex; } this.onEnterFrame = function() { letterMC._yscale += scaleDirect * Math.floor(1+ ( 101-Math.abs(letterMC._yscale) )/15 ); if ( letterMC._yscale <= -100 || letterMC._yscale >= 100 ) { scaleDirect *= -1; } brightness = letterMC._yscale * 2; if ( brightness >= 0 ) { newColor = "0x" + dec2hex(Math.floor(brightness*.5)) + dec2hex(Math.floor(brightness*.5)) + dec2hex(brightness); } else { brightness *= -1; newColor = "0x" + dec2hex(Math.floor(brightness*.7)) + dec2hex(brightness) + dec2hex(Math.floor(brightness*.7)); } letterMC.rawLetter.textColor = newColor ; }[/as]So with that code in Frame 1 of «letterAni», all you have to do is drag it to the main stage and preview to see the "W" spin and change colors.
At last, the complicated parts are over. All we have to do now is use ActionScript in the main scene to attach copies of «letterAni» to the stage and change the letter in the dynamic textbox. This time, we will start with the onEnterFrame event. We will have a delay between letters, by counting frames and incrementing a variable. With variable «frame» initialized at 0, we increment it in the onEnterFrame event as follows:
[as]this.onEnterFrame = function () { frame++;[/as]When «frame» reaches a certain point (I used a 5 frame delay), it will pull the next character from our input string (as long as we haven't reached the end). I added comments to each line in the following block of code to make it as easy as possible to understand:
[as] if ( frame > 5 && counter < inputString.length ) // after 5 frames && if we haven't reached the end of the input string { // attach letterAni with a unique ID and depth attachMovie ( "letterAni", "letter" + counter, counter ); // give it a handler for convenience thisLetter = this["letter"+counter]; // place it 15 pixels to the right of the previous letter(s) thisLetter._x = 15 + counter*15; // each letter will be the same distance from the top of the stage thisLetter._y = 20; // assign an initial color. this is a shade of blue // 6363C0 will be the first result from the dec2hex() function thisLetter.letterMC.rawLetter.textColor = 0x6363C0; // populate the dynamic textbox with the // current letter from inputString thisLetter.letterMC.rawLetter.text = inputString.charAt(counter); // reset delay frame = 0; // go to next letter counter++; }[/as]Aside from this, all we have to do is initialize the variables and delete the onEnterFrame event (to save processor power). The complete code for Frame 1 of the main scene is as follows:
[as]// this goes in Frame 1 of the main scene frame = 0; counter = 0; inputString = "BRIAN SHALER"; this.onEnterFrame = function () { frame++; if ( frame > 5 && counter < inputString.length ) { attachMovie ( "letterAni", "letter" + counter, counter ); thisLetter = this["letter"+counter]; thisLetter._x = 15 + counter*15; thisLetter._y = 20; thisLetter.letterMC.rawLetter.textColor = 0x6363C0; thisLetter.letterMC.rawLetter.text = inputString.charAt(counter); frame = 0; counter++; } if ( counter >= inputString.length ) { delete this.onEnterFrame; } }[/as]