Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning ActionScript 2.0 2006

.pdf
Скачиваний:
105
Добавлен:
17.08.2013
Размер:
12.47 Mб
Скачать

Chapter 17

// each layer behind gets progressively faded pBaseTimeline[“layer” + pCurrentLayer]._alpha = 100; pCurrentLayer = (pCurrentLayer + 1) % pNumLayers; for (var j:Number = 0; j < pNumLayers; j++)

{

pBaseTimeline[“layer” + ((pCurrentLayer + j)%pNumLayers)]._alpha ; = (j/pNumLayers)*100;

}

// Clear out the last layer, at 0% alpha pBaseTimeline[“layer” + pCurrentLayer].clear();

}

// Update the position of the drawing clip, and trace the line behind it. function plotLine(i:Number, drawLine:Boolean)

{

pBaseTimeline[“layer” + pCurrentLayer].lineStyle(1, pLineColour, 100); pBaseTimeline[“layer” + pCurrentLayer].moveTo(pPointX[i], pPointY[i]); // x/y coordinates are calculated based on rotation and scale of each dot pPointX[i] = (Math.cos(pPointDegree[i]) * pPointScale[i]);

pPointY[i] = (Math.sin(pPointDegree[i]) * pPointScale[i]); if (drawLine == true)

{

pBaseTimeline[“layer” + pCurrentLayer].lineTo(pPointX[i], pPointY[i]);

}

}

// Update random values function updateSeeds()

{

var deg:Number; var scale:Number;

//Set degree values uniformly across all points deg = randomRange(-100, 100) / 2000;

//Set scaling values uniformly across all points if (pPointScale[0] > pMaxSize)

{

scale = randomRange(-10, 0) / 2;

}

else if (pPointScale[0] < -pMaxSize)

{

scale = randomRange(0, 10) / 2;

}

else

{

scale = randomRange(-10, 10) / 2;

}

//Assign degree and scale values to each point for (var i:Number = 0; i < pNumTraces; i++)

{

pPointDegreeChange[i] = deg; pPointScaleChange[i] = scale;

}

pLineColour = randomRange(0, 0xFFFFFF);

428

Automated Transitions

}

// Calculate a random integer between two numbers; function randomRange(min:Number, max:Number):Number

{

var randomNum:Number = Math.round(Math.random()*(max-min))+min; return randomNum;

}

init(this);

7.Select Control Test Movie to try it out.

How It Works

This screen saver works by storing the degree and the distance values for each point, then animating those values. By adding 10 degrees to the rotation value for each point, they all move together in unison around the center by 10 degrees. By adding 10 pixels to the scale value for each point, they all move away from the center in unison by 10 pixels. By then randomizing how many pixels to add and remove, and how many degrees to rotate the animation by, you get random patterns being generated by the lines that are produced. The traces are created and faded by drawing each new line segment into its own layer, then adjusting the alpha of all the previous layers until the last one is blank and can be reused for the next segment.

First, some data needs to be saved. The maximum reach of the lines, the coordinates for the middle of the screen, the number of lines to animate, and the number of line segments that make up each trace are stored. Also, the current top layer and the color of the line to draw in the layer are saved:

var pMaxSize:Number = 150; var pCenterX:Number = 275; var pCenterY:Number = 200; var pNumTraces:Number = 20; var pNumLayers:Number = 30; var pCurrentLayer:Number = 0; var pLineColour:Number;

Arrays are used to store the degree, scale (distance from middle), and x/y coordinates for each point. The pPointDegree and pPointScale arrays store the degree and scale values for each point. The pPointDegreeChange and pPointScaleChange arrays store the values indicating how much the degree and scale values are going to change for the next animation update. When these values do not change, each point maintains the same rotation and the same rate of approaching or leaving the center point. By randomly changing these values, you cause all the points to shift their rotation and approach, giving the zigzag effect that you see:

var pPointDegree:Array = new Array();

var pPointDegreeChange:Array = new Array(); var pPointScale:Array = new Array();

var pPointScaleChange:Array = new Array(); var pPointX:Array = new Array();

var pPointY:Array = new Array();

A couple of variables store a handle to the main timeline and the ID for the interval used to periodically update the pPointDegreeChange and pPointScaleChange values:

429

Chapter 17

var pBaseTimeline:MovieClip; var pIntervalId:Number;

Within the init() function, a movie clip is created to hold the animation. Within that movie clip, more movie clips are created and moved so that the x=0, y=0 point is at the middle of the screen. This helps avoid a bit more math, because it is easier to work the math around 0,0 than around 275,200. Each of these movie clips are layers used to hold one part of each line segment, and as the alpha values of the layers are faded, so are the line segments that they hold:

pBaseTimeline = baseTimeline; pBaseTimeline.createEmptyMovieClip(“holder”, 0);

