Tornado Text

Tornado Text

The first system of three-dimensional space allows words to fly about in a seemingly chaotic vortex similar to the way ground debris is encaged within a tornado. Though wild in appearance, this system is actually rather constricted. As you will see during implementation, text within the tornado is not really free to do much more than spin about an axis, constrained within an imaginary cylinder. Still, the effect is rather stunning. Take a look at textTornado.swf .

click to expand

The construction of the tornado consists of three different movie clips. Open up textTornado.fla , available in this chapter's sample files from , and look in the Library (F11). First we have TextTornado itself, the main container movie clip that holds the entire system together and watches the mouse for interactive prompts from the user . Inside TextTornado there is a chunk of ActionScript that dynamically attaches a collection of TextTornadoRoto movie clips. TextTornadoRoto produces the three-dimensional effect of the system through simple adjustment of scale. Attached within each TextTornadoRoto is a collection of independent TextTornadoWord movie clips. Graphically, the TextTornadoWord is a text box loaded with some random words. The TextTornadoWord moves itself independently using wind, gravitation, and periodic levitation.

click to expand

Building the Tornado

Let's build the tornado from the ground up, beginning with its most crucial elements. As an alternative to typing all this code into Flash, you can follow along using the TextTornado.fla file.

  1. Within a new file (CTRL/CMD+N) or an existing project, create a new movie clip by selecting Insert > New Symbol... (CTRL/CMD+F8). Name it TextTornadoWord. Within the same Create New Symbol dialog box, enter advanced mode by clicking the Advanced button. This will provide access to the Linkage options. Link this movie clip by checking the Export for ActionScript and Export in first frame checkboxes. Give the new symbol the linkage identifier of textTornadoWord (note the lowercase t this time). Click on OK to create the new symbol. Later you will learn why it is critical that this movie clip be linked.

    click to expand
  2. Name the first layer of your new movie clip definition , and create a new layer named word . The order of the two layers on this timeline is not important.

    click to expand
  3. On the layer called word , use the Text Tool (T) to create a single dynamic text field. It might look something like this:

    click to expand
  4. Make sure the text field is dynamic, and assign it the variable txtword . You can assign the variable by selecting the text field and typing txtword in the Var field of the Property Inspector. This will allow you to dynamically place any word you want into this text field at the time of the creation of the tornado.

    click to expand
  5. To program this object, you will be prototyping the behavior of the TextTornadoWord so that it might be used in other places, at other times, for other purposes. For now, you are mainly interested in defining a word object that floats around randomly as if it is being affected by many disparate forces.

    click to expand

    The behaviour of all movie clips in this chapter are programmed using prototype functions. There are three advantages to using prototyped movie clips: they are transportable to other projects, extendable , and easy to convert into Flash MX components . It is also a great way to approach a programming excercise where there exist many similar objects.

  6. The entire code of the prototyped movie clip follows . This includes the skeleton of the prototype along with the two custom methods you will be using to give your movie clip behavior. For now, it is not important to concentrate on the syntax of the prototype. As the construction of this project continues, you will begin to notice similarities in design between the objects. Type this into frame 1 of the Definition layer of the TornadoTextWord movie clip:

      #initclip  // constructor  function TextTornadoWord() {   this.setup();   }  // allow TextTornadoWord class to inherit MovieClip properties  TextTornadoWord.prototype = new MovieClip();  // instance methods  TextTornadoWord.prototype.setup = function() {  // allow the word to fade in  this._alpha = 0;  // self set the word  this.txtWord =   Object.environment.wordlist[random(Object.environment.wordlist.length)];  // set the word on a tumbling course     this.onEnterFrame = this.tumble;    };  TextTornadoWord.prototype.tumble = function() {  // tumbling consists of arbitrary gravity, rotation, and levitation     // random levitation  if (!random(500)) {   this.vy = this.vy-random(5)-l;   }  // variable gravity  this.vy -= this._y/(1000+random(500));  // add vertical  this._y += this.vy;  // stop word from falling through ground  if (this._y>50) {   this._y = 50;   }  // random rotational velocity  this.rv += (random(7)-3)/4;   if (this.rv>4) {   this.rv = 4;   } else if (this.rv<-4) {   this.rv = -4;   }  // add rotational velocity to rotation  this._rotation = this._rotation + this.rv;  // fade in if not at 100% opacity  if (this._alpha<100) {   this._alpha+=1;   }   };  // Connect the class with the linkage ID for this movie clip  Object.registerClass("textTornadoWord", TextTornadoWord);   #endinitclip  

    The entire code block begins with an #initclip and ends with an #endinitclip. These two keywords tell Flash MX to initialize this object before any others. Although this is not required, it is a good idea if the object is used within other prototyped objects.

    The first step of the code block is very important: allowing the TextTornadoWord to inherit all the properties of the movie clip. Immediately afterward comes the setup function, which is executed each time an instance of this object is created. The setup function is a one-time event that sets the word up for its chaotic ride through the tornado.

    The two instance functions, setup and tumble , are custom functions that give your TextTornadoWord its behavior. The setup function does three things: it sets the alpha, or opacity, of the movie clip to zero (so that it can fade in); it sets the display word (using an array at the root of the movie); and it sets the word on its tumbling course through the tornado (by mapping the onEnterFrame event to the tumble function).

    The tumble function is what does most of the work in this project, so let's look at each section individually to understand how behavior is derived from code:

     // random levitation     if (!random(500)) {       this.vy = this.vy-random(5)-1;     } 

    This random conditional statement occasionally gives the word an intense upward thrust . As it appears here, there is a 1 in 500 chance of this happening. To increase the frequency of the upward thrusts, change the number 500 to something smaller. The variable vy represents vertical velocity. For each upward thrust you subtract a random amount. For stronger thrusts, increase the amount that is subtracted.

     // variable gravity     this.vy -= this.vy/(1000+random(500)); 

    You don't want your words to fly up and out of the screen, so with each frame, add some small amount of gravity to the word's vertical velocity. This method of variable gravity uses the word's current vertical position to determine how fast it should fall. Essentially , words higher up fall faster.

     // add vertical     this._y += this.vy; 

    This simple step adds the word's vertical velocity to the word's vertical position. Note that you never adjust the horizontal position of the word ”this is taken care of by the TextTornadoRoto , which you will build shortly.

     // stop word from falling through ground     if (this._y>50) {       this._y = 50;     } 

    Of course, you also do not want your words to fall through the bottom of the screen, so when the word is below a certain value, you set it to exactly that value. We have used a value of 50 pixels to give each word some clearance when rotating.

     // random rotational velocity     this.rv += (random(7)-3)/4;     if (this.rv>4) {       this.rv = 4;     } else if (this.rv<-4) {       this.rv = -4;     } 

    Similar to the random adjustment of vertical velocity, you'll do the same thing for rotational velocity. The variable rv represents rotational velocity. The previous code both randomly modifies the rotational velocity (in either direction) and assures that the value does not become too large. Here, a maximum rotation speed of 4 degrees per frame is allowed. That's pretty fast, so you may want to slow this part down by using a number less than 4.

     // add rotational velocity to rotation     this._rotation = this._rotation + this.rv; 

    This adds the rotational velocity to the word's rotation.

     // fade in if not at 100% opacity     if (this._alpha<100) {       this._alpha++;     } 

    This little hack increases the word's alpha if it's not at 100%. Keep in mind that you set the alpha of the word to zero in the setup function. This is an easy way to fade things in.

    All the preceding functionality combined defines a movie clip that rises and falls while rotating randomly about its center. You may have noticed that when the TextTornadoWord is set up, it sets a display word from an array of words in some object called environment . Where does this value come from? Where is the environment ? How do words get into the tornado? To answer these questions, you must keep building.

  7. Create a new movie clip called TextTornadoRoto (CTRL/CMD+F8). Export it with the linkage identifier textTornadoRoto (again note the lowercase t ) just as you did for the TextTornadoWord . Name the first layer definition (all code will be placed here) and create a new layer called words . This is going to be the layer where you will keep some instances of the TextTornadoWord you just created.

  8. Drag a couple of instances of the TextTornadoWord from the Library onto the stage within the words layer. For the most accurate visual results, keep the words to the right of the TextTornadoRoto movie clip's registration point. You may also size and position the words as you desire . Remember that the vertical position of the word is not really important, since the word changes its own vertical position once the movie starts. Your TextTornadoRoto words layer might look something like this:

    click to expand

    It's important that you do not place too many TextTornadoWords within the TextTornadoRoto . The total number of words in the tornado will be a multiple of how many words are placed here, as a fully assembled tornado consists of several TextTornadoRoto s. If there are too many words, the Flash player will get bogged down in computation and frames will be lost.

    The TextTornadoRoto movie clip can be thought of as a panel that spins about a vertical axis. Anything you put on the panel will spin along with it. Twice during the trip around the axis, the panel will momentarily disappear as it faces the user edge on, much like holding a piece of paper between your palms and looking at it straight on.

  9. Now you'll program the behavior of your TextTornadoRoto . Again, place the following code for the prototype in frame 1 of the definition layer:

      #initclip  // constructor  function TextTornadoRoto() {   this.setup();   }  // allow ParticleClass to inherit MovieClip properties  TextTornadoRoto.prototype = new MovieClip();  // instance methods  TextTornadoRoto.prototype.setup = function() {   this.onEnterFrame = this.spin;   };   TextTornadoRoto.prototype.spin = function() {  // increment rotation  this.theta = this.theta+this._parent.speed;  // keep theta reasonable  this.theta = this.theta%360;  // calculate spherical modifiers [-1..1]  var xbit = Math.sin(Math.PI/180*this.theta);   var ybit = Math.cos(Math.PI/180*this.theta);  // scale to show rotation  this._xscale = xbit*100;  // make word opaque when close, transparent when distant  this._alpha = 30+(ybit+1)*50;  // this.swapDepths(Math.round(this._alpha*4));  };  // Connect the class with the linkage ID for this movie clip  Object.registerClass("textTornadoRoto", TextTornadoRoto);   #endinitclip  

    Just as in the first movie clip you prototyped, the TextTornadoRoto uses #initclip and #endinitclip to indicate initialization importance. You may also notice the similarities in the prototyping syntax, but here you are mostly interested in the functionality of the TextTornadoRoto, largely embodied by the spin function.

    There are a few things going on in the spin function. Let's look at each section in more detail.

     // increment rotation     this.theta = this.theta+this._parent.speed; 

    The variable theta keeps track of the angle used in the 3D computations . Here, the angle is being adjusted by the parental variable speed . We will discuss how speed is determined when you build the final component of the system, the TextTornado . For now, it is important to know that ultimately the user controls the angle of the TextTornadoRoto .

     // keep theta reasonable     this.theta = this.theta%360; 

    As a user might sit hypnotized by your system for some hours, you must make sure that you do not let theta get too large or too small. A simple modulus operation keeps theta constrained within a reasonable range.

     // calculate spherical modifiers [-1..1]     var xbit = Math.sin(Math.PT/180*this.theta);     var ybit = Math.cos(Math.PI/180*this.theta); 

    The mathematics of the system involve only these two serious computations: that of xbit and ybit . Both of these variables oscillate between -1 and 1 , giving you nice sinusoidal modifiers for use in both scale and alpha. These two modifiers are key to the success of the text tornado effect. They are sinusoidal functions based on the angle theta . They are also the inverse of each other, such that when xbit is 1 or -1 , ybit is 0 , and when ybit is 1 or -1 , xbit is . As demonstrated in the scaling and opacity statements below, you need both variables.

     // scale to show rotation     this._xscale = xbit*100; 

    This is the essential transformation that produces the 3D effect. By simply changing the horizontal scale of your TextTornadoRoto panel (and consequently everything attached to it), you accurately and convincingly move the panel through three dimensions. Multiplying the value of xbit by 100 produces a smooth curve of values from -100 to 100 .

     // make word opaque when close, transparent when distant     this._alpha = 30+(ybit+1)*50; 

    Here, you want each panel to fade when it recedes into the distance. Just as you did with the scale , you can use the value of ybit to modify the _alpha of the movie clip. Negative values are not useful when talking about _alpha , so as a first step, you must add a constant of one. This shifts the range of ybit from to 2 . If you multiply this new value by 50 , you get an effective _alpha range from to 100 . As we didn't want the words to ever disappear entirely, we simply added a constant of 30 to the computed _alpha .

    This final statement is not necessarily required, so it has been commented out:

     //  this.swapDepths(Math.round(this._alpha*4)); 

    This is essentially a crude but effective way to sort the stacking order of the TextTornadoRoto S so that the movie clips that are closer to the user overlap those that are further behind. For black-and-white text, the overlapping is not obvious, so it's been commented out in this version of the tornado text to conserve precious processing power.

  10. For the final object in your system, create a new movie clip and name it TextTornado . Again, export this movie clip with a linkage identifier of textTornado . The TextTornado is the hub of this 3D text effect. The tornado is self-building, self-operating, and self-contained, and this will allow you to easily drop and drag tornados wherever you want them.

  11. Name the first layer of the TextTornado movie clip definition , and place the following code inside the first frame:

      #initclip  // constructor  function TextTornado() {   this.setup();   }  // allow ParticleClass to inherit MovieClip properties  Text Tornado.prototype = new MovieClip();  // instance methods  TextTornado.prototype.setup = function() {  // number of rotos  this.numRotos = 13;  // attach one rotational slice for each word  for (n=0; n<this.numRotos; n++) {  // give the rotational slice a name  var nombre = "roto"+String(n);  // distribute evenly around a circle  var init = { theta : n*(360/this.numRotos) };  // create and attach the new rotational slice  neo = this.attachMovie("textTornadoRoto", nombre, n, init);   }  // set the tornado in motion by watching them mouse  this.onEnterFrame = this.watchMouse;   };   TextTornado.prototype.watchMouse = function() {  // rotational speed of text tornado is directly related     // to horizontal mouse position  this.speed=this._xmouse/30;   };  // Connect the class with the linkage ID for this movie clip  Object.registerClass("textTornado", TextTornado);   #endinitclip  

    When a new TextTornado is created, it immediately assembles itself and begins to watch the mouse. The function setup carries out the assembly process. A given number of TextTornadoRotos are attached inside the loop. Each TextTornadoRoto is assigned a unique theta , juxtaposing it within the tornado. The angle is a function of the total number of TextTornadaRotos and the current TextTornadoRoto being attached.

    The function watchMouse runs throughout the lifetime of the tornado. It simply calculates speed directly based on the distance the mouse is from the center of the tornado. Each attached TextTornadoRoto references speed and spins accordingly . Having a centralized speed allows for efficiency of the calculation.

  12. As a final step, you need to define an array of words to place into the tornado. You do this at the root of the movie. In the first frame of any layer in the root movie, type the following:

     // register root as environment  Object.environment = this;  // create array of words to be used by text tornado  this.words = "friends of ed code poetry tornado left climbed   emily stormy weather particle cow time gonna need a bigger boat   data lost swept dead things mikey nothing leaving home today";   this.wordlist = this.words.split(" ");  

    This creates a globally accessible environment object containing an array of words visible to the TextTornadoWord movie clips. When each TextTornadoWord initializes, it chooses, by random, one of the words in this list. This method of sharing variables in a global fashion is repeated for all three systems discussed in this chapter.

  13. Drag an instance (or two) of the TextTornado onto the stage of your movie and test it (CTRL/CMD+ENTER). You should see spinning words slowly emerging from the background. Move your mouse from one side to the other and watch the tornado switch rotational directions. Watch this new construct for a while and you should begin to see the random levitation, variable gravity, and rotational acceleration that you just programmed into it:

    click to expand

