XamlFlair

by XamlFlair

XamlFlair / XamlFlair

XamlFlair is an animation library for UWP, WPF, and Uno, built to facilitate Xaml animations using o...

280 Stars 18 Forks Last release: Not found MIT License 171 Commits 0 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

XamlFlair

The goal of the XamlFlair library is to ease the implementation of common animations and allow a developer to easily add a single or combined set of animations with just a few lines of Xaml.

Sample App

Contents

Install from Nuget

| Platform | Package | NuGet | | -------- | -------- | ------- | | UWP | XamlFlair.UWP | UWPNuGetShield | | WPF | XamlFlair.WPF | WPFNuGetShield | | Uno | XamlFlair.Uno | UNONuGetShield |

To install XamlFlair, run the following command in the Package Manager Console:

UWP:

Install-Package XamlFlair.UWP

Your app must target a minimum of Windows 10 version 1809 (build 17763)

WPF:

Install-Package XamlFlair.WPF

Uno:

Install-Package XamlFlair.Uno

Your UWP app must target a minimum of Windows 10 version 1809 (build 17763)

Features Overview

Feature

UWP WPF UWP (Uno) iOS (Uno) Android (Uno) *Wasm (Uno) EXPERIMENTAL *
Animation System Composition Storyboards Storyboards Storyboards Storyboards Storyboards
Composite Transforms X X X X X X
DefaultAnimations.xaml - X - - - -

TransformOn
| - | X | - | - | - | - Compound Animations | X | X | X | X | X | X Relative Translations | X | X | X | X | X | X Repeating Animations | X | X | X | X | X | X Events & Bindings | X | X | X | X | X | X Primary/Secondary Completion Commands | X | X | X | X | X | X
StartWith
| X | X | X | X | X | X
AllowOpacityReset
| - | X | - | - | - | -
ClipToBounds
| X | N/A | X | X | X | X Animated Lists | X | X | X | X | X | X Blur Effect | X | X | - | - | - | - Saturation Effect | X | - | - | - | - | - Tint Effect | X | - | - | - | - | - Color Animations | - | X | X | X | X | X Debugging Animations | X | X | X | X | X | -

Note: A standard UWP app and a Uno app (UWP head) are different when it comes to XamlFlair. A standard UWP app referencing

XamlFlair.UWP
will use Composition-based animations behind the scenes. An Uno app (including the UWP head) that references
XamlFlair.Uno
will all use Storyboarding behind the scenes.

Basic Concepts

The basic concept of XamlFlair is based on animations that are categorized as From and To. Any UI element that consists of a From animation will start with one or more arbitrary values, and complete using the default value of the corresponding property. Any UI element that consists of a To animation will start in its current state and animate to one or more arbitrary values.

Example of a From animation (a UI element translating to the default value of a Translation (0)):

From animation

Example of a To animation (a UI element sliding away from its current state):

To animation

NOTE: It's important to note there is an exception to this rule for Color Animations, which is explained in the Base Animation Types section.

Usage

To begin, you need to have the following Xaml namespace reference:

UWP and Uno:

xml
xmlns:xf="using:XamlFlair"

WPF:

xml
xmlns:xf="clr-namespace:XamlFlair;assembly=XamlFlair.WPF"

From here on, it's a simple matter of setting an attached property to any

FrameworkElement
that needs an animation:

Note: If your

FrameworkElement
defines a
CompositeTransform
in your Xaml, it will be altered during the animation process.

Note: The use of

StaticResource
is to reference global common animations, which is discussed in the next section.

Base Animation Types

Fade

Fade animation

Warning: Be careful when animating

FadeTo
since the element remains in the Visual Tree if the
Visibility
is
Visible
. There may be cases where you'll need to manually manage
IsHitTestVisible
to allow the user to tap through the element.

Translate

Translation animation

Scale

Scale animation

Rotate

Rotation animation

Blur (UWP and WPF only)

Blur animation

Saturate (UWP only)

Saturate animation

Tint (UWP only)

Tint animation

Color (WPF and Uno only)

Color animation

Note: It's important to note when animating a color using a From animation, the color will animate from a specified value to its current state instead of a default value.

The following lists some notable default values when working with XamlFlair:

  • Kind: FadeTo
  • Duration (milliseconds): 500
  • Easing: Cubic
  • Easing Mode: EaseOut
  • TransformCenterPoint: (0.5, 0.5)
  • Event: Loaded
  • InterElementDelay (milliseconds): 25 (List controls only)
  • TransformOn: Render (WPF only)
  • Saturation: 0.5 (UWP only)
  • Tint: Transparent (UWP only)

