Table of Contents

MovieClip.beginGradientFill( ) Method Flash 6

starts a gradient-filled shape
mc.beginFill(fillType, colors, alphas, ratios, matrix)

Arguments

fillType

A string indicating the type of gradient, either "linear" or "radial". If any other value is specified, no gradient is drawn.

colors

An array of integers specifying the colors in the gradient. Normally supplied in RGB hexadecimal triplet notation�0xRRGGBB, where RR, GG, and BB are two-digit hex numbers representing Red, Green, and Blue. For example, the hex integer 0xFF0000 indicates red. For a complete discussion of RGB triplet notation, see the Color class.

alphas

An array of integers between 0 and 100, specifying the percentage opacity (or, conversely, the transparency) of the colors in the gradient. 0 is completely transparent, whereas 100 is completely opaque. Values above 100 are interpreted as 100; those below 0 are interpreted as 0. If the number of elements in the alphas array does not match the number of elements in the colors array, no gradient is drawn.

ratios

An array of integers specifying the spatial distribution of colors in the gradient on a scale from 0 to 255. Each element in the array indicates the relative position where the corresponding color from the colors array will display as a pure, unblended color. If the number of elements in the ratios array does not match the number of elements in the colors array, no gradient is drawn.

matrix

An object specifying the position, size, rotation, and skew of the gradient. The object takes one of two forms: a simple bounding box, where the gradient's position, size, and rotation are supplied through intuitive properties, or a raw 3 x 3 transformation matrix that maps a unit gradient centered about (0,0) to a final size, rotation, skew, and position. See details under the Description.

Description

Like beginFill( ), beginGradientFill( ) starts a shape, but it fills that shape with a linear or radial gradient (shown in Figure 18-1) instead of a solid fill.

Figure 18-1. A radial and a linear gradient
figs/act2.R01.gif

The gradient is defined, positioned, sized, and rotated by the fillType, colors, alphas, ratios, and matrix parameters. The filled shape appears above all Drawing API content already in mc, but beneath all other content in mc (e.g., movie clips, shapes, text, and buttons placed at authoring time, or content attached at runtime via attachMovie( ), duplicateMovieClip( ), or createTextField( )).

Just as with beginFill( ) we start drawing a gradient-filled shape with a call to moveTo( ), which indicates the starting position of the outline we'll draw around the shape. Next, we call beginGradientFill( ) to start the shape and define the attributes of the gradient. We then draw the shape's outline with lineTo( ) and/or curveTo( ) calls. Conceptually, the gradient is distinct from the shape, as though the two were separated onto two layers, with the gradient beneath the shape. The shape acts as a hole through which the gradient layer is visible (that is, the gradient is "clipped" by the shape). For example, if we draw a 100 x 100 square at position (25,0) and a 75 x 300 two-color linear gradient at position (0,0), the blended portion of the gradient extends 50 pixels into the square, and the remainder of the square is filled with the rightmost color in the gradient, as shown in Figure 18-2.

Figure 18-2. A linear gradient and a square
figs/act2.R02.gif

To make the gradient span the entire square perfectly, we'd have to change its size to 100 x 100, and position it at (25,0), the top-left corner of the square. Let's see how this works in code, first with the offset gradient, then with the perfectly aligned one. First, we make a clip in which to draw the square:

this.createEmptyMovieClip("drawing_mc", 1);

Then we position the drawing pen at (25,0):

drawing_mc.moveTo(25, 0);

Now we have to define the gradient. We'll store each of beginGradientFill( )'s arguments in a variable for easy reading. The fillType parameter should be "linear" or "radial", indicating whether the bands of color in the gradient will form straight lines or circles. We use a "linear" gradient (straight lines):

var fillType = "linear";

Next, we specify an array of color values (the colors parameter); these are the bands of color that will be blended together in our gradient. We have two colors, white and black, but you can specify as many as you like:

var colors = [0xFFFFFF, 0x000000];

Next, we specify the transparency of each color as an array of integers between 0 and 100 (the alphas parameter). Each element in alphas corresponds to an element in colors (both arrays must have the same number of elements). An alpha of 0 is completely transparent, whereas 100 is completely opaque. Our colors are not transparent, so we set them both to 100:

var alphas = [100, 100];

Next, we define the proportional position of each color band in our gradient as an array of integers between 0 and 255 (the ratios parameter). As before, the ratios array must have the same number of elements as the colors array. A value of 0 means the color is pure at the leftmost (linear) or innermost (radial) point of the gradient. A value of 255 means the color is pure at the rightmost (linear) or outermost (radial) point of the gradient. We want our gradient to blend evenly from white to black across its entire width, so we set the position of pure white to 0, and the position of pure black to 255:

