User Tools

Site Tools


notes:uwp:animation

Animation in UWP

Animation properties (adapted from the book “Programming Windows, 6th edition” by Charles Petzold):

  • The DoubleAnimation element has to be a child of a Storyboard element.
  • Both the Storyboard and the DoubleAnimation derives from the Timeline.
  • DoubleAnimation can animate any property of type double that's backed by a dependency property, for example Width and Height.
  • By default, animations are performed in a secondary thread. However, an animation that targets the FontSize property of a TextBlock must run in the UI thread because a change in the font size triggers a layout change. To enable the animation to run in the UI thread set the EnableDependentAnimation property to True.
  • The FillBehavior is set to HoldEnd (default). Another value is Stop which releases the animation from its target property and sets the target property to its pre-animation value.
  • If we leave out the To value, the animation goes only to the pre-animation value. Similarily, if we leave out From, the animation goes from the current value up to the To value. The From and To properties are of nullable double type.
  • The By property (used instead of From and To) increases the target property by a certain value.
  • When the Autoreverse property is True, the animation plays in reverse after it completes a forward iteration.
  • RepeatBehavior can be set to the number of cycles (2x, 3x, etc.) or a duration (e.g. 0:0:7.5) which specifies the total duration of the animation. It can be also set to Forever.
  • The BeginTime property delays the start of an animation.
  • The SpeedRatio makes the animation to go faster. You can slow down the entire animation by setting the SpeedRatio to 0.1 on the Storyboard.
  • The Completed event can be used for a notification when the animation has completed.
  • The AutoReverse, BeginTime, Duration, FillBehavior, RepeatBehavior, SpeedRatio properties and the Completed event are defined by Timeline. It means that you can set these properties on Storyboard to define behavior for all the children of the Storyboard. Note that only if all the animations in a Storyboard are the same length can the AutoReverse and RepeatBehavior properties be moved to the Storyboard.
  • An animation can be triggered in XAML rather than than in code-behind using an EventTrigger.

Use DoubleAnimation to animate the width of a TextBlock:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Resources>
        <Storyboard x:Key="Storyboard1">
            <DoubleAnimation Storyboard.TargetName="TextBlock1"
                             Storyboard.TargetProperty="Width"
                             EnableDependentAnimation="True"
                             FillBehavior="HoldEnd"
                             AutoReverse="True"
                             RepeatBehavior="2x"
                             BeginTime="0:0:0.5"
                             SpeedRatio="3"
                             From="200" To="700" Duration="0:0:3" />
        </Storyboard>
    </Page.Resources>
 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <!-- The target of animation -->
        <TextBlock Name="TextBlock1"
                   Text="Lorem ipsum..."
                   FontSize="16"
                   Height="100"
                   Width="200"
                   TextWrapping="Wrap"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center" />
 
        <!-- A button to trigger the animation -->
        <Button Content="Animate" Click="AnimateButton_Click" 
                VerticalAlignment="Top" HorizontalAlignment="Center" />
    </Grid>
</Page>
using Windows.UI.Xaml.Media.Animation;
...
private void AnimateButton_Click(object sender, RoutedEventArgs e)
{
    // Trigger the Storyboard.
    (this.Resources["Storyboard1"] as Storyboard).Begin();
}

Use two DoubleAnimations to animate the width and the height of an ellipse. This example also shows that we can set properties common to both animations on the parent Storyboard:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Resources>
        <!-- common settings for both DoubleAnimations are set on the Storyboard -->
        <Storyboard x:Key="Storyboard1"
                    RepeatBehavior="Forever"
                    AutoReverse="True">
 
            <DoubleAnimation Storyboard.TargetName="Ellipse1"
                             Storyboard.TargetProperty="Width"
                             EnableDependentAnimation="True"
                             From="100" To="300" Duration="0:0:1" />
            <DoubleAnimation Storyboard.TargetName="Ellipse1"
                             Storyboard.TargetProperty="Height"
                             EnableDependentAnimation="True"
                             From="300" To="100" Duration="0:0:1" />
        </Storyboard>
    </Page.Resources>
 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Ellipse Name="Ellipse1" Fill="Navy" />
    </Grid>
