#777 – Animating a Transform

You can animate any of the 2D transforms applied to an element by using a Storyboard that contains an object that derives from AnimationTimeline.

In the example below, we use two DoubleAnimation objects to animate the X and properties of a TranslateTransform, so that the TextBlock wanders around the screen.

For the X property of the transform, we specify that we want it to vary from -100 to 100 and then back again, taking 0.7 seconds and then repeating the pattern forever.  We do something similar for Y, but using a different time period.

    <Grid>
        <TextBlock Text="We shall overcome" HorizontalAlignment="Center" VerticalAlignment="Center"
                   Padding="20,10" Background="PaleGoldenrod" FontSize="16">
            <TextBlock.RenderTransform>
                <TranslateTransform x:Name="transTransform" X="-100" Y="-80"/>
            </TextBlock.RenderTransform>
            <TextBlock.Triggers>
                <EventTrigger RoutedEvent="TextBlock.Loaded">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="transTransform"
                                             Storyboard.TargetProperty="X"
                                             From="-100" To="100" Duration="0:0:0.7"
                                             AutoReverse="True" RepeatBehavior="Forever"/>
                            <DoubleAnimation Storyboard.TargetName="transTransform"
                                             Storyboard.TargetProperty="Y"
                                             From="-80" To="80" Duration="0:0:1.5"
                                             AutoReverse="True" RepeatBehavior="Forever"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </TextBlock.Triggers>
        </TextBlock>
    </Grid>

777-001
777-002

Advertisement

#776 – Setting the Center Point for Skew Transforms

Like rotation transforms, you can set the origin for a skew transform using either the RenderTransformOrigin property on the element, or the CenterX/CenterY properties on the SkewTransform element.

You can think of the center of a skew transform as the point that will be held in one place as the object is tilted.

Also note–setting the X value of the center point only affects skews specified using AngleY and setting the Y value only affects skews specified using AngleX.

In the example below, we use RenderTransformOrigin to move the Y component of the center point, which impacts how the AngleX skew is done.

776-001

 

You can better see how this works by looking at how the Visual Studio designer shows you the skew.  It also shows the pre-transformed element, so you can see which point is being used as the origin.

776-002

 

776-003

#775 – Skew Transforms

You can use a skew transform to skew, or tilt, a user interface element in either the X or Y dimensions.  You specify skew values separately in both X and Y dimensions, expressed as an angle.

You specify a skew using a SkewTransform element, setting values for the AngleX and AngleY properties.  Both properties default to a value of 0.

Specifying a value for AngleX tilts an element’s vertical edges away from the Y axis.  Specifying a value for AngleY tilts an element’s horizontal edges away from the X axis.

Here’s an example:

        <TextBlock Text="No Skew" HorizontalAlignment="Left"
                   Padding="20,10" Background="PaleGoldenrod" Margin="10" FontSize="16" />

        <TextBlock Text="Skew, AngleX = 25" HorizontalAlignment="Left"
                   Padding="20,10" Background="PaleGoldenrod" Margin="10" FontSize="16" >
            <TextBlock.LayoutTransform>
                <SkewTransform  AngleX="25"/>
            </TextBlock.LayoutTransform>
        </TextBlock>

        <TextBlock Text="Skew, AngleY = 25" HorizontalAlignment="Left"
                   Padding="20,10" Background="PaleGoldenrod" Margin="10" FontSize="16" >
            <TextBlock.LayoutTransform>
                <SkewTransform  AngleY="25"/>
            </TextBlock.LayoutTransform>
        </TextBlock>

775-001

#774 – Translate Transforms

You can use a translation transform to translate, or move, a user interface element in the X or Y dimensions.  You specify translation values separately in both X and Y dimensions, expressed in device independent units.

You specify translation using a TranslateTransform element, setting values for the X and Y properties.  Both properties default to a value of 0.

LayoutTransform will ignore translation transforms (since the element will be moved around during the layout process anyway).  So you only use translation transforms with a RenderTransform.