var ratios = [0, 255];

Finally, we set the position, width, height, and rotation of our gradient as an object (the matrix parameter). We set the matrix object's matrixType property to "box" and then provide values for the following properties: x (horizontal position), y (vertical position), w (width), h (height), and r (rotation). The x and y properties specify the gradient's top-left corner, relative to the clip's registration point, and the r property specifies the gradient's angle of rotation, in radians, not degrees. Our code calls a custom toRadians( ) function that converts degrees to radians:

var matrix = { matrixType:"box", x:0, y:0, w:75, h:300, r:toRadians(0) };
function toRadians (deg) {
  return deg * Math.PI/180;
}

With our gradient arguments defined, we can now invoke beginGradientFill( ):

drawing_mc.beginGradientFill(fillType, colors, alphas, ratios, matrix);

And then we simply draw our square, exactly as we would with a solid fill, being sure to return to the starting point (25,0) with our last call to lineTo( ):

drawing_mc.lineTo(125, 0);
drawing_mc.lineTo(125, 100);
drawing_mc.lineTo(25, 100);
drawing_mc.lineTo(25, 0);

Finally, we formally close the shape with endFill( ), which completes our gradient-filled square:

drawing_mc.endFill();

Now, how about aligning our gradient perfectly with the square? No problem, we just change the gradient's starting position to the shape's origin, (25,0), and set its size to 100 x 100 by adjusting our matrix object:

var matrix = { matrixType:"box", x:25, y:0, w:100, h:100, r:toRadians(0) };

By setting the r property of matrix to the number of radians in 45 degrees, using toRadians(45), we can create a diagonal gradient instead:

var matrix = { matrixType:"box", x:25, y:0, w:100, h:100, r:toRadians(45) };

To fill the nicely aligned box with a white circular gradient, we can set fillType to radial:

var fillType = "radial";

To switch the order of the colors, we simply reverse the colors array, as follows:

var colors = [0x000000, 0xFFFFFF];

The stroke defined by the most recent call to lineStyle( ) is automatically added to the shape. If lineStyle( ) has never been called, the shape is not stroked. For example, placing the following code before our moveTo( ) statement adds a red stroke to our square:

drawing_mc.lineStyle(1, 0xFF0000);

For most purposes, the bounding box object we used for matrix in our square example provides ample gradient control. However, a gradient's position, rotation, scale, and skew can also be specified by a 3 x 3 transformation matrix applied to a unit gradient centered at position (0,0). Transformation matrices are useful when programmatically generating fills, as is necessary in, say, a 3D engine. To use a 3 x 3 transformation matrix, we set the matrix parameter of beginGradientFill( ) to an object with the properties a, b, c, d, e, f, g, h, and i, corresponding to the following positions in our 3 x 3 matrix:

---------------
|  a   b   c  |
|  d   e   f  |
|  g   h   i  |
---------------

To scale, rotate, and translate (move) the unit gradient, we use the following transformation matrices:

     SCALE                  TRANSLATE                  ROTATE (clockwise)
---------------         ---------------         --------------------------------
|  sx  0   0  |         |  1   0   0  |         | cos(theta)  sin(theta)    0  |
|  0   sy  0  |         |  0   1   0  |         | -sin(theta) cos(theta)    0  |
|  0   0   1  |         |  tx  ty  1  |         | 0           0             1  |
---------------         ---------------         --------------------------------
sx = x scale factor     tx = amount of x-shift
sy = y scale factor     ty = amount of y-shift

In the simplest case, where we neither scale, rotate, nor translate the gradient, the matrices reduce to:

     SCALE                  TRANSLATE                  ROTATE (clockwise)
---------------         ---------------         --------------------------------
|  1   0   0  |         |  1   0   0  |         | 1           0             0  |
|  0   1   0  |         |  0   1   0  |         | 0           1             0  |
|  0   0   1  |         |  0   0   1  |         | 0           0             1  |
---------------         ---------------         --------------------------------
sx = x-scale factor     tx = amount of x-shift
sy = y-scale factor     ty = amount of y-shift

and our matrix object is set as follows:

var matrix = { a:1, b:0, c:0, d:0, e:1, f:0, g:0, h:0, i:1 };