</Page>
using Windows.UI.Xaml.Media.Animation;
...
public MainPage()
{
    this.InitializeComponent();
 
    // Trigger the animation when the page is loaded.
    Loaded += (sender, args) =>
    {
        (this.Resources["Storyboard1"] as Storyboard).Begin();
    };
}

Move a circle horizontally back and forth by animating attached properties Canvas.Left and Canvas.Right. Animating attached properties requires a special syntax for Storyboard.TargetProperty.

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Resources>
        <Storyboard x:Key="Storyboard1">
            <!-- the To property is set in code -->
            <DoubleAnimation Storyboard.TargetName="Ellipse1"
                             Storyboard.TargetProperty="(Canvas.Left)"
                             From="0" Duration="0:0:3"
                             AutoReverse="True"
                             RepeatBehavior="Forever" />
        </Storyboard>
    </Page.Resources>
 
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <!-- The margin compensate for the size of the Ellipse -->
        <Canvas Margin="0,0,48,48" SizeChanged="OnCanvasSizeChanged">
            <Ellipse Name="Ellipse1" Width="48" Height="48" Fill="Blue" />
        </Canvas>
    </Grid>
</Page>
using Windows.UI.Xaml.Media.Animation;
...
public MainPage()
{
    this.InitializeComponent();
 
    // Trigger the animation when the page is loaded.
    Loaded += (sender, args) =>
    {
        (this.Resources["Storyboard1"] as Storyboard).Begin();
    };
}
 
// Recalculate the To property when the window size changes.
// Note that we are changing values of an ongoing animation here.
void OnCanvasSizeChanged(object sender, SizeChangedEventArgs args)
{
    Storyboard storyboard = this.Resources["Storyboard1"] as Storyboard;
 
    // Canvas.Left animation
    DoubleAnimation anim = storyboard.Children[0] as DoubleAnimation;
    anim.To = args.NewSize.Width; // the new width of Canvas
}

Move a circle simultaneously horizontally and vertically. Together with AutoReverse set to True, it gives an effect of a bouncing ball against window edges. Note that we have to specify AutoReverse and RepeatBehavior individually on each animation as the duration of the animations is different.

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Resources>
        <Storyboard x:Key="Storyboard1">
            <DoubleAnimation Storyboard.TargetName="Ellipse1"
                             Storyboard.TargetProperty="(Canvas.Left)"
                             From="0" Duration="0:0:3.7"
                             AutoReverse="True"
                             RepeatBehavior="Forever" />
            <DoubleAnimation Storyboard.TargetName="Ellipse1"
                             Storyboard.TargetProperty="(Canvas.Top)"
                             From="0" Duration="0:0:1.01"
                             AutoReverse="True"
                             RepeatBehavior="Forever" />            
        </Storyboard>
    </Page.Resources>
 
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <!-- The margin compensate for the size of the Ellipse -->
        <Canvas Margin="0,0,48,48" SizeChanged="OnCanvasSizeChanged">
            <Ellipse Name="Ellipse1" Width="48" Height="48" Fill="Blue" />
        </Canvas>
    </Grid>
</Page>
using Windows.UI.Xaml.Media.Animation;
...
public MainPage()
{
    this.InitializeComponent();
 
    // Trigger the animation when the page is loaded.
    Loaded += (sender, args) =>
    {
        (this.Resources["Storyboard1"] as Storyboard).Begin();
    };
}
 
// Recalculate the To property when the window size changes.
// Note that we are changing values of an ongoing animation here.
void OnCanvasSizeChanged(object sender, SizeChangedEventArgs args)
{
    Storyboard storyboard = this.Resources["Storyboard1"] as Storyboard;
 
    // Canvas.Left animation
    DoubleAnimation anim = storyboard.Children[0] as DoubleAnimation;
    anim.To = args.NewSize.Width; // the new width of Canvas
 
    // Canvas.Top animation
    anim = storyboard.Children[1] as DoubleAnimation;
    anim.To = args.NewSize.Height; // the new height of Canvas
}

Trigger an animation in XAML rather than in code-behind using an EventTrigger. Note that the BeginStoryboard element can have multiple Storyboard children (in this example, we define only one child):

<!-- EventTrigger defined on the page level using Page.Triggers -->
<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Triggers>
        <EventTrigger>
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="Ellipse1"
                                     Storyboard.TargetProperty="(Canvas.Left)"
                                     From="0" To="300" Duration="0:0:2"
                                     AutoReverse="True"
                                     RepeatBehavior="Forever" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Page.Triggers>
 
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Canvas>
            <Ellipse Name="Ellipse1" Width="50" Height="50" Fill="Green" />
        </Canvas>
    </Grid>
</Page>
<!-- EventTrigger defined on the element level using Ellipse.Triggers -->
<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Canvas>
            <Ellipse Name="Ellipse1" Width="50" Height="50" Fill="Green">
                <Ellipse.Triggers>
                    <EventTrigger>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetName="Ellipse1"
                                                 Storyboard.TargetProperty="(Canvas.Left)"
                                                 From="0" To="300" Duration="0:0:2"
                                                 AutoReverse="True"
                                                 RepeatBehavior="Forever" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Ellipse.Triggers>
            </Ellipse>
        </Canvas>
    </Grid>
</Page>

Oscillate the font size using DoubleAnimation.EasingFunction and ElasticEase. The lower the Springness, the more extreme the effect.

  • Easing functions create non-linear animations.
  • There are 11 classes that derive from EasingFunctionBase.
  • EasingMode property values:
    • EaseOut (default) - the effect is applied at the end of animation.
    • EaseIn - the effect is applied at the beginning of the animation.
    • EaseInOut - the effect is applied to the beginning and the end.

Note that the ElasticEase function returns values outside the range of 0 and 1. It means that the animation could take on values outside the range of its From and To settings. The same is true for BackEase.

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Resources>
        <Storyboard x:Key="Storyboard1">
            <DoubleAnimation Storyboard.TargetName="TextBlock1"
                             Storyboard.TargetProperty="FontSize"
                             EnableDependentAnimation="True"
                             From="1" To="144" Duration="0:0:3">
                <DoubleAnimation.EasingFunction>
                    <ElasticEase EasingMode="EaseOut"
                                 Oscillations="5"
                                 Springiness="3" />
                </DoubleAnimation.EasingFunction>
            </DoubleAnimation>
        </Storyboard>
    </Page.Resources>
 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Name="TextBlock1"
                   Text="Animated Text"
                   FontSize="48"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center" />
        <Button Content="Test" Click="TestButton_Click" VerticalAlignment="Top" HorizontalAlignment="Center" />
    </Grid>
</Page>
using Windows.UI.Xaml.Media.Animation;
...
private void AnimateButton_Click(object sender, RoutedEventArgs e)
{
    // Trigger the Storyboard.
    (this.Resources["Storyboard1"] as Storyboard).Begin();
}

Animate foreground and background colors using ColorAnimation:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Resources>
        <Storyboard x:Key="Storyboard1" RepeatBehavior="Forever" AutoReverse="True">
            <ColorAnimation Storyboard.TargetName="GridBrush1"
                            Storyboard.TargetProperty="Color"
                            From="Navy" To="Yellow" Duration="0:0:2" />
            <ColorAnimation Storyboard.TargetName="TextBlockBrush1"
                            Storyboard.TargetProperty="Color"
                            From="Yellow" To="Navy" Duration="0:0:2" />
        </Storyboard>
    </Page.Resources>
 
    <Grid>
        <Grid.Background>
            <SolidColorBrush x:Name="GridBrush1" />
        </Grid.Background>
 
        <TextBlock Text="Hello!" FontSize="100">
            <TextBlock.Foreground>
                <SolidColorBrush x:Name="TextBlockBrush1" />
            </TextBlock.Foreground>
        </TextBlock>
    </Grid>
</Page>
using Windows.UI.Xaml.Media.Animation;
...
public MainPage()
{
    this.InitializeComponent();
 
    // Trigger the animation when the page is loaded.
    Loaded += (sender, args) =>
    {
        (this.Resources["Storyboard1"] as Storyboard).Begin();
    };
}

Animate a path using PointAnimation. PointAnimation animates properties of type Point. You may not animate Point.X and Point.Y separately as they are not backed up by dependecy properties.

Properties of type Point:

  • EllipseGeometry.Center
  • PathSegment derivatives:
    • ArcSegment.Point
    • BezierSegment.Point1, .Point2, .Point3
    • LineSegment.Point
    • QuadraticBezierSegment.Point1, .Point2
<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Resources>
    </Page.Resources>
 
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <!-- use Canvas to position the path in the center -->
        <Canvas HorizontalAlignment="Center" VerticalAlignment="Center">
            <Path Stroke="Blue" StrokeThickness="5" StrokeLineJoin="Round">
                <Path.Data>
                    <PathGeometry>
                        <!-- line segments: left, bottom, right, top -->
                        <PathFigure StartPoint="0,0">
                            <LineSegment Point="0,100" />
                            <LineSegment Point="50,100" />
                            <LineSegment Point="50,0" x:Name="TopRight" />
                            <LineSegment Point="0,0" x:Name="TopLeft" />
                        </PathFigure>
                    </PathGeometry>
                </Path.Data>
 
                <Path.Triggers>
                    <EventTrigger>
                        <BeginStoryboard>
                            <Storyboard RepeatBehavior="Forever">
                                <PointAnimation Storyboard.TargetName="TopLeft"
                                                Storyboard.TargetProperty="Point"
                                                EnableDependentAnimation="True"
                                                From="0,0" To="0,100"
                                                AutoReverse="True" />
                                <PointAnimation Storyboard.TargetName="TopRight"
                                                Storyboard.TargetProperty="Point"
                                                EnableDependentAnimation="True"
                                                From="50,0" To="50,100"
                                                AutoReverse="True" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </Path.Triggers>
            </Path>
        </Canvas>
    </Grid>
</Page>

Animate an ellipse using a key frame animation (PointAnimationUsingKeyFrames). Key frame animation is useful to apply different animations to the same target property. In this example we target the Center property of EllipseGeometry.

  • A key frame always indicates the desired value of the property at the elapsed time.
  • The duration of an animation is the highest key time in the collection.

Key frame collection classes:

  • PointAnimationUsingKeyFrames (has children of type PointKeyFrame)
  • DoubleAnimationUsingKeyFrames (has children of type DoubleKeyFrame)
  • ColorAnimationUsingKeyFrames (has children of type ColorKeyFrame)

PointKeyFrame classes:

  • DiscretePointKeyFrame
  • LinearPointKeyFrame
  • SplinePointKeyFrame - can speed up or slow down (superseded by EasingPointKeyFrame)
  • EasingPointKeyFrame - animates with an easing function
<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Triggers>
        <EventTrigger>
            <BeginStoryboard>
                <Storyboard>
                    <PointAnimationUsingKeyFrames Storyboard.TargetName="Ellipse1"
                                                  Storyboard.TargetProperty="Center"
                                                  EnableDependentAnimation="True"
                                                  RepeatBehavior="Forever">
                        <!-- initialise the animation -->
                        <DiscretePointKeyFrame KeyTime="0:0:0" Value="100,100" />
 
                        <!-- this animation takes 2 sec -->
                        <LinearPointKeyFrame KeyTime="0:0:2" Value="500,500" />
 
                        <!-- this animation takes 0.1 sec -->
                        <LinearPointKeyFrame KeyTime="0:0:2.1" Value="500,100" />
 
                        <!-- this animation takes 2 sec -->
                        <LinearPointKeyFrame KeyTime="0:0:4.1" Value="100,500" />
 
                        <!-- this animation takes 0.1 sec -->
                        <!-- 4.2 sec is the duration of the entire animation -->
                        <LinearPointKeyFrame KeyTime="0:0:4.2" Value="100,100" />
                    </PointAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Page.Triggers>
 
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Path Fill="Blue">
            <Path.Data>
                <EllipseGeometry x:Name="Ellipse1" RadiusX="24" RadiusY="24" />
            </Path.Data>
        </Path>
    </Grid>
</Page>