for (var j:Number = 0; j < pNumLayers; j++)

{

pBaseTimeline.createEmptyMovieClip(“layer” + j, j+1); pBaseTimeline[“layer” + j]._x = pCenterX; pBaseTimeline[“layer” + j]._y = pCenterY;

}

Start positions are set for each trace:

initTraces();

The animation is started up, with the moveSpheres() function being called every frame, and the updateSeeds() function being called every 2 seconds to change the direction of the traces:

pBaseTimeline.holder.onEnterFrame = function()

{

moveSpheres();

}

pIntervalId = setInterval(this, “updateSeeds”, 2000);

The initTraces() function sets starting values for each trace. It spreads the points evenly around the circle. Unfortunately, one complication is that the units used are actually radians, because the standard trigonometric functions do not use degrees. The conversion between the units is 360 degrees = 2 * π = 2 * 3.1416 = 6.2832 radians:

for (var i:Number = 0; i < pNumTraces; i++)

{

pPointX[i] = 0; pPointY[i] = 0;

pPointDegree[i] = (6.28318530718/pNumTraces) * i; pPointScale[i] = 50;

}

The change arrays are updated with new random values:

updateSeeds();

for (i = 0; i < pNumTraces; i++)

{

plotLine(i);

}

430

Automated Transitions

The moveSpheres() function adjusts the degree and scale values for each point based on the degree change and the scale change values:

for (var i:Number = 0; i < pNumTraces; i++)

{

pPointDegree[i] += pPointDegreeChange[i]; pPointScale[i] += pPointScaleChange[i]; plotLine(i, true);

}

The code goes through each layer starting from pCurrentLayer, fading it a bit more until it gets to the last one. The % (modulo, aka remainder) operator makes sure that when the loop passes the number of available layers, it loops back to zero and starts again:

pBaseTimeline[“layer” + pCurrentLayer]._alpha = 100; pCurrentLayer = (pCurrentLayer + 1) % pNumLayers; for (var j:Number = 0; j < pNumLayers; j++)

{

pBaseTimeline[“layer” + ((pCurrentLayer + j)%pNumLayers)]._alpha ; = (j/pNumLayers)*100;

}

// Clear out the last layer, at 0% alpha pBaseTimeline[“layer” + pCurrentLayer].clear();

The plotLine() function does the actual drawing of each line segment, converting the degree and scale combination to x and y coordinates:

pBaseTimeline[“layer” + pCurrentLayer].lineStyle(1, pLineColour, 100); pBaseTimeline[“layer” + pCurrentLayer].moveTo(pPointX[i], pPointY[i]); // x/y coordinates are calculated based on rotation and scale of each dot pPointX[i] = (Math.cos(pPointDegree[i]) * pPointScale[i]);

pPointY[i] = (Math.sin(pPointDegree[i]) * pPointScale[i]); if (drawLine == true)

{

pBaseTimeline[“layer” + pCurrentLayer].lineTo(pPointX[i], pPointY[i]);

}

The updateSeeds() function chooses new values for the degree change and the scale change values as well as a new color for the lines. It makes sure that when the distance from the middle becomes too great, it forces a negative value for the scale values. You may note that the degree change and the scale change values are the same for each point, making the use of an array to store them a waste. While that is true, they do not have to be the same for each point. You could modify this function to choose different values for each trace, either randomly or using a pattern to animate, for example, an ellipse instead of a circle:

var deg:Number; var scale:Number;

//Set degree values uniformly across all points deg = randomRange(-100, 100) / 2000;

//Set scaling values uniformly across all points if (pPointScale[0] > pMaxSize)

{

scale = randomRange(-10, 0) / 2;

431

Chapter 17

}

else if (pPointScale[0] < -pMaxSize)

{

scale = randomRange(0, 10) / 2;

}

else

{

scale = randomRange(-10, 10) / 2;

}

// Assign degree and scale values to each point for (var i:Number = 0; i < pNumTraces; i++)

{

pPointDegreeChange[i] = deg; pPointScaleChange[i] = scale;

}

pLineColour = randomRange(0, 0xFFFFFF);

The code ends with the randomRange() function, the same utility function described earlier to help with picking random values.

Summar y

This chapter covered many different aspects of ActionScript-based animation. Some of the things that you learned include the following:

How to use the Tween class to take control of the actual animating.

The easing classes allow you to specify how the tween accelerates and decelerates through the course of the transition.

Tweens can be run in parallel by simply instantiating multiple tweens. They can also be chained together in a sequence by making use of the onMotionFinished Tween event.

The drawing API makes for a great source of creative animation possibilities. Using polar coordinates allows you to get out of a linear way of thinking.

Exercises

1.Starting from the Try It Out exercise called “Multiple Tweens on an Elasticized Box,” add another tween to manipulate the transparency of the box. Pass in a fixed color and the tweened value for the alpha value to use for the drawing, and modify the drawBox() function so that it draws a fill with the color and alpha values passed to the function.

2.Modify exercise 1 so that it no longer yoyos. Place a button on the screen that when pressed, toggles the direction of the animation, but only when the previous animation has completed.

432

18

Handling Text

The TextField is the class used to display text in Flash. Text fields can be drawn onto the stage with the Tools panel’s Text tool. Text fields can be created with ActionScript using a robust property and method set at runtime. Each version of Flash makes improvements over the last and text fields always get some type of enhancement. Flash is continually being adopted for rich network applications, where different kinds of data need to be displayed in different ways with different text formatting.

Text, of course, is a complex subject, with terms like ASCII, ANSI, Unicode, escape characters, HTML code, kerning, smoothing, leading, style, and more. This chapter covers the basics of working with text.

Thankfully, Flash 8 clears up many issues and bugs associated with text in Flash. The capability to cache text as bitmaps allows a new level of text animation and integration within your user interface.

The most notable addition to the Flash 8 text features is FlashType, known to most by its preview name: Saffron. FlashType is a text-rendering engine that produces extremely smooth, clear, and readable text. New features in Flash 8 allow precise control over how and when text attributes are modified.

Three types of text fields exist: static, dynamic, and input. The input text field can also be used as a password input text field, which displays only asterisks as the user types. For each type, you have the choice of using default system fonts that exist on each of the end users’ computers or of using fonts that you embed within the Flash movie.

In this chapter, you learn how to create text fields on-the-fly and how to manipulate text attributes such as font, size, color, word-wrapping, and font embedding. You learn about how to apply rich text formatting, to include HTML in a text field, and to extend the capability to apply text formatting through the use of style sheets. Finally, you explore different techniques for creating scrollable regions of text.

Chapter 18

Creating Text Fields with ActionScript

Creating text fields with ActionScript is straightforward. You use the createTextField() method to place text on any timeline.

Field Instance Names Versus Field Variable Names

When creating text fields with ActionScript, it is usually best to use the text property of the TextField class. There is also the variable property, which allows the text field to show the current state of any variable without explicitly assigning text to the text field. This is especially helpful in chat applications built using the XML socket.

In the following example, the text field usernameField would reveal the current state of the variable username:

var username:String = “jberg”; usernameField.variable = “username”;

System Fonts and Embedded Fonts

When you embed a font within your application, a duplicate of the font is created and placed in the final SWF file. By embedding fonts, you ensure that the application looks how you intended because the user does not need to have the specified font on his system. This can be particularly useful when developing multilingual applications, where the target system is not required to have the specific font for the language installed.

When a font is not embedded, the end user’s system provides the closest match to the font requested by Flash. This is similar to HTML where you can specify sans, serif, or a group of fonts to search through, looking for the first font that exists on the user’s system. For example, you may specify a serif font, and the end user system will provide the main serif font specified on the system. If you specify Georgia, Times, Courier as a group of desired fonts, it will try each until it can display one of them, or it will find the closest match on the system. It is generally safe to rely on default lists, as you would with HTML. You can generally predict that most users will have Times, and most will have some Arial variant. Otherwise, if this lack of control over type disturbs your design, or the motion graphics in your application require a specific font to fit and function properly, you’ll want to use the embed option.

Creating a Text Field On-the-Fly

The first thing that you need to know how to do is to create a text field. A method of the MovieClip class, called createTextField(), enables you to create a text field using the chosen movie clip as a holder. The basic form of this method looks like this:

MovieClip.createTextField(instanceName:String, depth:Number, x:Number, y:Number, ;

width:Number, height:Number);

The following snippet shows createTextField()in use, placing a 100x30-pixel text field at position 10, 10 on the main timeline, and giving it the value “jberg”:

this.createTextField(“username”, this.getNextHighestDepth(), 10, 10, 100, 30);

username.text = “jberg”;

434

Handling Text

Try It Out

Creating Dynamic and Input Text Fields On-the-Fly

Ready to create some text fields? Just follow these steps:

1.Open a new FLA file. Save the file as textTest.fla in your workspace.

2.Add the following code to frame 1:

var titleField:TextField = createTextField (“field1”, this.getNextHighestDepth(),

;

20, 20, 200, 20); titleField.text = “Login!”;

var nameField:TextField = createTextField (“field2”, this.getNextHighestDepth(), ; 20, 50, 200, 20);

nameField.border = true; nameField.type = “input”; nameField.text = “Name”; nameField.onSetFocus = function ()

{

this.text = “”;

};

nameField.onKillFocus = function ()

{

if (this.text == “”)

{

this.text = “Name”;

}

};

var passwordField:TextField = createTextField (“field3”, ; this.getNextHighestDepth(), 20, 80, 200, 20);

