4.11. Filling a Shape with a Complex Gradient

Problem

You want to draw a gradient-filled shape at runtime, but the box-style gradient matrix doesn’t offer sufficient control.

Solution

Use the beginGradientFill( ) and endFill( ) methods in conjunction with a TransformMatrix object.

Discussion

In Recipe 4.10, we used a box-style gradient to apply a simple fill pattern. However, you can attain precise control over the gradient by passing a transformation matrix as the matrix parameter sent to the beginGradientFill( ) method.

ActionScript uses a 3 × 3 transformation matrix to apply a custom gradient. Working directly with the transformation matrix can be a bit more complicated than it is worth, so you should take advantage of the TransformMatrix class, which makes this process much easier. You need to include TransformMatrix.as in any Flash document in which you wish to work with a transform matrix:

#include "TransformMatrix.as"

The TransformMatrix.as file is not part of the standard Flash installation, but it is included on the Flash CD-ROM under Goodies\Macromedia\OtherSamples\transformmatrix.as. You should copy the file from the CD-ROM to Flash’s Include directory (FlashIntallation\Configuration\Include).

First, create a TransformMatrix object using the standard constructor method:

matrix = new TransformMatrix(  );

Thereafter, you can call any of the five available methods:

translate(x, y)

The translate( ) method offsets the bottom-left corner (for linear gradients) or the center (for radial gradients) of the gradient. By default, the gradient is positioned at (0,0). The two parameters specify the number of pixels by which to translate the gradient in the x and y directions.

scale(width, height)

The scale( ) method scales the gradient to the specified width and height.

rotate(degrees)

The rotate( ) method rotates the gradient clockwise by the specified number of degrees (not radians).

skew(degrees)

The skew( ) method skews the gradient by the number of degrees specified, creating a stretching effect.

shear(x, y)

The shear( ) method shears the gradient. The two parameters specify the number of pixels by which to shear the gradient in the x and y directions.

Unlike the standard 3 × 3 transformation matrix, the TransformMatrix class uses a gradient that is 1 × 1 pixels until you scale it. Therefore, when working with a transformation matrix, you should use the scale( ) method, either by itself or in conjunction with the other methods, to ensure that the gradient is appropriately sized.

This example applies the translate( ) method with the scale( ) method:

// Include the drawing methods, which are needed for the drawRectangle(  ) method.
#include "DrawingMethods.as"

// Include the file that implements the TransformMatrix class.
#include "TransformMatrix.as"

// Create an empty movie clip for drawing.
_root.createEmptyMovieClip("shape_mc", 1);

// Create the colors, alphas, and ratios arrays just as you would when working with a
// box-style gradient.
colors = [0x0000FF, 0x00FF00, 0xFF0000];
alphas = [100, 100, 100];
ratios = [0, 127.5, 255];

// Create a new TransformMatrix object.
matrix = new TransformMatrix(  );

// Scale the gradient to 100   ×   200 pixels and offset it 20 pixels to the right.
matrix.scale(100, 200);
matrix.translate(20, 0);

// Use a 1-pixel, black, solid border.
shape_mc.lineStyle(1, 0x000000, 100);

// Call beginGradientFill(  ) just as you would when working with a box-style gradient,
// except the matrix parameter is a TransformMatrix object.
shape_mc.beginGradientFill("linear", colors, alphas, ratios, matrix);

// Draw a rectangle (requires DrawingMethods.as).
shape_mc.drawRectangle(100, 200);
shape_mc.endFill(  );

You can achieve animation effects by repeatedly redrawing the same shape and applying different transformations to the gradient fill:

// Include the drawing methods, which are needed for the drawCircle(  ) method.
#include "DrawingMethods.as"
// Include the file that implements the TransformMatrix class.
#include "TransformMatrix.as"

_root.createEmptyMovieClip("shape_mc", 1);

// Call the following actions repeatedly by placing them within the shape_mc clip's
// onEnterFrame(  ) method.
shape_mc.onEnterFrame = function (  ) {

  // Create the colors, alphas, and ratios arrays as usual.
  var colors = [0x0000FF, 0x00FF00, 0xFF0000];
  var alphas = [100, 100, 100];
  var ratios = [0, 127.5, 255];

  // Create the TransformMatrix object.
  var matrix = new TransformMatrix(  );

  // Increment a custom scaleFactor property and pass that value to the transform
  // matrix's scale(  ) method. This will scale the gradient in the x and y directions
  // uniformly, increasing over time.
  var sf = this.scaleFactor++;
  matrix.scale(sf, sf);

  // Clear the previously drawn shape. Otherwise, Flash will get bogged down trying
  // to keep track of all the old shapes.
  this.clear(  );

  // Draw a circle with a gradient fill. Each time this circle is redrawn the 
  // gradient will be larger.
  this.lineStyle(1, 0x000000, 100);  // Use a one-pixel, black, solid border
  this.beginGradientFill("radial", colors, alphas, ratios, matrix);
  this.drawCircle(100);       // Requires DrawingMethods.as
  this.endFill(  );
}

Get Actionscript Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.