In the following subsections we'll take a look at a couple of modifications to the tornado text movie.

Center-Facing Words

Thus far, the tornado's text is most readable around the outside edges of the tornado. Words that approach the center gradually become thinner until reaching dead center, at which point they appear paper thin. Suppose you want a movie that makes words most visible in the center ”how would you achieve that? In fact, you need only change the code in a few places to create such a system. The file textTornado_center.fla contains the following modifications (again, all the examples are available for download from ).

  1. The setup function of the TextTornadoRoto has an additional line of code:


    You need a random radius to make things appear chaotic. This radius will place the panel of words 50 to 250 pixels from the center of the tornado.

  2. New code also exists in the TextTornadoRoto definition layer, where the _xscale of the movie clip is calculated. The following line:

     this._xscale = xbit * 100; 

    is changed to this:

     // make word readable when in center  this._xscale = ybit * 100;   this._x = xbit * this.radius;  

    This way, the TextTornadoRoto is translated about the axis and scaled normally at the center, keeping it more readable.

    click to expand

Line to Origin

As another modification, it might be nice to connect each word to the origin of rotation by a single line. This is a theme that will occur again later in this chapter, and with the drawing API features of Flash MX, this kind of thing is both fun and easy to do. These changes have been implemented in the textTornado_line.fla (for more discussion of the drawing API in the context of 3D effects, be sure to check out Chapter 9).

  1. First, remove all rotation manipulation from the TextTornadoWord definition . You don't want the words to rotate, because it makes it more difficult to track the origin. The modified tumble function with no rotation appears as such, with new code shown in bold:

     TextTornadoWord.prototype.tumble = function() {     // random levitation     if (!random(500))  {       this.vy = this.vy-random(5)-1;     }     // variable gravity     this.vy -= this._y/(1000+random(500));     // add vertical     this._y += this.vy;     // stop word from falling through ground  if (this._y>50) {   this._y = 50;   }  // fade in if not at 100% opacity     if (this._alpha<100) {       this._alpha+ = l;     }     // draw a line to the origin  this.drawLineToOrigin();   };  
  2. Notice that the very last line in the preceding code calls a function named drawLineToOrigin . This is a new function that you will write yourself. Type the following in the first frame of the definition layer of the TextTornadoWord movie clip. It should be somewhere toward the end, but not after the class registration.

      TextTornadoWord.prototype.drawLineToOrigin = function() {   this.clear();   this.lineStyle(0, 0x000000, 25);   this.lineTo(-this._x, -this._y);   };  
  3. This function literally draws a translucent line to the origin of the TextTornadoWord within the TextTornadoRoto. The combined effects of this function clearly show what is actually going on inside the text tornado.

    click to expand

An interesting challenge would be to horizontally flip any word on the left side of the tornado so that all words could be easily readable at all times.

Flash 3D Cheats Most Wanted
Flash 3D Cheats Most Wanted
ISBN: 1590592212
Year: 2002
Pages: 97 © 2008-2017.
If you may any questions please contact us: