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

Beginning ActionScript 2.0 2006

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

Chapter 13

};

handle.onRelease = function() { clearInterval(_global.refreshScreen); this.stopDrag();

};

handle.onReleaseOutside = function() { clearInterval(_global.refreshScreen); this.stopDrag();

};

}

5.Create the control and anchor points by adding the following code below the code you entered in step 4:

anchorOne = createEmptyMovieClip(“anchorPoint1”, this.getNextHighestDepth()); anchorOne._x = anchorOne._y=50;

anchorOne.beginFill(0xCCCCCC, 100);

anchorOne.lineStyle(0, 0x000000, 100, false, false, “none”, “miter”, 2); createSquare(anchorOne, 8, -8);

setDraggable(anchorOne);

anchorTwo = createEmptyMovieClip(“anchorPoint2”, this.getNextHighestDepth()); anchorTwo._x = anchorTwo._y=250;

anchorTwo.beginFill(0xCCCCCC, 100);

anchorTwo.lineStyle(0, 0x000000, 100, false, false, “none”, “miter”, 2);

createSquare(anchorTwo, 8, -8); setDraggable(anchorTwo);

controlOne = createEmptyMovieClip(“control1”, this.getNextHighestDepth()); controlOne._x = anchorTwo._x;

controlOne._y = anchorOne._y; controlOne.beginFill(0xCCCCCC, 100);

controlOne.lineStyle(0, 0x000000, 100, false, false, “none”, “miter”, 2); createSquare(controlOne, 8, -8);

setDraggable(controlOne);

connect();

6.Test your movie in the debug player. You will see three squares on the screen. These are draggable. Move them around to see how the anchor points and control points interact to create Bezier curves.

How It Works

The most pertinent part of the code in this example is in step 2: the function that connects the two anchor points via a line using the curveTo method. The code also calls lineStyle, with just three parameters, generating a basic line. (A line gradient could have been used as well.)

The methods of the drawing API are enacted directly upon the stage of the movie clip on which they’re called. You nest the entire process in child clips for much more freedom when extending the code.

Also in the connect() function, the moveTo method is used to virtually lift the drawing tool to a new position so that it does not draw any lines from a previous position. You can remove this method with a lineTo method to see what happens when you don’t lift the drawing tool off the virtual canvas. Also pertaining to the virtual canvas is the clear() method. Try removing this method now. You see that the object retains lines drawn during previous loops. By clearing the canvas you can start with a fresh line.

328

Working with Vector Graphics

Calling clear also relieves the CPU of having to track many vector points that in some cases may no longer be visible. Even though cacheAsBitmap relieves you from this concern to a degree, you should still be aware of the vector points you have on the stage, and any memory you’re using. Vectors appear simple, but the points that define shapes can stack up quickly.

In the createSquare function, a code block is created to easily add squares of varying size and offset to any movie clip. In a larger application, it is likely wiser to make this function a static class method in a drawing library class. But in this example, it is clear how you can take advantage of the drawing API to perform repetitive drawing tasks without having to do them by hand and place them in the library. This method relies on the parameter handle having a fill method already assigned on it. The function fails otherwise. In a static class method, it would be practical to return some Boolean state to describe an error such as this.

Next you add a setDraggable function, which you are able to call with any of your movie clips to add interactivity to them. Notice some code block side railing occurring here, as it attempts to retain any interactivity the clip might have previously had defined upon it. The function is generic, and could be used on just about any clip. In a larger application it would probably be better to make this method an extension of the MovieClip class. However, in this context you can see a simplified way to use the drawing API to create real, usable UI elements that can interact with the user.

In the last bit of code, the simple application is tied together using the methods defined in previous steps as well as built-in create methods for adding movie clips to the stage. Each clip defines a lineStyle, as well as a fill method. In this way you can make each instance unique in some way. This also shows that the lineStyle and fill methods can be assigned per object, and more generic calls from lineTo, moveTo, and curveTo can be used to complete the shape desired.