Color Animations (WPF And Uno Only)

Color animations require some attention since they are slightly different than the other base type animations. When using either

ColorTo
and
ColorFrom
, the following must be done:
  • You can only animate the following properties:
    Control.Background
    ,
    Control.Foreground
    ,
    Control.BorderBrush
    ,
    TextBlock.Foreground
    ,
    Shape.Fill
    ,
    Shape.Stroke
  • Make sure to set a brush on the corresponding property you intend to animate
  • You must also specify the target property using
    ColorOn

The following example will animate the Rectangle's

Fill
from RoyalBlue to DarkGreen:

Overriding the Global Default Values

If you have the need to globally change one of the default animation values (for example, having a default

Duration
of 750 instead of 500), you can call the
OverrideDefaultSettings
function in your app's initialization code. The following example changes the default values for
Duration
and
Easing
:
XamlFlair.Animations.OverrideDefaultSettings(
    duration: 750,
    easing: EasingType.Quadratic);

Therefore, with the sample code above, every animation will run for 750ms with a quadratic easing.

Using a
ResourceDictionary
for Base Settings

All common animations should be placed in a global

ResourceDictionary
(ex:
Animations.xaml
) and used where needed throughout the app. The goal is to consolidate all the animations into one file with meaningful names so that any developer can understand exactly what animation is applied to a
FrameworkElement
. Here's a small example of what it looks like:
<double x:key="PositiveOffset">50</double>
<double x:key="NegativeOffset">-50</double>
<double x:key="SmallScaleFactor">0.75</double>
<double x:key="LargeScaleFactor">1.25</double>

<animationsettings x:key="FadeIn" kind="FadeFrom" opacity="0"></animationsettings>

<animationsettings x:key="FadeOut" kind="FadeTo" opacity="0"></animationsettings>

<!-- Scale to a larger value -->
<animationsettings x:key="Expand" kind="ScaleXTo,ScaleYTo" scalex="{StaticResource LargeScaleFactor}" scaley="{StaticResource LargeScaleFactor}"></animationsettings>

<!-- Scale from a larger value -->
<animationsettings x:key="Contract" kind="ScaleXFrom,ScaleYFrom" scalex="{StaticResource LargeScaleFactor}" scaley="{StaticResource LargeScaleFactor}"></animationsettings>
.
.
.
</resourcedictionary>

To setup this set of pre-configured

AnimationSettings
already available in your app, perform the following steps:
  1. Right-click on your project, then click Add > New Item...
  2. Choose Resource Dictionary and name it
    Animations.xaml
  3. In your
    App.xaml
    , add the following:
    
        
            
                
            
        
    
  1. In
    Animations.xaml
    , copy & paste the contents from the corresponding links below:

Your app now has a global set of common animations ready to use.

Default Animations (WPF Only)

Alternatively to creating your own

ResourceDictionary
containing your custom
AnimationSettings
, XamlFlair provides some Default Animations.

To reference these Default Animations in your app, perform the following steps:

  1. In your
    App.xaml
    , add the following
    
        
            
                
            
        
    

Where you should replace the merged dictionary URI accordling,


Your app now has a global set of Default animations ready to use.

TransformOn
Property (WPF Only)

Using the

TransformOn
property, you can target which type of
RenderTransform
to apply to your animation. Available options are
Render
and
Layout
. When nothing is specified, the default vale is
Render
. Here's an example of the two:

TransformOn animation

Combining Animations

Animations can be combined, and as previously mentioned, any of these combined animations that are commonly used should be placed in the global

ResourceDictionary
(ex:
Animations.xaml
):
    .
    .
    .
    

<animationsettings x:key="FadeInAndSlideFromTop" kind="FadeFrom,TranslateYFrom" opacity="0" offsety="{StaticResource NegativeOffset}"></animationsettings>

<animationsettings x:key="FadeInAndGrow" kind="FadeFrom,ScaleXFrom,ScaleXFrom" opacity="0" scalex="{StaticResource SmallScaleFactor}" scaley="{StaticResource SmallScaleFactor}"></animationsettings>

<animationsettings x:key="FadeInAndGrowHorizontally" kind="FadeFrom,ScaleXFrom" opacity="0" scalex="{StaticResource SmallScaleFactor}"></animationsettings>
.
.
.
</resourcedictionary>