Here’s an example that uses a couple of Sliders to dynamically change the X and Y values of a TranslateTransform.

    <StackPanel Orientation="Vertical">
        <TextBlock Text="Jack Kerouac" FontWeight="Bold" HorizontalAlignment="Center"
                   Padding="10,5" Background="PaleGoldenrod" Margin="5">
            <TextBlock.RenderTransform>
                <TranslateTransform  X="{Binding ElementName=sliX, Path=Value}" Y="{Binding ElementName=sliY, Path=Value}"/>
            </TextBlock.RenderTransform>
        </TextBlock>
        <TextBlock Text="Born 12 Mar, 1922" HorizontalAlignment="Center"
                   Padding="10,5" Background="Thistle"/>

        <Slider Name="sliX" Minimum="0" Maximum="300" Margin="10"/>
        <Slider Name="sliY" Minimum="0" Maximum="300" Margin="10"/>
    </StackPanel>

774-001
774-002
774-003

#773 – A Rotation Center Point Can Be Outside an Element

When you use the RenderTransformOrigin property of an element to specify the point of origin for all render transforms, you typically express X and Y as normalized coordinates.  X and Y both range from 0.0 to 1.0 as the position moves from one side of the element to the other.

You can also specify X and Y values that are less than 0.0 or greater than 1.0, indicating a point that is outside the element’s boundaries.  (Possibly quite distant from the element).

In the example below, the origin for a rotation transform is set to be off to the right of a Button.  The Slider allows you to try out different rotation angles at runtime.

    <StackPanel Orientation="Vertical">
        <Button Content="Push Me" HorizontalAlignment="Center" Padding="10,5" Margin="5"/>
        <Button Content="And Me" HorizontalAlignment="Center" Padding="10,5" Margin="5"
                RenderTransformOrigin="3.0,1.0" >
            <Button.RenderTransform>
                <RotateTransform Angle="{Binding ElementName=sliAngle, Path=Value}" />
            </Button.RenderTransform>
        </Button>
        <Slider Name="sliAngle" Minimum="-180"  Maximum="180" Value="-20" Margin="25,100"/>
    </StackPanel>

773-001
773-002

#772 – Use RenderTransformOrigin to Change Center Point for Rotation Transforms

There are two methods for specifying the center point for a rotation transform.  You can either set the RenderTransformOrigin property for the element itself or you can set the CenterX and CenterY properties of the RotateTransform element.

Using RenderTransformOrigin is preferred, because you specify the center point using coordinates that are normalized against the rendered size of the element.  This is easier than having to know what the actual size of element is.  For example, you use (0.5, 0.5) to indicate that the rotation center is the center of the element.

The RenderTransformOrigin property will apply to all render transforms being applied to the element.  So if you have multiple transforms and want to specify an origin for only the rotation transform, you’ll need to use the CenterX/CenterY properties on the RotateTransform element.

        <Button Content="Push Me" HorizontalAlignment="Center"
                RenderTransformOrigin="0.5,0.5"
                Margin="30">
            <Button.RenderTransform>
                <RotateTransform Angle="45" />
            </Button.RenderTransform>
        </Button>

772-001

#771 – Setting the Center Point for Rotation Transforms

When you rotate a user interface element using a rotation transform, you can choose the point about which the element rotates.  By default, the element will rotate about a point at the upper left corner of the element, at the point (0,0).

There are two different ways for specifying the center point of the rotation:

  • Using the CenterX and CenterY properties of the RotateTransform, in device independent units
  • Using the RenderTransformOrigin property on the element itself to set both X and Y values, in normalized (0.0 – 1.0) units

(The RenderTransformOrigin actually applies to all render transforms being applied to the element).

In both coordinate systems, the X value increases from left to right and the Y value increases from top to bottom.

Using RenderTransformOrigin to specify the different corners of the element, you’d use:

771-002

And using CenterX and CenterY for a button with a size of 100 x 30, you’d use:

771-003

#770 – The Difference Between a LayoutTransform and a RenderTransform