The final line calls the connect method. Because it waits for interactivity before drawing, so as to preserve CPU power while interactivity is not taking place, connect needs to be called to create the initial curveTo line condition and connect your anchor points in their default positions.

So far you’ve learned how to place primitive shapes and simple lines on the stage and manipulate them through user interactivity. At the heart of interactive graphics is knowing when to call the clear method and how to compartmentalize repeated tasks such as drawing squares. In the next Try It Out you use the drawing API in a real-world example, using a data set and going from raw data points to final graphic.

Try It Out

Build a Graph

In this example you create dynamic information graphics based on a data table. lineTo, moveTo, and beginFill are used to frame the graph as well as to create the actual graph.

1.Open a new Flash document. Save it as graph.fla in your work folder. In the FLA properties panel, select Modify Document, and change the width of the stage to 1024. Ensure that the height is 400. (I advise making the background #fffff6, but that’s optional.) Click OK to commit the stage changes.

2.Click the first frame in the timeline, open the Actions panel, and enter the following ActionScript function:

dataTable = [];

dataTable.push([“1851-1860”, 8, 5, 5, 1, 0, 19]); dataTable.push([“1861-1870”, 8, 6, 1, 0, 0, 15]);

329

Chapter 13

dataTable.push([“1871-1880”, 7, 6, 7, 0, 0, 20]); dataTable.push([“1881-1890”, 8, 9, 4, 1, 0, 22]); dataTable.push([“1891-1900”, 8, 5, 5, 3, 0, 21]); dataTable.push([“1901-1910”, 10, 4, 4, 0, 0, 18]); dataTable.push([“1911-1920”, 10, 4, 4, 3, 0, 21]); dataTable.push([“1921-1930”, 5, 3, 3, 2, 0, 13]); dataTable.push([“1931-1940”, 4, 7, 6, 1, 1, 19]); dataTable.push([“1941-1950”, 8, 6, 9, 1, 0, 24]); dataTable.push([“1951-1960”, 8, 1, 5, 3, 0, 17]); dataTable.push([“1961-1970”, 3, 5, 4, 1, 1, 14]); dataTable.push([“1971-1980”, 6, 2, 4, 0, 0, 12]); dataTable.push([“1981-1990”, 9, 1, 4, 1, 0, 15]); dataTable.push([“1991-2000”, 3, 6, 4, 0, 1, 14]); dataTable.push([“2001-2005”, 7, 2, 3, 3, 1, 9]); get2dArrayValues = function (handle, n) {

temp = [];

for (var i = 0; i<handle.length; i++) { temp.push(handle[i][n]);

}

return temp;

};

This code creates a two-dimensional array that holds your data, as well as a method for retrieving that data easily.

3.Now define a function to draw a shape. The function is similar, but a little more complex than the createSquare function defined in the preceding Try It Out:

drawGraph = function (handle, values, max, grpWidth, grpHeight, style, ; xoffset, yoffset) {

var xincrement = grpWidth/values.length; var yincrement = grpHeight/max;

handle = handle.createEmptyMovieClip(“graphline”+getTimer(), ; handle.getNextHighestDepth());

handle._x = xoffset; handle._y = yoffset;

handle.lineStyle(0, 0xFFFFFF, 4); handle.moveTo(0, grpHeight); handle.beginFill(style[0], Style[1]);

handle.lineTo(0, grpHeight-(values[0]*yincrement)); for (var i = 1; i<values.length; i++) {

handle.lineTo((i*xincrement), grpHeight-(values[i]*yincrement));

}

handle.lineTo((values.length-1)*xincrement, grpHeight); handle.lineTo(0, grpHeight);

handle.endFill();

};

4.To draw the graph data, type the following code below the code you entered in step 2:

myGraph = this.createEmptyMovieClip(“graphHolder”,0); var F1:Array = get2dArrayValues(dataTable, 1); drawGraph(myGraph, F1, 12, 800, 200, [0x3C4B6C, 5], 22); var F2:Array = get2dArrayValues(dataTable, 2); drawGraph(myGraph, F2, 12, 800, 200, [0x3C4B6C, 25], 22);

330

Working with Vector Graphics

var F3:Array = get2dArrayValues(dataTable, 3); drawGraph(myGraph, F3, 12, 800, 200, [0x3C4B6C, 45], 22); var F4:Array = get2dArrayValues(dataTable, 4);

drawGraph(myGraph, F4, 12, 800, 200, [0x3C4B6C, 65], 22); var F5:Array = get2dArrayValues(dataTable, 5); drawGraph(myGraph, F5, 12, 800, 200, [0x000000, 85], 22);

5.Test your movie to see the graph created with the data. Close the .swf and return to the first frame ActionScript.

You can go back into the dataTable array added in step 2 and change the values to see them reflected in the drawing. If you already know how to import XML, try changing the data table to external data sources. Try modifying the graph to suit your visual style.

How It Works

This example showed how to use simple functions together to create sophisticated information graphics entirely within ActionScript.

In step 2 you created the data model, as well as a method for extracting values from that model easily in a reusable code block. You can change the values in the dataTable array or remove some of the data to see what happens and how the code copes with different amounts of data points. Because the function you create later doesn’t rely on a specific number of data points or a specific set of values, you can change your graph quickly and easily. Clearly, the drawing API can be used to save time and keep file size down — note that the SWF file size is less than 3 kilobytes. If you re-create this same graph as a

.jpeg or .gif image, it would cost you some 25–40 kilobytes for a similar-quality image.

moveTo, lineTo, beginFill, lineStyle, and endFill are used in the drawGraph function. Change the values specified in this function. You see how you can customize the look and feel of the shapes it creates. Don’t worry if it looks a little goofy at first. Keep working until you understand how to get a line you want. The drawGraph function creates the actual data points on the graph. This method is called repeatedly in step 4 to generate graphs for each set in the dataTable array. Each new value set overlays the data sets drawn earlier. The beginFill method provides the color and transparency for the data set. You can change the behavior and look of the graph data by changing the drawing API method calls in this function.

You also could begin to define interactivity by adding text information to the stage and creating a function to swap the depths of the data sets when key values are clicked. I encourage you to attempt this and explore the issues that exist if you were to make the graph interactive for the user.

The drawGraph function requires six parameters and has two optional ones, all of which are described in the following table:

Parameter

Description

 

 

handle

A reference to the movie clip in which to draw the graph.

values

An array of values that determine the height of the graph values

 

being drawn.

 

Table continued on following page

331

Chapter 13

Parameter

Description

 

 

max

The maximum value the graph is capable of displaying. This is

 

essentially the scale of your graph. A max value that is much

 

larger than the actual values in the graph results in a flat-looking

 

graph.

grpWidth

The maximum width of the graph in pixels.

grpHeight

The maximum height of the graph in pixels.

style

An array of a color in hexadecimal format, and an alpha value.

xoffset

Together with yoffset, moves the container clip for each graph

 

drawn. Not required. In step 4, you used an xoffset of 22 pixels to

 

align data points over the center of the labels rather than the

 

beginning of the label.

yoffset

Together with xoffset, moves the container clip for each graph

 

drawn. Not required.

Take a little deeper look at the drawGraph function. The first two lines determine how far apart each data point should be by establishing the length of virtual grid segments. This is established by dividing the grpWidth and grpHeight values by the number of values expected:

var xincrement = grpWidth/values.length; var yincrement = grpHeight/max;

The next lines create a placeholder for the graph and move it according to the xoffset and yoffset values. The handle variable name is recycled to point to the child movie clip created with the createEmptyMovieClip method:

handle = handle.createEmptyMovieClip(“graphline”+getTimer(),; handle.getNextHighestDepth());

handle._x = xoffset; handle._y = yoffset;

In these three lines of code you begin to use the drawing API methods. The first method is moveTo. The x value is set to 0. The y value is a bit different. An important consideration when using the drawing methods is that a movie clip index begins at 0,0, and positive x and y values move to the right and down on the stage coordinate system. Because positive values indicate lower onscreen positions, it can be counterintuitive. Creating graphs often requires negative values for y coordinates. So in this case the start index of the graph is the height of the graph because the very top left of your entire interface is index 0,0. That’s likely confusing, but with a bit of experience you’ll see why this is an important consideration.

The following line defines the beginFill style. You use the Style parameter of the drawGraph function to declare the values:

handle.beginFill(Style[0], Style[1]);

The next line draws the first vector line. In case its value changes, this lineTo is kept separate from the following lineTo values. The x value is 0 because this is the first graph value being drawn.

332

Working with Vector Graphics

The y parameter is a bit more complex:

handle.lineTo(0, grpHeight-(values[0]*yincrement));

The start position is indicated as grpHeight. The y value to be drawn is multiplied by the yincrement value obtained earlier. The values[0] array index is the first graph value. Because the height of the graph is divided into segments, multiplying the actual variable from the data set by the segment length provides the y value to plot to. Subtract the plot value from the height of the graph because positive values would cause the graph to be drawn upside down due the coordinate system.

Now that the initial start position of the drawing is defined, you can loop the rest of the values. The next line in the function defines a for loop, which does the same work as the lineTo method discussed earlier, but it runs through the entire data set provided in the values array, modifying the conditional value used to find the plot point:

for (var i = 1; i<values.length; i++) { handle.lineTo((i*xincrement), grpHeight-(values[i]*yincrement));

}

To plot the x value in this lineTo method, the i value of the for loop is multiplied by the xincrement obtained earlier. The i value is also used as an array index to obtain the value in the values array, which is multiplied by the yincrement to find the actual plot value of data.

Then you finalize the end of the graph with a vertical line. Because the last lineTo method call in the for loop set the index position at the last possible x position, you use that value again (you don’t want to move to the right or left; you just want to move straight down). In the preceding for loop, the conditional statement is i<values.length because numeric arrays start at 0 instead of 1. So to get the actual number of plotted values, the length is shifted by subtracting one from the values array length property. To close off the end of the graph as a side, then, the y value is specified as the index grpHeight, which is the start y position of the graph:

handle.lineTo((values.length-1)*xincrement, grpHeight);

The last two lines of the drawGraph function code close the final graph shape. You don’t need to call a final closing lineTo method in all cases because endFill closes a shape with the first known plot value. However, it is a good idea to stipulate a closer line so that you have full control over your shape and quirky shapes won’t act in a way you don’t expect. Declaring a closing lineTo also allows easy modification of a closer line if changes ever need to be made to the behavior of the shape. The function closes the shape with the endFill method call:

handle.lineTo(0, grpHeight); handle.endFill();

So that’s the drawGraph function. In just a few lines of code you can create dynamic, complex shapes while reusing code and keeping your drawing easily modifiable.

333

Chapter 13

The Matrix Object

You explore filters in the next chapter, but before you go there, the Matrix object requires explanation. A Matrix object can easily describe a change made to a set of values that affect a MovieClip or Bitmap object.

Its basic methods — createGradientBox, invert, rotate, and scale — automate some of its behaviors. These methods are explained when the objects that use them are discussed later in this book.

A matrix can describe how an object should be transformed. It is a grid of values that allows functions to communicate a set of data variables in an efficient manner. Many types of matrix objects exist. The flash.gom.matrix object, for example, controls how an object is physically modified on the stage. Color matrices and convolution matrices exist as well. Chapter 14 covers matrices so that you can begin to use

them efficiently in your code. I encourage you to return to this chapter and review the beginBitmapFill and beginGradientFill methods with their matrix object parameters to complete more complex shape manipulation when using the drawing API.

Summar y

In this chapter you explored the many ways in which you can modify movieClip and Bitmap objects using basic available method sets and known formulas for manipulating images.

The convolutionMatrix proved particularly powerful, as did the BitmapData object.

Many of the methods and objects in this chapter have the capability to be manipulated directly on a more advanced level. If a particular object suits your intent, look into the object further to see how you might customize or create a class to control it.

All of the filters, blend modes, and methods can be automated and reused efficiently in class objects. Seek out existing libraries and formulas to help automate the many tasks these filters and the methods in this chapter can perform alone and in combination with one another.

The pinhole camera effect provided a Try It Out that showed how using many of these objects and methods together in a specific order can produce a result that you expect from expensive image editing programs, not from a real-time animation rendering function set. Have fun with these methods. Don’t get bogged down with the mathematics involved and try out as many things as you can think of!

Exercises

1.Create a simple circle using some circle math.

2.Write a function that uses mouse interaction to draw lines.

3.Create a shape in a movie clip. Use that movie clip to mask a bitmap image in another movie clip.

334

14

Applying Filter Effects

Filters in Flash are similar to the layer styles found in popular image editing programs. Filters allow for glow, shadow, bevel effects, and more! These effects are new in Flash 8. Previous versions of Flash allowed rudimentary effects using vector graphics libraries, which were both difficult to manage and processor intensive. With Flash 8 filters, you have the advantage of built-in pixel-level manipulation of objects as bitmaps, which means fast and easy filter manipulation of any movieClip or Bitmap object.

The filters are applied easily by declaring the filters property of a movie clip. When the movie clip changes, the filters property is checked and the filter is applied. You can apply multiple filters to the same object. You also can apply multiple versions of the same filter to the same object. This gives you unparalleled control of filter effects at runtime using ActionScript.

Filters are exceptionally easy in Flash. You can stipulate all the properties within each new filter constructor or set them individually. This enables you to reuse an existing filter rather than instantiating a new filter object. Each time you modify a filter, you must reapply it to your target movie clip using the filters property of the movie clip.

Although you can set the properties of a filter via the new constructor, it is far more readable, and easier to scan, when a property declaration list is used. This is especially helpful for group development, particularly when working with developers who might not be familiar with all of the parameters available in the new constructor.

When describing methods, the properties are listed individually rather than as parameters. If you want to use constructor parameters to construct your filter values, you can use code hints in the ActionScript panel to show you the expected order of the parameters.

This chapter examines the major filters and their properties.

Chapter 14

DropShadowF ilter

DropShadowFilter does exactly what the name implies. You’re likely familiar with drop shadows in popular image editing software. An interesting and useful detail is that a drop shadow is rendered only as a shadow of visible pixels within a movie clip or bitmap. This includes transparent PNG and GIF. A shadow will only be rendered for the visible pixels in images.

The properties of the DropShadowFilter are described in the following list. These properties can be set within the constructor of the filter or defined as properties after the construction:

alpha — Specifies the opacity of the shadow. Surprisingly, this numeric property is not a value of 0–100. Instead it is 0.0 to 1.0, so to set the alpha property of the baseline pixel of the shadow to 25, you would set it to .25.

angle — The angle, again surprisingly, is a numeric value from 0 to 360. This is unexpected because most other angle and rotation properties in Flash use radians, an alternative method for working with circular points. It is important to consider when using the Math object that some radian-to-degree conversions are required to make the angle work. As well, Flash’s stage defines 0 degrees along the x axis. That is, a value of 0 puts a shadow to the right of your movie clip. So this is a bit quirky, but after you use it a few times, you’ll get used to it.

blurX and blurY — These are numeric values (0 to 255) that describe the amount to which the shadow should be blurred. You don’t need a high value to obtain desirable results. In fact, high values can produce visible stepping. The value loosely matches the amount of pixels to which the shadow will expand, depending upon the strength property applied, and whether the inner property is true or false.

color — A hexadecimal value. If you do not specify this property, it defaults to 0x000000.

distance — A numeric pixel value. Any numeric value is acceptable, including negative values. This property determines how far away from the movie clip the shadow should be rendered. This is a two-dimensional value. Setting a larger distance only moves the shadow on the x and y plane; it does not change the size of the shadow in relation to distance.

hideObject — A Boolean. When set to true, the movie clip is hidden, but the shadow is still rendered. Unlike the _visible property of the movie clip, hideObject allows the movie clip to retain mouse interactivity. The vector points of the movie clip are still processed by the rendering engine, so this method has little to no effect on overall performance. The default is false.

inner — A Boolean that specifies where the shadow is rendered. Set to true, it causes the shadow to be overlaid onto the object and fade inward. The default value is false, which renders the shadow in the more traditional manner beneath the movie clip.

knockout — Replaces the fill areas in your movie clip with the colors that reside beneath the clip. It essentially makes your movie clip transparent while preserving the opacity of the fills. This is confusing and is best understood by simply trying it out and seeing the result. knockout enables many superb effects on existing stage content.

quality — A numeric value of 0 to 15. Use it to customize how smoothly a movie clip’s shadow is rendered. The quality setting is essentially a multi-pass setting that extrapolates more detailed pixel data for the shadow with each pass. The higher the value, the prettier your

shadow, but the more CPU intensive the shadow rendering becomes. Usually a value of 3–5 produces sufficient smoothness. (Also, the higher the value, the more passes blur previous passes, so a higher-quality shadow appears more bloomed and ambient than a lower-quality

336 shadow.)

Applying Filter Effects

strength — A numeric value from 0 to 255. The higher the value, the more the color of the filter is opaque on the surrounding content. This value also directly affects the blur values because the higher the strength value, the higher the contrast between the shadow and the surrounding content. As the strength increases, fewer steps are used to render the blur. With both large blur and large strength values, undesired results such as visible stepping can occur.

BlurF ilter

BlurFilter blurs a bitmap or movie clip in a similar manner to the blur filters found in popular image editing programs. Using a Bitmap object as the target for a blur means you can blur specific parts of an image. Varying values within the properties enables you to blur in a specific direction to imply motion or directional blur.

The properties of the BlurFilter and a description of each property follows. These properties can be set within the constructor of the filter or defined as properties after the construction:

blurX and blurY — These two properties determine the amount of blur to apply to the target object. The properties expect a Number value from 0 to 255. The default value is 4. After a value of 255 is surpassed, the object is no longer visible.

quality — A numeric value of 0 to 15. This property essentially tells the filter how many times it should be run on the object. A low value produces more rudimentary blurring; higher values produce blurred pixels and thus a more Gaussian effect.

GlowF ilter

GlowFilter creates a uniform ambient color around the movie clip. It is similar to DropShadowFilter, but without an angle setting. The strength of the glow is affected by the alpha values present as well as the relative size of the areas within the object. A thin line, for example, will have less of a glow than a large opaque circle in the same clip.

The properties of the GlowFilter and a description of each follows. These properties can be set within the constructor of the filter or defined as properties after the construction:

alpha — A Number between 0.0 and 1.0.

blurx and blurY — These properties determine the amount the glow is blurred. The Number values (0 to 255) are directly affected by the quality and strength properties.

color — A hexadecimal number in the format 0xRRGGBB.

inner — A Boolean. If the inner property is set to true, the glow is overlaid onto the object and the glow fades inward from the outer edges of the shape. The default is false, and the glow appears beneath the object and fades outward from the edges of the shape.

knockout — A Boolean that specifies whether the shape that has the glow filter applied should be made invisible. However, alpha values of the original object are retained, and the fill areas adopt the pixels visible beneath it on the stage. You can use this property to create interesting effects and transitions.

337