To scale the unit gradient to 100 x 100, we set the a and e properties to 100, leaving the i property as 1 and the others as 0, as follows:

var matrix = { a:100, b:0, c:0, d:0, e:100, f:0, g:0, h:0, i:1 };

This transformation is close to the one we specified earlier for our square's gradient, but it is not identical. The x-scale and y-scale factors of the matrix (a and e) cause the unit gradient, which is centered around the origin (0,0), to be scaled up to a height and width of 100. Scaling alone, however, does not change the center point of the gradient�it remains at (0,0) when the translation properties (g and h) are set to 0.

To also move the gradient's origin to position (25,0), we set the horizontal translation parameter (g) to move the gradient 25 pixels to the right, as follows:

var matrix = { a:100, b:0, c:0, d:0, e:100, f:0, g:25, h:0 , i:1 };

This produces a gradient that is centered about the point (25,0).

However, our earlier matrix positioned the gradient's top-left corner, not its center, at (25,0). To center the gradient in our square (as we did earlier), we need to translate from the point (25,0) to the middle of the destination by adding 50 to the horizontal and vertical coordinates (50 is half of our square's width and height).

Therefore, to center our gradient, we set g to 75 (which is 25 + 50) and h to 50 (which is 0 + 50), as follows:

var matrix = { a:100 , b:0 , c:0 , d:0 , e:100 , f:0 , g:75 ,h:50 , i:1 };

For comparison, here's the complete square code, showing both ways of specifying our beginGradientFill( )'s matrix argument:

// Convenient degree-to-radian converter.
function toRadians (deg) {
  return deg * Math.PI/180;
}
   
// Define our beginGradientFill() parameters.
var fillType = "linear";
var colors = [0xFFFFFF, 0x000000];
var alphas = [100, 100];
var ratios = [0, 255];
// Use either the box matrix version:
var matrix = { matrixType:"box", x:25, y:0, w:100, h:100, r:toRadians(0) };
// or the transformation matrix version:
var matrix = { a:100 , b:0 , c:0 , d:0 , e:100 , f:0 , g:75 ,h:50 , i:1 };
   
// Make the movie clip.
this.createEmptyMovieClip("drawing_mc", 1);
   
// Draw the gradient-filled square.
drawing_mc.moveTo(25, 0);
drawing_mc.beginGradientFill(fillType, colors, alphas, ratios, matrix);
drawing_mc.lineTo(125, 0);
drawing_mc.lineTo(125, 100);
drawing_mc.lineTo(25, 100);
drawing_mc.lineTo(25, 0);
drawing_mc.endFill();

By combining matrices, we can use a single matrix to describe scale, rotation, and translation together. Matrix multiplication is outside the scope of this discussion; however, Macromedia provides a TransformMatrix class on the Flash MX CD under: Goodies\Macromedia\Other Samples\transformmatrix.as. It defines easy-to-use methods for specifying and combining transformation matrices.

Usage

Even though Flash attempts to fix improperly specified shapes (e.g., a shape with no endFill( ) method), predictable results can be guaranteed only when the shape-drawing rules described under MovieClip.beginFill( ) are observed.

Example

The following code draws a triangle with a red, green, and blue radial gradient. The triangle is centered about the clip's registration point, and the gradient is centered within the triangle:

// Create an empty clip for drawing, and set the pen position
this.createEmptyMovieClip("drawing_mc", 1);
drawing_mc._x = drawing_mc._y = 200;
drawing_mc.lineStyle(1, 0xFF0000);
drawing_mc.moveTo(0, -50);
   
// Set gradient parameters
var fillType = "radial";
var colors = [0xFF0000, 0x00FF00, 0x0000FF];
var alphas = [100, 100, 100];
var ratios = [0, 127, 255];
var matrix = { matrixType:"box", x:-50, y:-35, w:100, h:100, r:toRadians(0) };
function toRadians (deg) {
  return deg * Math.PI/180;
}
   
// Start the shape
drawing_mc.beginGradientFill(fillType, colors, alphas, ratios, matrix);
// Draw the lines of the triangle
drawing_mc.lineTo(50, 50);
drawing_mc.lineTo(-50, 50);
drawing_mc.lineTo(0, -50);
// End the shape
drawing_mc.endFill();

See Also

MovieClip.beginFill( ), MovieClip.clear( ), MovieClip.curveTo( ), MovieClip.endFill( ), MovieClip.lineStyle( ), MovieClip.lineTo( ), MovieClip.moveTo( ); Chapter 13


Table of Contents