passwordField.text = “Password”; passwordField.border = true; passwordField.type = “input”; passwordField.onSetFocus = function ()

{

this.text = “”; this.password = true;

};

passwordField.onKillFocus = function ()

{

if (this.text == “”)

{

this.password = false; this.text = “Password”;

}

};

3.Test the movie by selecting Control Test Movie. Click the various text fields to see how they behave.

435

Chapter 18

How It Works

By using the createTextField() method and applying different properties to each type of text field, you were able to quickly create a very simple input interface.

The title field allowed the text field to default on all attributes except text. The text attribute was used to place the word “Login!” within the text field. You could also declare titleField.selectable = false to disallow the user from being to select it.

The nameField instance was given a border. The border of a text field can be manipulated and customized. Because you want users to input their name here, the type property was specified as input. The text field was then given a default value that describes the information being requested.

Finally, the code is taking advantage of the onSetFocus and onKillFocus events to keep the user interface consistent. Once the behavior of the application is finalized, the focus events can be used to verify the validity of the inputs.

Working with Text Display Proper ties

Many properties are available to modify the look and behavior of the text field. They allow rudimentary style changes to the text but are geared toward the default behavior of the field itself rather than to any rich text formatting. You can view the full list of properties by opening up the Flash Help panel and browsing to ActionScript 2.0 Language Reference ActionScript Classes TextField. The properties that you can use to modify the look of a text field include border, background, backgroundColor, and textColor. The primary means to manipulate the look of a text field is not through the properties at all, but through either the TextFormat class or the StyleSheet class. You see these both in action a little later in this chapter.

The TextField class has so many properties that it’d take many pages to define them all here. Flash 8 includes many new properties, most of which relate to clarity and granularity of control over previous versions of Flash. You explore a few of them here, but you can use the ActionScript panel’s code hinting to reveal the others, and then try them out to see what each does. Most are capable of setting and getting the value, but some are merely getters, such as the textHeight and textWidth properties that do not permit you to change the value.

antiAliasType

antiAliasType is an important new property because it facilitates many of the other new properties available. Setting it to advanced applies the new rendering method upon the text for ultra-clear text presentation. The property defaults to normal. Normal rendering uses the text display engine from Flash 7 and earlier, and it lacks the clarity of the text display engine added to Flash 8.

You can override all antiAliasType calls by declaring the property directly onto the class package, using the code flash.text.TextRenderer.antiAliasType = “on”;. This enables you to easily make the property change in all fields, rather than specifying the property in each field. Once you set this value, you cannot override it by setting the property on an individual text field.

436

Handling Text

To take advantage of the advanced rendering of text you must embed the font. The font must be embedded via the library with an export linkage specified. The embedFonts property must be set to true, and the font linkage name specified as a string in a TextFormat object. This sounds like a lot of dependencies, but in fact using these properties even without advanced text rendering is common practice. After you see the difference in quality, you’ll agree that the extra work is worth the effort.

When you apply properties to a text field that affect the look of the text, such as antiAliasType, sharpness, and thickness, all text in the text field is affected. You cannot selectively apply these properties to just a segment of the text displayed within a particular text field.

sharpness

The sharpness property is used in conjunction with advanced anti-aliasing. It expects a value from –400 to 400. The property specifies the smoothness of the transition between the edges of the text characters and the background they reside on. Changing this setting can affect the performance of animations as well as the speed of filters applied to the text field. Use a sharpness setting that makes sense for the activity of the text field.

A low sharpness setting causes your font to appear bloomed, or a slight hollow effect will appear. A high number produces very clear text at small sizes, but can cause jagged curves and sharpness artifacts. Use high values for sharpness only when you specify very small sizes with a TextFormat object. Changing the default sharpness at very large sizes is probably not necessary.

thickness

The thickness property determines the width of the transition area between the edges of the text characters and the background. Changing this property can make your text appear to bloom, or bold. The property can be used in conjunction with the sharpness property to fine-tune the text-aliasing behavior of the text field.

The best way to understand the effects of these properties is to try them out.

Try It Out

Precise Control over Text Display

In this example you see the clarity of text when using advanced anti-aliasing. A TextFormat object is created because it is required when embedding fonts in dynamic text fields. The TextFormat class is explained more fully later in this chapter.

1.Open a new FLA. Save it as antiAliasTest.fla in your workspace folder.

2.Open the Library panel. At the top right is an icon that looks like a bulleted list with a small arrow pointing down. Click it to open the Options menu.

3.Select the New Font option. A pop-up window appears.

4.Give the font a logical name and choose the font you’d like to use in your text field as advanced rendered font. Click OK.

5.The font appears in the library. Click the font symbol in the library so that it is highlighted. Open the library’s Options menu again and select the Linkage option. A pop-up window with options opens.

437