Use two key frame animations of type PointAnimationUsingKeyFrames to animate the StartPoint and EndPoint properties of a LinearGradientBrush. Note that we need to set the EnableDependentAnimation property to True in order to refresh UI:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Triggers>
        <EventTrigger>
            <BeginStoryboard>
                <Storyboard RepeatBehavior="Forever">
                    <PointAnimationUsingKeyFrames Storyboard.TargetName="GradientBrush1"
                                                  Storyboard.TargetProperty="StartPoint"
                                                  EnableDependentAnimation="True">
                        <LinearPointKeyFrame KeyTime="0:0:0" Value="0,0" />
                        <LinearPointKeyFrame KeyTime="0:0:1" Value="1,0" />
                        <LinearPointKeyFrame KeyTime="0:0:2" Value="1,1" />
                        <LinearPointKeyFrame KeyTime="0:0:3" Value="0,1" />
                        <LinearPointKeyFrame KeyTime="0:0:4" Value="0,0" />
                    </PointAnimationUsingKeyFrames>
 
                    <PointAnimationUsingKeyFrames Storyboard.TargetName="GradientBrush1"
                                                  Storyboard.TargetProperty="EndPoint"
                                                  EnableDependentAnimation="True">
                        <LinearPointKeyFrame KeyTime="0:0:0" Value="1,1" />
                        <LinearPointKeyFrame KeyTime="0:0:1" Value="0,1" />
                        <LinearPointKeyFrame KeyTime="0:0:2" Value="0,0" />
                        <LinearPointKeyFrame KeyTime="0:0:3" Value="1,0" />
                        <LinearPointKeyFrame KeyTime="0:0:4" Value="1,1" />
                    </PointAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Page.Triggers>
 
    <Grid>
        <Grid.Background>
            <LinearGradientBrush x:Name="GradientBrush1">
                <GradientStop Offset="0" Color="Red" />
                <GradientStop Offset="1" Color="Blue" />
            </LinearGradientBrush>
        </Grid.Background>
    </Grid>
</Page>

Animate colors using ColorAnimationUsingKeyFrames:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Triggers>
        <EventTrigger>
            <BeginStoryboard>
                <Storyboard RepeatBehavior="Forever">
                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Brush1"
                                                  Storyboard.TargetProperty="Color">
                        <DiscreteColorKeyFrame KeyTime="0:0:0" Value="#FF0000" /> <!-- initialise -->
                        <LinearColorKeyFrame KeyTime="0:0:1" Value="#FFFF00" />
                        <LinearColorKeyFrame KeyTime="0:0:2" Value="#00FF00" />
                        <LinearColorKeyFrame KeyTime="0:0:3" Value="#00FFFF" />
                        <LinearColorKeyFrame KeyTime="0:0:4" Value="#0000FF" />
                        <LinearColorKeyFrame KeyTime="0:0:5" Value="#FF00FF" />
                        <LinearColorKeyFrame KeyTime="0:0:6" Value="#FF0000" /> <!-- the animation is 6s long -->
                    </ColorAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Page.Triggers>
 
    <Grid>
        <Grid.Background>
            <SolidColorBrush x:Name="Brush1" />
        </Grid.Background>
    </Grid>
</Page>

Animate a property of an object using ObjectAnimationUsingKeyFrames. Here, we switch the Visibility property of an ellipse between Visible and Collapsed.

  • DiscreteObjectKeyFrame is the only class that derives from ObjectKeyFrame. It means that it is the only class that can be used with ObjectAnimationUsingKeyFrames.
  • Object animations are used mostly for targeting properties of enum types or Brush types in control templates.
<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Triggers>
        <EventTrigger>
            <BeginStoryboard>
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames
                        Storyboard.TargetName="Ellipse1"
                        Storyboard.TargetProperty="Visibility"
                        RepeatBehavior="Forever">
                        <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="Visible" />
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="Collapsed" />
                        <!-- this key frame sets the length of the animation -->
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="Visible" />
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Page.Triggers>
 
    <Grid>
        <Ellipse Name="Ellipse1" Fill="Blue" Width="90" Height="90" />
    </Grid>
</Page>

Animate the Fill property of an ellipse using ObjectAnimationUsingKeyFrames. Here, each key frame provides a different brush from a StaticResource:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Triggers>
        <EventTrigger>
            <BeginStoryboard>
                <Storyboard>
                    <!-- Change the Fill property with predefined brushes -->
                    <ObjectAnimationUsingKeyFrames
                        Storyboard.TargetName="Ellipse1"
                        Storyboard.TargetProperty="Fill"
                        RepeatBehavior="Forever">
                        <DiscreteObjectKeyFrame KeyTime="0:0:0" 
                            Value="{StaticResource ApplicationPageBackgroundThemeBrush}" />
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.2" 
                            Value="{StaticResource ApplicationForegroundThemeBrush}" />
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.4" 
                            Value="{StaticResource ApplicationPressedForegroundThemeBrush}" />
                        <DiscreteObjectKeyFrame KeyTime="0:0:0.6" 
                            Value="{StaticResource ApplicationPageBackgroundThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Page.Triggers>
 
    <Grid>
        <Ellipse Name="Ellipse1" Fill="Blue" Width="90" Height="90" />
    </Grid>
