Recommended

Skip Navigation LinksHome / Articles / View Article

Silverlight Bug: Transforms and OpacityMask

+ Add to SilverlightShow Favorites
2 comments   /   aggregated from Laurent Bugnion (GalaSoft) on Apr 04, 2008  /  original article
(0 votes)
Categories: Issues
Introduction

In WPF, one of the best know effects is the "reflection" effect, where a scene reflects itself dynamically. It's a very cool feature, because it's really easy to realize, and it allows to reflect images, but also videos or other User Interface scenes. The key to this is to use a VisualBrush. Silverlight is not exactly as powerful as WPF, and doesn't have VisualBrush, but it has ImageBrush and VideoBrush, both of them allowing cool media reflection effects (these brushes can also be used for other things!).

The key to making a reflection is placing a picture (or a video), and underneath it, an element (typically a Border). Then, you set the background of this element (Border.Background) to an ImageBrush (or a VideoBrush) pointing to the source that you want to reflect. To make the reflection look more lifelike, however, you want to skew it (because the surface you reflect is forming an angle with the reflecting element); also, you typically use an OpacityMask and make it look as if the reflection was progressively disappearing on a non-perfect surface. Life is not perfect, people, so a perfect reflection doesn't look lifelike.

The issue

However, when creating such an effect, I noticed an issue causing skewed elements with an OpacityMask to disappear completely. The following code shows the problem:

<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="200"/> <ColumnDefinition Width="*"/> Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="100"/> <RowDefinition Height="*"/> Grid.RowDefinitions> <Border Background="Red"> <Border.OpacityMask> <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> <GradientStop Color="#FFFFFFFF" Offset="0"/> <GradientStop Color="#00FFFFFF" Offset="1"/> LinearGradientBrush> Border.OpacityMask> <Border.RenderTransform> <SkewTransform AngleX="30" AngleY="0"/> Border.RenderTransform> Border> Grid>
Skewed Border, OpacityMask, Silverlight
Skewed Border, OpacityMask, WPF
Notes

Here are a couple of notes about this:

  • I simplified the code as much as possible to display the issue. Obviously this is not a reflection anymore, but I stumbled upon the issue when creating a reflection.
  • The issue is visible in Blend and also if you run the application.
  • This issue is not limited to Borders. It also occurs if you replace the Border with a Grid, for example.
  • The issue also occurs with other Transforms. Replacing the SkewTransform with a RotateTransform will reproduce the issue.
  • If you don't transform the element, the issue does not occur.
  • If you remove the OpacityMask, the problem does not occur.
  • If you give a Width and a Height to the element, the problem does not occur.
  • The same code in WPF runs correctly.

Share


Comments

Comments RSS RSS
  • RE: Silverlight Bug: Transforms and OpacityMask  

    posted by Luke Puplett on Nov 11, 2009 21:05

    Hi I've just been trying to make a ticker whereby the edges of the content (usually text) fade into the surroundings. When translating the text (label, Canvas, etc.) the OpacityMask either moves or shrinks although the ScrollViewer generally is less buggy.

    I've added some commentry at the end of the OpactiyMask MSDN documentation.

    Glad I'm not alone ;)

     

    Luke

  • RE: Silverlight Bug: Transforms and OpacityMask  

    posted by Soprano on Feb 23, 2010 21:36

    I cannot make OpacityMask using code in Silverlight 3. I tried the following simple example and it does not show any error nor displays the mask at all. It is like being ignored.

    The following code ignores the: rect1.OpacityMask = irgb; to apply the opacity mask at runtime.

    public MainPage() 

    {

    InitializeComponent();

    Rectangle rect1 = new Rectangle(); 

    rect1.Width = 300;

    rect1.Height = 300;

    rect1.Fill = new SolidColorBrush(Colors.Red); 

    RadialGradientBrush irgb = new RadialGradientBrush(); 

    irgb.GradientOrigin = new Point(0.5, 0.5); 

    irgb.Center = new Point(0.5, 0.5);

    irgb.RadiusX = 0.5;

    irgb.RadiusY = 0.5;

    GradientStop gs1 = new GradientStop(); 

    GradientStop gs2 = new GradientStop(); 

    GradientStop gs3 = new GradientStop(); 

    GradientStop gs4 = new GradientStop(); 

    // Set the color for each stop object 

    gs1.Color = Color.FromArgb(255, 255, 255, 255); 

    gs2.Color = Color.FromArgb(255, 255, 255, 255); 

    gs3.Color = Color.FromArgb(255, 150, 150, 150); 

    gs4.Color = Color.FromArgb(255, 0, 0, 0); 

    // Set the offset for each stop object 

    gs1.Offset = 0.0;

    gs2.Offset = 0.25;

    gs3.Offset = 0.75;

    gs4.Offset = 1.0;

    // Add the Gradient stops to the Linear Gradient Brush 

    irgb.GradientStops.Add(gs1);

    irgb.GradientStops.Add(gs2);

    irgb.GradientStops.Add(gs3);

    irgb.GradientStops.Add(gs4);

    rect1.OpacityMask = irgb;

    LayoutRoot.Children.Add(rect1);

    }

Add Comment

 
 

   
  
  
   
Please add 3 and 6 and type the answer here:

Help us make SilverlightShow even better. Whether you'd like to suggest a change in the structure, content organization, section layout or any other aspect of SilverlightShow appearance - we'd love to hear from you! Need material (article, tutorial, or other) on a specific topic? Let us know and SilverlightShow content authors will work to have that prepared for you. (hide this)