How To Use Keyframe Animations
You can use a keyframe animation to change one or more control properties following a timeline. The keyframes are defined in Avalonia UI styles with cue points along the duration of the animation, and set the intermediate values of the properties at a point in time.
The property values between keyframes are set following the profile of an easing function. The default easing function is a straight-line interpolation.
The animation is triggered to start, and then can run any number of times, in either direction. There are also options to delay the start of the animation, and to repeat it.
If you are familiar with keyframe animations keyframe work in CSS, you will recognise the similarity with how they are done in in Avalonia UI.
Example
You define a keyframe animation using styles.
To revise how Avalonia UI uses styles, see the concept here.
Follow this procedure to define a simple color fade animation using XAML:
- Create a styles collection at your chosen level.
- Add a style to the collection with a selector that can target the control you want to animate.
- Add a
Setter
element to define the property that you wan the animation to change. In this example<Setter Property="Fill" Value="Red"/>
- Add a
Style.Animations
element to contain your animation. - Add an
Animation
element and set itsDuration
attribute. This is in the format"Hours:Minutes:Seconds"
. - Now define the keyframes for the animation. This example uses cues at 0% and 100%.
- Add
Setter
elements to each keyframe for value of the fill opacity. This example animates between opacity values of 0.0 and 1.0.
The finished code will look like this:
<Window xmlns="https://github.com/avaloniaui">
<Window.Styles>
<Style Selector="Rectangle.red">
<Setter Property="Fill" Value="Red"/>
<Style.Animations>
<Animation Duration="0:0:3">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0.0"/>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="1.0"/>
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Window.Styles>
<Rectangle Classes="red" Width="100" Height="100"/>
</Window>
The resulting animation looks like this:
The animation runs as soon as the rectangle control is loaded and can be selected by the style. In fact it runs in the preview pane as well!
Animate Two Properties
This example shows you how to animate two properties on the same timeline.
<Window.Styles>
<Style Selector="Rectangle.red">
<Setter Property="Fill" Value="Red"/>
<Style.Animations>
<Animation Duration="0:0:3" IterationCount="4">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0.0"/>
<Setter Property="RotateTransform.Angle" Value="0.0"/>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="1.0"/>
<Setter Property="RotateTransform.Angle" Value="90.0"/>
</KeyFrame>
</Animation>
</Style.Animations>
</Style>
</Window.Styles>
The red rectangle is faded-in and rotated at the same time.
Configuring animation
Delay
You can add a delay to the start of an animation by setting the delay attribute of the animation element. For example:
<Animation Duration="0:0:1"
Delay="0:0:1">
...
</Animation>
Repeat
You can make an animation repeat for a set number of times, or indefinitely. To repeat for a finite number of iterations set the IterationCount
attribute on the animation element like this:
<Animation IterationCount="5">
...
</Animation>
To repeat an animation indefinitely, use the special "INFINITE"
value. For example:
<Animation IterationCount="INFINITE">
...
</Animation>
Playback Direction
By default an animation plays forward. That is it follows the profile of the easing function from left to right. You can alter this behavior by setting the PlaybackDirection
attribute on the animation element. For example:
<Animation IterationCount="9" PlaybackDirection="AlternateReverse">
...
</Animation>
The following table describes the options:
Value | Description |
---|---|
Normal | (Default) The animation is played forwards. |
Reverse | The animation is played in reverse direction. |
Alternate | The animation is played forwards first, then backwards. |
AlternateReverse | The animation is played backwards first, then forwards. |
Fill Mode
The fill mode attribute of an animation defines how the properties being set will persist after it runs, or during any gaps between runs. For example:
<Animation IterationCount="9" FillMode="Backward">
...
</Animation>
The following table describes the options:
Value | Description |
---|---|
None | Value will not persist after animation nor the first value will be applied when the animation is delayed. |
Forward | The last interpolated value will be persisted to the target property. |
Backward | The first interpolated value will be displayed on animation delay. |
Both | Both Forward and Backward behaviors will be applied. |
Easing Function
An easing function defines how a property is varied over time during an animation.
The default easing function is linear (above left), but you use another pattern by setting the name of the desired function in the easing attribute. For example to use the 'bounce ease in' function (above right):
<Animation Duration="0:0:1"
Delay="0:0:1"
Easing="BounceEaseIn">
...
</Animation>
For a full list of the Avalonia UI easing functions, see the reference here.
You can also add your own custom easing function class like this:
<Animation Duration="0:0:1"
Delay="0:0:1">
<Animation.Easing>
<local:YourCustomEasingClassHere/>
</Animation.Easing>
...
</Animation>
Running animation from the code behind
In some situations, developers need more flexibility with animation lifetime, comparing to the XAML style selectors. Easiest would be to define animation in the Resources
dictionary.
While defining Animation
this way, it's important to specify both x:Key
and x:SetterTargetType
. First one will be used to access animation by the key, and second helps compiler to create strongly typed setters.
<Window xmlns="https://github.com/avaloniaui">
<Window.Resources>
<Animation x:Key="ResourceAnimation"
x:SetterTargetType="Rectangle"
Duration="0:0:3">
<KeyFrame Cue="0%">
<Setter Property="Opacity" Value="0.0"/>
</KeyFrame>
<KeyFrame Cue="100%">
<Setter Property="Opacity" Value="1.0"/>
</KeyFrame>
</Animation>
</Window.Resources>
<Rectangle x:Name="Rect" />
</Window>
Now, this animation can be accessed and executed in a custom code behind handler.
var animation = (Animation)this.Resources["ResourceAnimation"];
// Running XAML animation on the Rect control.
await animation.RunAsync(Rect);
RunAsync
returns a task which is completed with the animation. If animation is infinite/repeating, task will never end, unless cancelled externally by passing CancellationToken
to the RunAsync method.
While it's easier to define animations in XAML, it's also possible to do completely in C# code. It's possible to create an instance of Animation
type, and populate key frames collection.