</Page>

Create an animation in code. The Storyboard and DoubleAnimation objects can be created once and reused (when the animation target is always the same object) or they can be created anew as needed.

DoubleAnimation anim = new DoubleAnimation
{
    EnableDependentAnimation = true,
    To = 96,
    Duration = new Duration(new TimeSpan(0, 0, 1)), // the default value for Duration is Automatic
    //Duration = Duration.Automatic, // 1 second
    AutoReverse = true,
    RepeatBehavior = new RepeatBehavior(3)
};
 
// Set the target object. We use Storyboard.SetTarget rather than Storyboard.SetTargetName which corresponds 
// to Storyboard.TargetName in XAML because we are setting the target *object* not the target *name*.
Storyboard.SetTarget(anim, sender as Button);
 
// Set a property on the target object (=Storyboard.TargetProperty in XAML).
Storyboard.SetTargetProperty(anim, "FontSize");
 
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(anim);
storyboard.Begin(); // run the animation

Examples of theme animations:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 
    <Page.Resources>
        <Storyboard x:Key="popIn">
            <PopInThemeAnimation TargetName="Button1" />
        </Storyboard>
        <Storyboard x:Key="popOut">
            <PopOutThemeAnimation TargetName="Button1" />
        </Storyboard>
        <Storyboard x:Key="fadeIn">
            <FadeInThemeAnimation TargetName="Button1" />
        </Storyboard>
        <Storyboard x:Key="fadeOut">
            <FadeOutThemeAnimation TargetName="Button1" />
        </Storyboard>
        <Storyboard x:Key="swipeBack">
            <SwipeBackThemeAnimation TargetName="Button1" />
        </Storyboard>
        <Storyboard x:Key="swipeHint">
            <SwipeHintThemeAnimation TargetName="Button1" />
        </Storyboard>
        <Storyboard x:Key="dragItem">
            <DragItemThemeAnimation TargetName="Button1" />
        </Storyboard>
        <Storyboard x:Key="dropTarget">
            <DropTargetItemThemeAnimation TargetName="Button1" />
        </Storyboard>
    </Page.Resources>
 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <ListView Width="200" HorizontalAlignment="Left" 
                  SelectionChanged="ListView_SelectionChanged">
            <x:String>popIn</x:String>
            <x:String>popOut</x:String>
            <x:String>fadeIn</x:String>
            <x:String>fadeOut</x:String>
            <x:String>swipeBack</x:String>
            <x:String>swipeHint</x:String>
            <x:String>dragItem</x:String>
            <x:String>dropTarget</x:String>
        </ListView>
 
        <!-- animation target -->
        <Button x:Name="Button1" Content="TESTING" FontSize="40" Padding="16"
                HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Page>
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs args)
{
    if (args.AddedItems.Count > 0)
    {
        string key = args.AddedItems[0] as string;
        Storyboard storyboard = this.Resources[key] as Storyboard;
        storyboard.Begin();
    }
}

A theme animation triggered using XML:

<Page x:Class="TestApp.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <TextBlock x:Name="HelloTextBlock" Text="Hello!" Padding="20" FontSize="40">
            <TextBlock.Triggers>
                <EventTrigger RoutedEvent="FrameworkElement.Loaded">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <FadeOutThemeAnimation TargetName="HelloTextBlock" />
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </TextBlock.Triggers>
        </TextBlock>
    </Grid>
</Page>

Example: Apply a theme transition to child elements of a Grid:

<Grid>
    <Grid.ChildrenTransitions>
        <TransitionCollection>
            <EntranceThemeTransition/>
        </TransitionCollection>
    </Grid.ChildrenTransitions>
</Grid>  

Example: Use a Storyboard as a way to delay an operation:

Storyboard sb = new Storyboard();
...
// define
sb.Duration = new Duration(TimeSpan.FromSeconds(1));
sb.Completed += (s, e) =>
{
    // ... perform a delayed operation here
};
...
// execute
sb.Stop();
sb.Seek(TimeSpan.Zero);
sb.Begin();

Links:

notes/uwp/animation.txt · Last modified: 2017/04/12 by leszek