Opacity Masks are a great addition to Silverlight even thought it was there from the beginning, they are not as much helpful as otherwise they might be due to the lack of brushes in Silverlight (compared to WPF). And the addition of Alpha along with RGB in colour definition, opacity masks don't really gain much attention as they deserve. Although the use of Opacity Masks in Silverlight is very limited it is nonetheless a less important features, especially in animations and applying both vertical and horizontal gradients or both linier and radial gradient to the same object let us from start with looking at what opacity masks are and then how opacity masks are helpful in applying both vertical and horizontal gradients to the same object.
As you might already know that you can only attach one single colour schema (Either Solid colour or gradients) to an object, so we'll first begin with looking at what opacity masks are.
Opacity Masks.
First we'll look at what opacity masks do on a solid colour, and then we'll go in detail with complex gradients.
Image 1: Rectangle with Solid colour
<Rectangle Fill="#FF0B1BC6" Stroke="#FF000000" RadiusX="8" RadiusY="8"/>
Now I have an object with solid colour (Rectangle with Colour FF0B1BC6 in this case) and lets say that we want to apply some transparency to the the object either at the beginning or at the end, so since Silverlight have Alpha channel in its colour definition along with RGB definition its simple to use it, Since we are dealing with a solid colour here its easy to just create a liner gradient with alpha reduced e.g.,
Image 2: Rectangle with Linear gradient with opacity
<Rectangle RadiusX="8" RadiusY="8" Stroke="#FF000000">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#7F0B1BC6"/>
<GradientStop Color="#FF0B1BC6" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
Notice the Colour between two gradient stops they are the same colour (0B0BC6) the only difference is the Alpha (7F and FF), at offset 0 (beginning of the gradient) we have 50% opacity and at the offset 1 (end of the gradient) we have 100% opacity.
It works but we can also achieve he same by applying opacity mask to the rectangle in Image 1,
Image 3: Rectangle with opacity mask
<Rectangle Fill="#FF0B1BC6" Stroke="#FF000000" RadiusX="8" RadiusY="8">
<Rectangle.OpacityMask>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#7F000000" Offset="0"/>
<GradientStop Color="#FFFFFFFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.OpacityMask>
</Rectangle>
Notice Image 2 and Image 3, the difference isn't much, infact technically there isn't any difference because both of them are one and the same, the only difference is applying the opacity mask to a solid colour have achieved the same results as actually applying a gradient.
Uses of Opacity Mask
You might ask well if we can achieve the same results with both gradient and applying opacity mask then why use opacity mask, well the advantages of opacity masks are very clear, consider this you can only apply one gradient to an object but with the addition of opacity mask you can achieve both at the same time.
Here is an example,
Consider the following gradient
Image 4: Rectangle with liner gradient from left to right
Now consider that we want darken the rectangle on the top and leave the bottom the same, given that we can only apply one gradient for a single object, so to achieve this we'll have to put the another rectangle on top of that with a black gradient running from top to bottom, and giving the top about 50% opacity and the bottom 0% opacity.
Instead we can use opacity masks to achieve this,
Image 5: Rectangle gradient (left to right) with opacity mask (top to bottom)
<Rectangle RadiusX="8" RadiusY="8" Stroke="#FF000000">
<Rectangle.OpacityMask>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#7E000000" Offset="0.4"/>
<GradientStop Color="#FF000000" Offset="1"/>
<GradientStop Color="#B2000000" Offset="0.5"/>
</LinearGradientBrush>
</Rectangle.OpacityMask>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1.,0.5" StartPoint="0,0.5" >
<GradientStop Color="#FFC60B0B" Offset="0"/>
<GradientStop Color="#FFC60B0B" Offset="1"/>
<GradientStop Color="#FFAAB30C" Offset="0.175"/>
<GradientStop Color="#FE3B8C41" Offset="0.31"/>
<GradientStop Color="#FE2E6C6F" Offset="0.48"/>
<GradientStop Color="#FE21258D" Offset="0.70"/>
<GradientStop Color="#FE9E19A1" Offset="0.85"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
This trick is usually used in making the glass effects with gradients, and it is limited to dark backgrounds since in reality the opacity mask is actually making the object transparent than actually making it darker or lighter, which brings us to another usage of opacity masks.
Partially transparent objects, captures the imagination, and you can achieve them using opacity masks, for example consider the following image, its the same rectangle in Image 5 over other rectangles.
Objects using Opacity Masks
Opacity masks are not limited to objects rectangles or paths or gradients, opacity masks can also be applied to various objects to give partial transparency, including and not limited to images and vides infact you can apply opacity masks to all UI elements and you can apply any brush (Graident brush/image brush/Video Brush etc.) as a base for opacity mask.
Opacity Masks in Silverlight 2 are limited since other brushes (those available in WPF) are not available in Silverlight, but probably probably they might be avialble in future versions of Silverlight.
Opacity Masks and animation and themes
One of the areas where I usually use opacity masks are in themes and animation, I'll soon post a tutorial on using opacity masks in animation/ themes and in creating custom controls and templates, watch this space.