Home > Development > blogs
One thing that has always fascinated me with Flex/Flash is the power of native graphics APIs built into the Flash player. This is one feature where I have not seen an equal in any other RIA technology, based on ease of use and capability. These graphics APIs allow you to do everything from drawing a line from point A to point B, manipulate images, draw shapes, change image properties, etc... They enable a majority of the functionality in the Flex that makes it both extremely powerful, and unique. These graphics APIs enable dynamic charting, skinning, programmatic drawing, among countless other features, but for now I want to focus on one technique that seems strangely under-used in Flex: Graphics Masks.
Masks can be used for a variety of purposes. As an example, you can take a standard bar chart, and make it look something like this...
Most developers who have made the transition from Flash into Flex already know what I am talking about. Most developers that I have seen transition from the Java world into Flex do not.
Essentially, a mask is a "hole" (or shape) where the graphics of the masked object are visible. Any DisplayObject can be used as a mask on another display Object. The actual graphics of the masked object will only be displayed in the non-transparent part of the graphics mask.
Masks can be used to achieve some very dynamic interfaces and powerful graphics and visualizations. Some examples of which you will find later on in this post.
A mask can be hard to explain, so let's take a look at an example... If we start with this source image:
... apply this mask:
... this is what the result will look like:
As I mentioned before, any DisplayObject can be a mask of any other DisplayObject. This includes default Flex components, images, or custom drawing with the drawing API.
Now, lets look at how you do this...
My first example is using a mx:Canvas to create a mask over an image. You can see that the visible area of the canvas is the area of the image that is actually visible within the application, which includes the rounded corners of the image.
<mx:Image source="assets/chicago.jpg" x="518" y="10" mask="{maskCanvas}">
<mx:filters>
<filters:DropShadowFilter />
</mx:filters>
</mx:Image>
<mx:Canvas x="596" y="61" width="344" height="274" backgroundColor="#ff0000" id="maskCanvas" cornerRadius="15" borderStyle="solid"/>
Notice that the only thing you have to do to mask one object with another is to set the "mask" property.
This is a very simple example, but keep in mind masks can get much more complicated. When a mask object moves on the screen, so does the visible portion of the mask image. When using Image masks, you can actually use the transparency of images (png and gif) to determine the area that mask will show. Notice that the code is actually very simple:
<mx:Image source="assets/chicago.jpg" x="518" y="10" mask="{ maskImage }">
<mx:filters>
<filters:DropShadowFilter />
</mx:filters>
</mx:Image>
<mx:Image source="assets/imageMask.png" x="518" y="10" id="maskImage" cacheAsBitmap="true" /^gt;
There is one distinct, and very important difference in this case. You must set the value of the cacheAsBitmap parameter on the mask object to "true" for this to work properly.
Things get even more interesting when you start using png images that support semi-transparency as masks on your images. The code to do so is almost identical to that above, however you need to make sure that you set cacheAsBitmap='true' on both the mask and the object that is being masked. A simple semi-transparent gradient mask looks something like this.
when applied to an image, it will yield a result like this:
You can also use any DisplayObject as a mask on another object. So far, I have mostly focused on using images to mask other images, but what happens if you use an actionscript-rendered objects to mask an object? ... You get interesting results.
Here's an example showing a mask that changes over time. First, take a look at the screenshot:
Here's how it is applied; Notice that cacheAsBitmap must be set to true for both teh mask, and the masked object.
<mx:Image source="assets/chicago.jpg" x="518" y="10" mask="{ maskImage }" cacheAsBitmap="true">
<mx:filters>
<filters:DropShadowFilter />
</mx:filters>
</mx:Image>
<components:AnimatedMask id="maskImage" x="518" y="10" width="500" height="375" cacheAsBitmap="true" />
And here is the source of the mask object itself:
public class AnimatedMask extends Container
{
private var count : Number = 0;
public function AnimatedMask()
{
super();
this.addEventListener( Event.ENTER_FRAME, onEnterFrame )
}
private function onEnterFrame( event : Event ) : void
{
if ( this.visible )
{
count++;
var g:Graphics = this.graphics;
if ( count % 250 == 0 ) g.clear();
g.lineStyle( 3, 0, .5 );
g.moveTo( Math.random() * width, Math.random() * height )
g.lineTo( Math.random() * width, Math.random() * height )
}
}
}
The mask actually changes with every enterFrame event. This is a pretty basic example, but these concepts can go a long way. Now, lets look at some real-world scenarios how these techniques can be applied in your applications.
My first example is for creating dynamically color-coded complex objects. This could apply to almost anything, but for now, lets focus on a gear. Let's say that you have a gear in your application that represents part of a workflow process. You want that gear to change color based on data coming into you application. You can easily achieve this kind of effect without having to programmaticly draw every part of that shape. You can just use a mask that is the shape of a gear, and apply it to a Canvas object that has the background color changed at runtime. The results can be very dramatic. Here's an example:
And the code to achieve this is very simple as well:
<mx:Canvas x="10" y="10" width="200" height="200" id="colorCanvas" backgroundColor="#ff0000" mask="{ maskImage }" cacheAsBitmap="true">
<mx:filters>
<filters:DropShadowFilter />
</mx:filters>
</mx:Canvas>
<mx:Image source="assets/gearMask.png" x="10" y="10" id="maskImage" cacheAsBitmap="true" />
To change the color of the rendered gear image, all you need to do is change the color of the canvas that is being masked. This can be done very simply by changing the backgroundColor style property:
colorCanvas.setStyle( "backgroundColor", Math.random() * 0xFFFFFF );
As I said before, any DisplayObject can be used as a mask on any other DisplayObject. Here are a few examples showing you Flex charts that are applied as masks on images. you can create some really wild interfaces with these techniques.
You can view all of these examples in action at:
http://www.cynergysystems.com/blogs/blogs/andrew.trice/masks/masks.html
All of the source for this application is publicly available at:
http://www.cynergysystems.com/blogs/blogs/andrew.trice/masks/srcview/index.html
You can also check out a cool example using video on my Cynergy blog at:
http://www.cynergysystems.com/blogs/page/andrewtrice?entry=fun_with_masks












Andrew,
Excellent post! Thanks for the great tips and examples. It really does show how easy it is to make things look like you put a lot of time and design into them.
Cheers,
ewH
Very interesting post! (Coming from someone which never -really- programmed in any flash'esque tool).
Great post! Thanks for sharing with us..great codes and examples
Thanks... will defenetly give it a try.
Great tutorial. Your examples helped me make some animated masks from flash swfs.
That is really nice example.... so could you plz help in finding out???? how to find whether mask is used in project or not!!!! is there is any way to get mask layer name and its object present in that time line