Knowing that hexadecimal values of gray are created with equal values of each color 0x666666, for example, it’s common to see a value of 0.33 used for each R, G, and B component of every
Trang 1Color Effects
21 var invert: ColorTransform = new ColorTransform ();
22 invert redOffset = 255;
23 invert greenOffset = 255;
24 invert blueOffset = 255;
25 invert redMultiplier = -1;
26 invert greenMultiplier = -1;
27 invert blueMultiplier = -1;
28 mc2 transform.colorTransform = invert;
The ColorMatrixFilter Class
The next color effect uses the ColorMatrixFilter class This class uses a 4 × 5
matrix to transform red, green, blue, and alpha values of the image, and can
be used to create advanced hue, saturation, and contrast changes, among other
effects The following example demonstrates using luminance constants to
desaturate an image to create a color grayscale
The identity matrix (the default matrix, as discussed in Chapter 8) for the
ColorMatrixFilter class is as follows:
Rs, Gs, Bs, As, Os
Rnew = 1, 0, 0, 0, 0,
Gnew = 0, 1, 0, 0, 0,
Bnew = 0, 0, 1, 0, 0,
Anew = 0, 0, 0, 1, 0
The rows represent the sum of changes in red, green, blue, and alpha values
for each pixel The first four columns are the multipliers for red, green, blue,
and alpha values of the source (s), and the fifth column is the offset value for
each row The identity matrix shows a default multiplier of 1 and offset of 0
for each color channel, and no change to the other source color multiplier or
offset values for that channel—that is, Rnew equals Rs, Gnew equals Gs, and
so on
By introducing changes to the other color values, the appearance of each pixel
will change A good way to make this clear is to demonstrate the creation of a
color grayscale image When creating the new red value for a pixel, instead of
using a multiplier of 1 for red and 0 for green and blue, you can use a partial
value of 1 for all colors (with no change in alpha or offset) There will be no
change in brightness because the sum of each row will still be 1 The alpha
row receives no change to R, G, or B values, and the standard alpha multiplier
of 1 is used with no offset
The only question is, what partial values should be used for each color?
Knowing that hexadecimal values of gray are created with equal values of
each color (0x666666, for example), it’s common to see a value of 0.33 used for
each R, G, and B component of every pixel However, it turns out that unequal
values of red, green, and blue combine to create better grayscale images We
can take advantage of prior research to achieve color grayscales that are more
pleasing to the eye, using what are known as luminance constants—constant
red, green, and blue brightness values used for color calibration
N OT E
Luminance is the amount of light that
is reflected or emitted by a color In lay terms, luminance is brightness (which
is more of a human perception than a measured quantity) NTSC broadcast luminance constants (TV grayscale) published in 1954 were replaced by val-ues better tuned to CRT monitors and computer displays.
For many years, Paul Haeberli’s lumi-nance vectors of 0.3086 for red, 0.6094 for green, and 0.0820 for blue, published
in 1993, were used for color grayscale Recently, these values have been
adjust-ed for HDTV standards and are now slightly different Red has reduced
slight-ly, and green and blue have increased slightly, over previous values The cur-rent standard is 0.2126 for red, 0.7152 for green, and 0.0722 for blue Experiment
to see which combination you prefer.
Trang 2Image Encoding and Saving
By applying these constants to the source R, G, and B values, the new red, green, and blue values for each pixel will be optimized for grayscale display (Figure 9-16) The newly created matrix is passed to the filter constructor (line 8), and the result is applied to the filters array of the display object (line 12) The following code is found in the color_matrix_filter.fla source file
3 var lumRd: Number = 2126;
4 var lumGr: Number = 7152;
5 var lumBl: Number = 0722;
6
7 var grayscale: ColorMatrixFilter =
8 new ColorMatrixFilter ([lumRd, lumGr, lumBl, 0, 0,
9 lumRd, lumGr, lumBl, 0, 0,
10 lumRd, lumGr, lumBl, 0, 0,
11 0, 0, 0, 1, 0]);
12 mc1 filters = [grayscale];
The Color Class
The last color manipulation is the simplest It uses the Color class, from the
fl.motion package to set the tint of a display object The tint is set the same way line and fill styles are set using the Graphics class Two parameters, color and alpha, are used to define the tint Once the tint is created, it’s applied to the colorTransform property of the display object’s transform object, as in previous examples
The following code is found in the set_tint.fla source file:
1 import fl.motion.Color ;
2
3 var blueTint: Color = new Color ();
4 blueTint setTint (0x0000FF, 1);
5 mc transform.colorTransform = blueTint;
Image Encoding and Saving
Now that you know how to create bitmap data, let’s talk about how to save it! We’ll discuss encoding a BitmapData object and saving the image as a JPG
At the end of the chapter, you’ll see how to add encoding and saving to our ongoing painting application, as well as save to PNG format, complete with transparency
The encoding process involves sending the bitmap data to an image encod-ing class Fortunately, Adobe provides both JPG and PNG encoders as part
of Adobe’s AS3 Core Library At the time of this writing, information can be found at https://github.com/mikechambers/as3corelib, where you can down-load the library
Original
Grayscale
Figure 9-16. Grayscale created by the
ColorMatrixFilter
N OT E
Discussed in Chapter 8, the Color class
was written to support converting
time-line animations into ActionScript and
is only available to Flash Professional
users However, we have reproduced a
subset of these features, to support the
material covered in this book, in the
com.learningactionscript3.color.
ColorUtils class This will allow
users of other ActionScript editors to
use the scripts in this book with minor
modification The class is included in the
source material for this chapter, and its
use in sample source code for Chapter 8
includes notes on its use.
Trang 3Image Encoding and Saving
The saving portion of the exercise is accomplished using the FileReference
class This class allows you to upload and download files Some features,
including the save() method for saving to your hard drive, require Flash
Player 10
Saving JPG Images
The heavy lifting of this exercise is performed during the encoding process
by Adobe’s image encoder classes The inner workings of these classes are a
bit outside the scope of this book, but they’re very easy to use The following
script is found in the encode_and_save_jpg.fla source file, and it demonstrates
the handy feature of taking a screen capture of everything on the stage We’ll
review Chapter 8 by drawing a button dynamically and adding it to the
stage Clicking that button will copy anything on the stage into a BitmapData
instance, and then provide a prompt to save that image as a JPG Later on,
we’ll use a button to save the contents of a preexisting BitmapData instance—
namely, the output of the paint program we developed earlier in this chapter
This exercise starts routinely with line 1 importing the JPGEncoder class, and
lines 3 through 11 drawing a button and adding it to the display list Notice
that lines 8 and 9 center the button by determining the horizontal and
verti-cal center of the stage, and line 10 sets the buttonMode property of the sprite
to true to enable hand cursor feedback when rolling over the sprite
1 import com.adobe.images.JPGEncoder;
2
3 var saveBtn: Sprite = new Sprite ();
4 var g: Graphics = saveBtn graphics ;
5 g beginFill (0x990000, 1);
6 g drawCircle (0, 0, 40);
7 g endFill ();
8 saveBtn x = stage.stageWidth /2;
9 saveBtn y = stage.stageHeight /2;
10 saveBtn buttonMode = true ;
11 addChild (saveBtn);
Lines 12 and 13 add a mouse click event listener to the button, which calls
the function in lines 14 through 24 when the button is clicked Lines 15 and
16 create a BitmapData object the size of the stage, and line 17 draws into the
object everything on the stage, effectively taking a screen shot of the stage
Line 19 creates an instance of the JPGEncoder class, and passes an image
qual-ity setting of 100 into the constructor when doing so If no value is passed
into the class during instantiation, a 50-percent quality setting is used Line
20 encodes the bitmap data into bytes that can be understood as a JPG It also
stores the bytes in a special array called a ByteArray A ByteArray is a heavily
optimized array with its own properties and methods for reading and writing
data at the byte level
N OT E
An ActionScript 3.0 package called ZaaIL, developed by Aaron Boushley and Nate Beck of ZaaLabs, adds support for
40 additional image formats! See http:// www.zaalabs.com/2010/04/introducing-zaail-40-image-format-support-for-flash/
for more information.
N OT E
When using a Flash Player 10–specific feature, be sure your file is set to publish
to Flash Player 10 in the File→Publish Settings→Flash→Player menu (Flash Professional CS5 users can get to this setting immediately by clicking the Profile→Edit button in the Publish sec-tion of the Properties panel.)
N OT E
The companion website includes infor-mation about using a server and PHP
to accomplish the same goal in Flash Player 9 See the post “Saving Data in Flash Player 9 Using PHP” for more information.
N OT E
See Chapter 8 if you need to review drawing vectors with the Graphics
class.
Trang 4Adding Functionality to Your Color Picker
Finally, line 22 creates an instance of the FileReference class, and line 23 invokes the save() method from this instance In doing so, it passes in the bytes for the JPG and a default file name The user’s operating system prompts for a location to save the file and the JPG is written to your local directory of choice
12 saveBtn addEventListener ( MouseEvent.CLICK , onSaveImage,
13 false , 0, true );
14 function onSaveImage(evt: Event ): void {
15 var stageCapture: BitmapData =
16 new BitmapData ( stage.stageWidth , stage.stageHeight );
17 stageCapture draw (stage);
18
19 var jpgEncoder:JPGEncoder = new JPGEncoder(100);
20 var jpgBytes: ByteArray = jpgEncoder encode (stageCapture);
21
22 var fileRef: FileReference = new FileReference ();
23 fileRef save (jpgBytes, "stageCapture.jpg" );
24 }
Adding Functionality to Your Color Picker
Now it’s time to exercise the gray cells and put what you’ve learned into prac-tice The first example makes the color picker art you created in Chapter 8 functional In the process, you’ll learn how to get and set pixel color values in a
BitmapData instance Then we’ll end with an exercise that uses many of the skills you’ve developed over the past few chapters We’ll expand the drawing applica-tion you created by adding the color picker to change the color of your brush We’ll also use the RoundRectButton class from Chapter 8 to create a button that triggers a save method, saving your artwork to your hard drive in PNG format
Getting and Setting Pixels
In Chapter 8, we created the visual component of a color picker (shown in Figure 9-17), but didn’t add any functionality to the exercise In this chapter, we’ll expand this class-based example and create a ColorPickerCustom class (named as such to differentiate it from the ColorPicker component in Flash Professional) This class will add an instance of the ColorPickerGraphics
class you created in Chapter 8 to serve as the color graphic in the picker We’ll also add a simple text display and a “current color” chip to the picker, and then show you how to get and set pixels using methods of the BitmapData
class The class is found in the book code library, at com/learningactionscript3/
color/ColorPickerCustom.as, and we’ll put it to use in the next section.
Lines 1 through 10 define the package and import all the classes required by this class Lines 12 through 18 declare the class (which extends MovieClip so you can easily treat the picker as a display object) and declare a small number
of variables Lines 14 and 15 contain the picker (_pickerArt) and a BitmapData
instance (_bmd) that will contain the pixel data from the picker This will allow
us to get the color value of a pixel during the actual color picking process
N OT E
Prior to Flash Player 10.1, saving a file
using the FileReference class required
active involvement, such as a mouse
click, from the user You can’t invoke the
save() method from a timer or enter
frame event, for example, because that
is considered a passive experience from
the viewpoint of the user This has been
relaxed in Flash Professional CS5.
Pu sh
You rself!
Figure 9-17. The color picker created in
Chapter 8
N OT E
ColorPickerGraphics, the display
por-tion of the color picker exercise created
in Chapter 8, is in the same directory
as this class, so your new code will
function without importing that class
However, doing so allows you to see all
class dependencies at a glance.
Trang 5Adding Functionality to Your Color Picker
The _col variable in line 16 will hold the picked color, and the _tf variable
in line 17 will contain a text field that we’ll use to display the color value in
string hexadecimal notation (#FFFFFF rather than 0xFFFFFF) The final
variable, _chip, in line 18, will contain a movie clip that we’ll tint to match
the selected color The text and color chip will provide valuable feedback for
the user when picking colors
1 package com.learningactionscript3.color {
2
3 import flash.display.BitmapData ;
4 import flash.display.Graphics ;
5 import flash.display.MovieClip ;
6 import flash.events.MouseEvent ;
7 import flash.text.TextField ;
8 import flash.text.TextFieldAutoSize ;
9 import fl.motion.Color ;
10 import com.learningactionscript3.color.ColorPickerGraphics;
11
12 public class ColorPickerCustom extends MovieClip {
13
14 private var _pickerArt:ColorPickerGraphics;
15 private var _bmd: BitmapData ;
16 private var _col: uint = 0x000000;
17 private var _tf: TextField ;
18 private var _chip: MovieClip ;
Lines 20 through 50 make up the class constructor Lines 21 and 22 create
an instance of the ColorPickerGraphics class to create the spectrum artwork,
and add it as a child of the new class instance Lines 23 and 24 add a mouse
click event listener to the picker art inside the class The private method
onClick() (lines 52 through 59) will be used for visual feedback inside the
picker (setting the text and “current color” chip values) and to populate a
class property with the selected color What we do with that color will be
determined outside the ColorPickerCustom class when the picker is put into
use by a project We’ll look at that process later in this section
Lines 26 through 28 create a BitmapData instance the size of the picker art
and draw the picker art into the bitmap data Once we have the color
spec-trum in pixel data, we can retrieve the color values of a pixel clicked on by
the mouse
Lines 30 through 37 create a text field to display the chosen color’s
hexadeci-mal value It’s the width of the picker art, 14 pixels tall, and positioned just
under the picker art Note its initial content of “#FFFFFF” (white) is in line
34 In a moment, we’ll also apply an initial white color to the selected color
chip In line 35, the field’s background (with a default color of white) is turned
on so the picker won’t let the stage color show beneath the field Also, line 36
disables mouse interaction so that the cursor won’t change into a text cursor
upon rolling over the field and the text won’t be selectable
Lines 39 through 45 draw a small movie clip using the Graphics class
dis-cussed in Chapter 8, to serve as the selected color chip It’s white (set in line
41), 100 × 14 pixels (line 42) and is positioned just under the text field (line
N OT E
In this example, no bitmap is created from the bitmap data or added to the display list Because the spectrum art has already been stored in the _pic-kerArt property and added to the dis-play list, we need only the BitmapData
instance for accessing color data It need not be a part of the display list.
Trang 6Adding Functionality to Your Color Picker
44) Also, using the Graphics class, lines 47 through 50 draw a 1-pixel black border for the entire picker, as a finishing touch to the picker’s appearance
19 //class constructor
20 public function ColorPickerCustom() {
21 _pickerArt = new ColorPickerGraphics();
22 addChild (_pickerArt);
23 _pickerArt addEventListener ( MouseEvent.CLICK ,
24 onClick, false , 0, true );
25
26 _bmd = new BitmapData (_pickerArt width ,
27 _pickerArt height );
28 _bmd draw (_pickerArt);
29
30 _tf = new TextField ();
31 _tf width = 100;
32 _tf height = 14;
33 _tf y = 100;
34 _tf text = "#000000" ;
35 _tf background = true ;
36 _tf mouseEnabled = false ;
37 addChild (_tf);
38
39 _chip = new MovieClip ();
40 var g: Graphics = _chip graphics ;
41 g beginFill (0x000000);
42 g drawRect (0, 0, 100, 14);
43 g endFill ();
44 _chip y = 114;
45 addChild (_chip);
46
47 var border: MovieClip = new MovieClip ();
48 border graphics.lineStyle (1, 0x000000);
49 border graphics.drawRect (0, 0, 100, 128);
50 addChild (border);
51 }
getPixel()
Three things happen within the class when the picker is clicked First, the
getPixel() method is used in lines 54 and 55 to retrieve the color value from the pixel at the mouse location This color is stored in the private property
_col Second, line 56 places the hexadecimal value of the color into the text field, using the prependZeros() method in lines 67 through 75 We’ll cover that method in a moment Finally, the setTint() method (line 59) is used to apply the selected color to the color chip, as discussed previously in the sec-tion “The Color Class.”
52 //listener function
53 private function onClick(evt: MouseEvent ): void {
54 _col = _bmd getPixel (_pickerArt mouseX ,
55 _pickerArt mouseY );
56 _tf text = prependZeros(_col);
57
58 var col: Color = new Color ();
59 col setTint (_col, 1);
60 _chip transform colorTransform = col;
61 }
Trang 7Adding Functionality to Your Color Picker
At this point, the color picker is completely functional, but only as a
self-contained widget We can’t yet use the picker for its intended purpose,
because the _col property is private, so we can’t retrieve the selected color
from outside the class Therefore, the last functionality we need to put in
place is a getter, color, in lines 63 through 65, to provide access to the _col
property
63 public function get color(): uint {
64 return _col;
65 }
Finishing the explanation of this class, the aforementioned prependZeros()
method takes a numeric color value and converts it to a string for display in
the picker’s text field However, when converting to a string, leading zeros are
dropped As such, if blue was selected, a string converted from its
hexadeci-mal value would read FF instead of the far more typical 0000FF equivalent
So we need to add the number of leading zeros required to fill out the color
value
The method starts with an empty string, zeros, in line 68, and then converts
the numeric value to a string in line 69 using the toString() method If we
used this method without an argument, it would convert the number to
decimal, or base 10 White, therefore, would appear as 16777215, which isn’t
very useful for most people By passing 16 into the method, it will convert
the value to hexadecimal, or base 16 Using this argument, the result for
white would be ffffff—acceptable, but not ideal By using the toUpperCase()
method, the string will be converted to uppercase and display as FFFFFF All
that remains is adding any necessary leading zeros and the preceding hash
mark (#)
Because the hexadecimal color string we want has six characters, line 70
determines how many zeros are needed by subtracting the current length of
the string from 6 Using blue (0000FF) as an example again, 6 minus 2 (for
the two characters in FF) is 4, so we need 4 zeros Lines 71 through 73 loop
the determined number of times and build the zeros string Finally, the return
string is assembled by concatenating the hash mark, leading zeros, and color
string
66 //text formatting for hex string display in picker
67 private function prependZeros(hex: uint ): String {
68 var zeros: String = "" ;
69 var hexString = hex toString (16) toUpperCase ();
70 var cnt: int = 6 - hexString length ;
71 for ( var i: int = 0; i < cnt; i++) {
72 zeros += "0" ;
73 }
74 return "#" + zeros + hexString;
75 }
76 }
77 }
Trang 8Adding Functionality to Your Color Picker
Using the picker with setPixel()
Now that you know how to get the color values from a pixel, let’s do the reverse To set the color values of a pixel in a BitmapData object, you need to again provide an x and y coordinate, but you also need to furnish the color you want the pixel to display In the color_picker_set_pixel.fla source file, we’ll use the picker we just created to set the color of pixels in a small bitmap Lines 1 through 5 import the ColorPickerCustom class, instantiate the picker, place it at point (10, 10), and add it to the display list Lines 7 through 12 cre-ate a 100 × 100–pixel black BitmapData object, create a bitmap from that data, position it just to the right of the picker, and add it to the display list The enter frame event listener in lines 14 through 19 manipulates the bitmap data, which we’ll explain after the code
1 import com.learningactionscript3.color.ColorPickerCustom;
2
3 var colorPicker:ColorPickerCustom = new ColorPickerCustom();
4 colorPicker x = colorPicker y = 10;
5 addChild (colorPicker);
6
7 var canvasBmd: BitmapData = new BitmapData (100, 100,
8 false , 0xFF000000);
9 var canvasBm: Bitmap = new Bitmap (canvasBmd);
10 canvasBm x = 120;
11 canvasBm y = 10;
12 addChild (canvasBm);
13
14 addEventListener ( Event.ENTER_FRAME , onLoop, false , 0, true );
15 function onLoop(evt: Event ): void {
16 var rndX: int = Math.random () * 100;
17 var rndY: int = Math.random () * 100;
18 canvasBmd setPixel (rndX, rndY, colorPicker.color);
19 } Lines 16 and 17 of the listener select random pixel locations between 0 and
100, the size of the BitmapData instance These values are then passed to the
setPixel() method, along with the value from the color property of the picker Figure 9-18 shows the file in action
If you want to get a better view of the pixels changing, add the following bold line to your script after line 11 This will scale the bitmap 300 percent, enlarging the pixels so they are easier to see The source file already has this line in place, so you can compare your file with the source file, if you prefer
10 canvasBm y = 10;
11 canvasBm.scaleX = canvasBm.scaleY = 3;
12 addChild (canvasBm);
Expanding Your Paint Program
This exercise picks up where our paint tool left off, and can be found in the
paint_tool_erase_blur_pick_save_png.fla source file At this point, the paint
program can paint using a blue color and air brush effect, as well as erase what you create We’re going to add the most recent color picker, to allow you
Figure 9-18. Setting pixels in a canvas
N OT E
The setPixel() method takes integer
pixel values but ActionScript will
auto-matically truncate a Number (lop off the
decimal value) when passed into any
object typed as an int.
Trang 9Adding Functionality to Your Color Picker
to pick the color for your brush, and a custom button and image encoder to
save your artwork as a PNG
Although you may want to reorganize your file later (to consolidate import
statements, for example), we’re going to add the new code to the end of the
existing script for consistency and simplicity Lines 56 through 58 import
the required classes, including the color picker, button, and image encoder
classes Lines 60 through 62 create and position the color picker, and add it
to the display list, as in the setPixel() example
Lines 64 through 68 add a mouse click event listener to the color picker to
supplement its functionality In addition to its self-contained behavior (like
populating its text field and tinting its color chip), clicking on the picker
widget will also query its color property and recreate the brush tool with the
newly selected color This will change the color of your airbrush
56 import com.learningactionscript3.color.ColorPickerCustom;
57 import com.learningactionscript3.ui.RoundRectButton;
58 import com.adobe.images.PNGEncoder;
59
60 var colorPicker:ColorPickerCustom = new ColorPickerCustom();
61 colorPicker x = colorPicker y = 10;
62 addChild (colorPicker);
63
64 colorPicker addEventListener ( MouseEvent.CLICK ,
65 onPickColor, false , 0, true );
66 function onPickColor(evt: MouseEvent ): void {
67 brush = createBrush(colorPicker.color, 1);
68 }
The final section of code allows you to save your artwork to a PNG file
Lines 70 through 72 create a single instance of the RoundRectButton class
introduced in Chapter 8 The button is 60 × 20 pixels, with a rounded corner
radius of 6 A single-pixel border and button color based on a dark blue color
theme, offsets the white button label, “Save.” The button is positioned below
the picker in lines 73 and 74, and added to the display list in line 75
Lines 77 through 84 add a mouse click event listener to the button, and the
three simple lines of code therein are all it takes to save your art as a PNG
Line 80 encodes the bitmap data into bytes, just like the JPGEncoder class that
you used in the “Saving JPG Images” section of this chapter, with two small
exceptions The PNGEncoder class requires no quality setting or instantiation
Instead, the encode() method is static and can be called by the class itself, not
by an instance of the class Lines 82 and 83 are essentially the same in both
examples, with the very minor change of the default file name
70 var saveBtn:RoundRectButton =
71 new RoundRectButton(60, 20, 6, 1, 0x000066,
72 "Save" , 0xFFFFFF);
73 saveBtn x = 10;
74 saveBtn y = 150;
75 addChild (saveBtn);
76
Trang 10What’s Next?
77 saveBtn addEventListener ( MouseEvent.CLICK , onSaveImage,
78 false , 0, true );
79 function onSaveImage(evt: Event ): void {
80 var byteArray: ByteArray = PNGEncoder encode (bmd);
81
82 var fileRef: FileReference = new FileReference ();
83 fileRef save (byteArray, "myArt.jpg" );
84 } Congratulations! Your modifications are complete Figure 9-19 shows a detail
of the application at work In this figure, we set the stage color to a pale yellow
to emphasize that the erasing is actually removing color, instead of painting over it with white
What’s Next?
One of the most surprising things to come to light after each major Flash upgrade is how small the engineering team manages to keep Flash Player The bitmap manipulation and compositing features discussed in this chapter are
by no means an exhaustive look at everything Flash Player can do with pix-els If you spent some time and effort on the project, you could make a fairly respectable graphics-editing application using only Flash (and, perhaps, a server technology like PHP for file management) The best examples of this that we can think of are the image editing applications available in the Aviary suite at http://www.aviary.com Yet despite these capabilities, Flash Player still remains small and easy to install and update Bravo, past and present Flash Professional and Flash Player engineers, and congratulations to the creative and programming team at Aviary!
Now it’s time to change direction and focus on the oft-overlooked workhorse
of the Flash family: text Text can be as fruitful a subject for experimentation and eye-candy as vectors and bitmaps, but it also serves a very important utilitarian purpose Creating, styling, and parsing text are fundamental needs that you’ll frequently encounter
In the next chapter, we’ll look at ways to work with text, including:
• Creating text fields on the fly
• Initializing basic text field appearance and behavioral attributes
• Formatting text, including default formats for text fields, as well as chang-ing formats across entire fields or partial text selections
• Using HTML and Cascading Style Sheets (CSS) for limited HTML ren-dering and global styling
• Embedding ActionScript triggers in HTML anchor tags
• Parsing paragraph, line, and character data from text fields using points and indices
Figure 9-19. A detail of the save-capable
painting application
learningaction-script3 Packages
The new packages contributed
to the book’s ActionScript 3.0
library for this chapter include
ColorPickerCustom, a class for
creating a functioning color picker,
and ColorEffects, a bonus
class that consolidates several
preset color effects discussed in
the chapter, which you can use
with the ConvolutionFilter,
ColorTransform, and
ColorMatrixFilter classes.