In this example, we show how to programmatically create a gradient (a feathered or a 'soft') mask in ActionScript 3 and Flash. If you are interested in a simple mask, see another of our How-Tos: How to Create a Mask in ActionScript 3. For animating and manipulating masks dynamically, visit our tutorial: Masking in Flash CS3 and ActionScript 3.
Download
- Download the fla file our example: htalphamask.fla
The Code
We keep comments as comments within the code for greater clarity.
/*
We imported a jpeg image to the Stage and converted it to a MovieClip
called PrepPic. Then we linked the MovieClip to AS3 via Linkage item in the Library menu
(Flash CS3), or Properties - Linkage (Flash CS4). A Library object that is linked
to AS3, can be instantiated at runtime and this is what we are doing below.
Instead, of linking to AS3, you could have placed and positioned the MovieClip on the
Stage and give it an instance name
'maskedClip'. In that case, you would skip the first four lines. The rest would
remain the same.
*/
var maskedClip:MovieClip=new PrepPic();
this.addChild(maskedClip);
maskedClip.x=50;
maskedClip.y=45;
var clipWidth:Number=maskedClip.width;
var clipHeight:Number=maskedClip.height;
var maskingShape:Shape=new Shape();
//Even though the mask itself will not be visible, it MUST be
//added to the Display List.
this.addChild(maskingShape);
maskingShape.x=maskedClip.x;
maskingShape.y=maskedClip.y;
//We call a function, defined later in the script, that draws a gradient
//in 'maskingShape'.
drawInMask();
/*
The next two lines are CRUCIAL for a gradient mask to bahave
properly: both a masked Display Object and a masking Display Object
must be cached as Bitmaps. Otherwise, the whole area of the gradient
(except for the completely transparent areas) will fully reveal
the underlying image, and the gradient effect will not happen.
*/
maskedClip.cacheAsBitmap=true;
maskingShape.cacheAsBitmap=true;
/*
The next line assigns 'maskingShape' as a mask of 'maskedClip'.
Comment out this line and test the movie. You see a gradient-filled
rectangle drawn in 'maskingShape'. It is a radial gradient,
centered in the middle of the rectangle. What is changing in the gradient
is not the color (it remains white) but the opacity. Near the center,
the color is opaque. It becomes more and more transparent as you
get farther from the center. When assigned as a mask, the opaque
portions of the gradient will show the underlying image,
the transparent parts less so. The more transparent the mask, the less
visible is the underlying image. It may seem counterintuitive but it is not.
Remember, it is the FILLED areas of a mask that act as windows to see through.
The less 'filled' - in other words, the more transparent - areas,
the less shows through.
*/
maskedClip.mask=maskingShape;
/*
The function 'drawInMask' draws the gradient in 'maskingClip' that you just saw
if you commented out the line above. Drawing gradients deserves a separate
tutorial or a How-To. We use the matrix parameter that you can pass
to 'beginGradientFill' method. We use the 'createGradientBox' method
of the Matrix class. The dimensions of our 'GradientBox'
coincide with those of our 'maskedClip'. The other parameters
that the 'beginGradientFill' method takes are colors (immaterial in our case),
alphas, and ratios. Our alphas Array determines that the colors (both white)
will change their opacity from 1 to 0, starting from the center
of the gradient. The ratios determine how the alphas will be distributed
throughout the gradient box. ratios=[0,255] would give a half-and-half
distribution. ratios=[200,255] cause alpha=1 (completely opaque) to occupy
most of the gradient, and alpha less than 1 only the edges.
*/
function drawInMask():void {
var mat:Matrix= new Matrix();
var colors:Array=[0xFFFFFF,0xFFFFFF];
var alphas:Array=[1,0];
var ratios:Array=[200,255];
mat.createGradientBox(clipWidth,clipHeight);
maskingShape.graphics.lineStyle();
maskingShape.graphics.beginGradientFill(GradientType.RADIAL,colors,alphas,ratios,mat);
maskingShape.graphics.drawEllipse(0,0,clipWidth,clipHeight);
maskingShape.graphics.endFill();
}
/*
The masked object can be any Display Object, not necessarily
a MovieClip. The masking object can also be any Display Object,
not necessarily a Shape. The only visible portion of the masked
object will be the portion behind the filled part of the masking object.
*/
/*
If you wish to remove a mask set the 'mask' property of the masked
object to null and remove the masking object:
maskedClip.mask=null;
this.removeChild(maskingShape);
*/