Reflections are neat. You can use them to create the illusion of depth, transforming a plain white background into a sheet of glossy white glass. In this post, I'll walk you through the process of using a ScaleTransform and an opacity mask to create a reflection in WPF/E.
You'll create a reflection for the following image.
The following illustration shows the completed reflection.
reflection_examples\reflection_example
aghost.js
gear_large.png
reflection.html
reflection.xaml
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!-- The object to reflect. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="20"> </Image></Canvas>
To run the sample, open the file named reflection.html in a browser. You should see the following output.
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!-- The object to reflect. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="20"> </Image> <!-- The reflection. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="20"> </Image> </Canvas>
-1
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!-- The object to reflect. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="20"> </Image> <!-- The reflection. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="20"> <Image.RenderTransform> <ScaleTransform ScaleY="-1" /> </Image.RenderTransform> </Image> </Canvas>
When you run the sample, notice that the second image has been flipped almost out of sight.
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!-- The object to reflect. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="20"> </Image> <!-- The reflection. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="258"> <Image.RenderTransform> <ScaleTransform ScaleY="-1" /> </Image.RenderTransform> </Image> </Canvas>
The markup now produces the following output.
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!-- The object to reflect. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="20"> </Image> <!-- The reflection. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="258"> <Image.RenderTransform> <ScaleTransform ScaleY="-1" /> </Image.RenderTransform> <Image.OpacityMask> <LinearGradientBrush StartPoint="0.5,0.0" EndPoint="0.5,1.0"> <GradientStop Offset="0.0" Color="#00000000" /> <GradientStop Offset="1.0" Color="#FF000000" /> </LinearGradientBrush> </Image.OpacityMask> </Image> </Canvas>
As you can see in the following output, the second image now fades into the background.
-0.75
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!-- The object to reflect. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="20"> </Image> <!-- The reflection. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="258"> <Image.RenderTransform> <ScaleTransform ScaleY="-0.75" /> </Image.RenderTransform> <Image.OpacityMask> <LinearGradientBrush StartPoint="0.5,0.0" EndPoint="0.5,1.0"> <GradientStop Offset="0.0" Color="#00000000" /> <GradientStop Offset="1.0" Color="#FF000000" /> </LinearGradientBrush> </Image.OpacityMask> </Image> </Canvas>
The sample now produces the following output. Notice that the reflected image appears to have changed position.
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!-- The object to reflect. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="20"> </Image> <!-- The reflection. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="228"> <Image.RenderTransform> <ScaleTransform ScaleY="-0.75" /> </Image.RenderTransform> <Image.OpacityMask> <LinearGradientBrush StartPoint="0.5,0.0" EndPoint="0.5,1.0"> <GradientStop Offset="0.0" Color="#00000000" /> <GradientStop Offset="1.0" Color="#FF000000" /> </LinearGradientBrush> </Image.OpacityMask> </Image> </Canvas>
As you can see in the following output, the reflected image is now in the correct position.
0.75
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!-- The object to reflect. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="20"> </Image> <!-- The reflection. --> <Image Source="gear_large.png" Canvas.Left="75" Canvas.Top="228" Opacity="0.75"> <Image.RenderTransform> <ScaleTransform ScaleY="-0.75" /> </Image.RenderTransform> <Image.OpacityMask> <LinearGradientBrush StartPoint="0.5,0.0" EndPoint="0.5,1.0"> <GradientStop Offset="0.0" Color="#00000000" /> <GradientStop Offset="1.0" Color="#FF000000" /> </LinearGradientBrush> </Image.OpacityMask> </Image> </Canvas>
-m jacobs