This demonstrates a combined animation of a

FadeFrom
and
TranslateFrom
:

Fade and translation animation

This demonstrates a combined animation of a

FadeFrom
,
TranslateFrom
, and
ScaleFrom
:

Fade, translation, and scale snimation

Overriding Values

Animations can have their settings overridden directly on the

FrameworkElement
. This is commonly done to alter values for Delay and Duration so that we don't over-populate the
Animations.xaml
file with repeated resources. To achieve overriding, use the
Animate
markup extension paired with the
BasedOn
property:

Relative Translations on X and Y Axes

Since hard-coded values for

OffsetX
and
OffsetY
can be limiting (such as in cases when dealing with resizable windows), both
OffsetX
and
OffsetY
support star-based values:

A star-based value will calculate the offset based on the current

ActualWidth
and/or
ActualHeight
value(s) of the
FrameworkElement
, therefore it's important that the element has executed its
Loaded
event. If
ActualWidth
and/or
ActualHeight
are not yet calculated, the offset value will try to be based on
Width
and/or
Height
.

Compound Animations

A compound animation is simply a multi-step animation using the

CompoundSettings
class. Each inner animation executes once the previous one completes, hence they're sequential animations:

Compound animation

    
        
        
        
    

Note:

CompoundSettings
support the
Event
property, which is discussed in a later section.

Repeating Animations

An animation can be repeated by using the

IterationBehavior
and
IterationCount
properties (default values of
Count
and
1
respectively).

Compound animation

The following demonstrates how to run an animation only 5 times:


The following demonstrates how to run an animation indefinitely:


Also note that it is also possible to repeat a Compound animation. For example, using the compound animation (named Progress) from the previous section:


Warning: When using repeating animations, you cannot set a

Secondary
animation on the element.

Events and Bindings

By default, all animations execute once the UI element fires its

Loaded
event. This behavior can be overridden by setting the
Event
property.
Event
can be one of the following values:
  • Loaded (default value)
  • None
  • Visibility (triggers only when Visibility == Visible)
  • DataContextChanged
  • PointerOver
  • PointerExit
  • GotFocus
  • LostFocus

When specifying

None
, you will manually need to trigger your animations using the
PrimaryBinding
or
SecondaryBinding
properties. These properties are of type
bool
and expect a value of
True
in order to execute the corresponding animation. The following is an example of triggering an animation based off the
IsChecked
of the CheckBox control:

The above animation will only execute when the

IsChecked
is
True
. If
None
was not specified for
Event
, the animation would then execute on
Loaded
and on the binding.

When working with both

PrimaryBinding
and
SecondaryBinding
together (based on the same boolean value), it may be cleaner and simpler to use
CombinedBinding
.
CombinedBinding
simply acts as both
PrimaryBinding
and
SecondaryBinding
together. Instead of the following:

You would use it as such:

By using

CombinedBinding
in this way, it saves on having to use a converter for the inverse boolean value, which is handled internally.

Primary and Secondary Completion Commands

There may be scenarios where you may want to execute an

ICommand
when an animation completes. In such a case, two properties exist:
PrimaryCompletionCommand
and
SecondaryCompletionCommand
.

In the following example, the command named MyCustomCommand will execute once the primary animation completes:


Using the
StartWith
Property

There will be cases when you will need your UI element to start in a specific state, for example, the element needs to be shrunk before its animation executes. This is achieved using the

StartWith
property:

In the above example, since the element is scaling from the bottom, but with a delay, we need to start in the scaled position, so we use the

StartWith
property to set its initial state. What
StartWith
essentially does is setup the initial values on the element as soon as it has loaded.

Using the
AllowOpacityReset
Property (WPF Only)

The .Net documentation states the following:

In some cases, it might appear that you can't change the value of a property after it has been animated. ...you must stop the animation from influencing the property.

There may be cases when you animate the opacity, in which the opacity animation suddenly resets it's value instead of animating, or doesn't behave as you intend. In cases, you may need to set

AllowOpacityReset = False
(the default value of
AllowOpacityReset
is
True
) to achieve the intended behavior:

Using the
ClipToBounds
Property (UWP And Uno Only)

A helpful property that exists in WPF,