When you are transforming user interface elements using a 2D transform, you can choose one of two types of transforms.

  • LayoutTransform transforms elements before they are layed out by the parent panel
  • A RenderTransform transforms element after they are layed out by the parent panel (but before they are rendered)

Which one you use depends on whether you want transform and then lay out (use LayoutTransform) or to lay out and then transform (use RenderTransform).  (Note: You could also use both types).

    <StackPanel Orientation="Horizontal">
        <StackPanel Orientation="Vertical">
            <Label Content="LayoutTransform"/>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}"/>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}">
                <Button.LayoutTransform>
                    <RotateTransform Angle="20"/>
                </Button.LayoutTransform>
            </Button>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}">
                <Button.LayoutTransform>
                    <RotateTransform Angle="-20"/>
                </Button.LayoutTransform>
            </Button>
        </StackPanel>
        <StackPanel Orientation="Vertical">
            <Label Content="RenderTransform"/>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}"/>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}">
                <Button.RenderTransform>
                    <RotateTransform Angle="20"/>
                </Button.RenderTransform>
            </Button>
            <Button Content="Push Me" Style="{StaticResource buttonStyle}">
                <Button.RenderTransform>
                    <RotateTransform Angle="-20"/>
                </Button.RenderTransform>
            </Button>
        </StackPanel>
    </StackPanel>

770-001

#769 – Rotation Transforms

You can use a rotation transform to rotate a user interface element.

To rotate an element, you specify the number of degrees to rotate, in a clockwise fashion.  A negative number will rotate the object counter-clockwise.  By default, the object is rotated around a point at its center.

You specify rotation using a RotateTransform element, setting values for the Angle property.

Note that rotating an element normally doesn’t change the element’s ability to respond to user input.

Here’s a simple example:

    <StackPanel Orientation="Vertical">
        <Button Content="Push Me" HorizontalAlignment="Center" Padding="10,5" Margin="5"/>
        <Button Content="Push Me" HorizontalAlignment="Center" Padding="10,5" Margin="5">
            <Button.LayoutTransform>
                <RotateTransform Angle="15"/>
            </Button.LayoutTransform>
        </Button>
        <Button Content="Push Me" HorizontalAlignment="Center" Padding="10,5" Margin="5">
            <Button.LayoutTransform>
                <RotateTransform Angle="-15"/>
            </Button.LayoutTransform>
        </Button>
        <Button Content="Push Me" HorizontalAlignment="Center" Padding="10,5" Margin="5">
            <Button.LayoutTransform>
                <RotateTransform Angle="-90"/>
            </Button.LayoutTransform>
        </Button>
    </StackPanel>

769-001

#768 – Scaling Transforms

You can use a scaling transform to scale a user interface element in the X or Y dimensions.  Scaling an element increases or reduces its size.  You can specify separate scaling in the X and Y dimensions.

A value of 1.0 represents the normal (not scaled) size of the element.  Scale values larger than 1.0 increase the size of the element and values less than 1.0 decrease its size.

You specify scaling using a ScaleTransform element, setting values for the ScaleX and ScaleY properties.  If you don’t supply a scale value for one of the dimensions (X or Y), a value of 1.0 is used.

Here’s a simple example:

    <StackPanel Orientation="Vertical">
        <Button Content="Push Me" HorizontalAlignment="Center" Padding="10,5" Margin="5"/>
        <Button Content="Push Me" HorizontalAlignment="Center" Padding="10,5" Margin="5">
            <Button.LayoutTransform>
                <ScaleTransform ScaleX="2.0"/>
            </Button.LayoutTransform>
        </Button>
        <Button Content="Push Me" HorizontalAlignment="Center" Padding="10,5" Margin="5">
            <Button.LayoutTransform>
                <ScaleTransform ScaleY="2.0"/>
            </Button.LayoutTransform>
        </Button>
        <Button Content="Push Me" HorizontalAlignment="Center" Padding="10,5" Margin="5">
            <Button.LayoutTransform>
                <ScaleTransform ScaleX="0.7" ScaleY="0.7"/>
            </Button.LayoutTransform>
        </Button>
    </StackPanel>

767-001