ClipToBounds
is a helpful property that exists in WPF, but unfortunately not in UWP. Therefore, it has been added in XamlFlair due to its ease of use and handiness. To clip child content to the bounds of the containing element, simply set
ClipToBounds
to
True
on the containing element:
.
.
.

Debugging Animations

In order to debug an animation and step into the code, use the

EnableDebugging
property. Debugging is possible due to the inclusion of the SourceLink library. Please be sure to do the following:

SourceLink1 SourceLink2


The following tables explains the enumeration values:

Enum Value

Description

None
InitializeElement
RunAnimation

Logging Animations

The XamlFlair library abstracts its logging using

Microsoft.Extensions.Logging.Abstractions
. Below is a logging example using Serilog in a UWP app:
public App()
{
    this.InitializeComponent();
    .
    .
    .
    // Setup the Serilog logger
    Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Debug()
        .WriteTo.Debug()
        .CreateLogger();

// Initalie the XamlFlair loggers using the LoggerFactory (with Serilog support)
XamlFlair.Animations.InitializeLoggers(new LoggerFactory().AddSerilog());

}

To output the values of one or more animations, simply set

Debug
to the
EnableLogging
property on the target
FrameworkElement
:

Doing so will provide you with the following similar console output (differs slightly for WPF):

Element = Windows.UI.Xaml.Controls.Button
Kind = FadeFrom, TranslateFrom
TargetProperty = Translation
Duration = 500
Delay = 0
Opacity = 0
OffsetX = 0
OffsetY = 50
OffsetZ = 0
ScaleX = 1
ScaleY = 1
ScaleZ = 1
Rotation = 0
Blur = 0
TransformCenterPoint = 0.5,0.5
Easing = Cubic
EasingMode = EaseOut

As each storyboard executes, it's kept in an internal list until it completes (or gets stopped). To output this internal list, temporarily add the following in your app startup code:

Animations.EnableActiveTimelinesLogging = LogLevel.Debug;

Doing so will provide you with the following similar console output:

---------- ALL ACTIVE TIMELINES --------
Active timeline removed at 12:42:26:43222

Element = Button, Key = d69f826a-1978-4a4e-b516-4a6b0469238b, ElementGuid = 195d8c13-1dd7-4fef-a7f3-fc78bdab1cd7 State = Running, IsSequence = False, IsIterating = False, IterationBehavior = Count, IterationCount = 0


---------- ACTIVE TIMELINE -------- Guid d69f826a-1978-4a4e-b516-4a6b0469238b - Updated state to: Completed at 12:42:26:88616


---------- ALL ACTIVE TIMELINES -------- Active timeline removed at 12:42:26:89614

NO ACTIVE TIMELINES!

Currently, all the logging in XamlFlair mentioned above is logged at

LogLevel.Debug

ListViewBase
(UWP and Uno) and
ListBox
-based (WPF) Animations

ListView item animations

In order to properly implement item animations on list items, it was not enough to simply create attached properties against the ListViewBase (UWP) and ListBox (WPF) controls. Instead, inherited controls were created:

AnimatedListView
and
AnimatedGridView
for UWP, and
AnimatedListView
and
AnimatedListBox
for WPF, all available from the
XamlFlair.Controls
namespace:

UWP and Uno namespace:

xml
xmlns:xfc="using:XamlFlair.Controls"

WPF namespace:

xml
xmlns:xfc="clr-namespace:XamlFlair.Controls;assembly=XamlFlair.WPF"

Animating items in lists is slightly different than animating a typical UI element. The main reason for this difference is that the

Event
value on the corresponding
AnimationSettings
cannot be changed from its default value. Therefore the following is invalid:

List item animations, by default, animate based on the

Loaded
event of each visible item, and also based on an update to the
ItemsSource
property of the list control. In order to disable these default behaviors, the following two properties can be used independently:

<animatedlistview itemssource="Binding SampleDataList" xf:animations.animateonitemssourcechange="False" ...>

By default, item animations have a delay of 25 milliseconds between each item. This value can be changed using the

InterElementDelay
property:

Just like

PrimaryBinding
and
SecondaryBinding
, item animations can be triggered by a binding with the use of the
ItemsBinding
property:

Warning (UWP only): Be aware that if you have any

ItemContainerTransitions
set on the
AnimatedListView
or
AnimatedGridView
, they will be cleared. This is done to avoid conflicting item animations.

Note (Uno only): To avoid any flickers on item animations, there is currently a constraint in place:

Items
animation must contain a
FadeFrom
.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.