Skip to main content
September 16, 2016
Mobile

Animations with the Visual Layer



When the layout of your Universal Windows Platform (UWP) app changes, there is often a slight pause as your app rearranges content to fit the new window size or orientation. Composition APIs let you create smooth-as-butter animations between these states so your layout changes won’t jar your users. After all, layout changes are a basic fact of the app life cycle. It doesn’t mean we can’t handle them gracefully.

image1

Layout animations aren’t completely new, of course. UWP has always allowed you to hook up XAML transitions. These animations have tended to be, let’s just say, somewhat limited. By using implicit animations in the Visual Layer, however, you can have access to low-level animations that run at 60 frames a second in a separate process and all the freedom you need to create the layout animations you want.

Implicit versus Explicit animations

So what exactly is an implicit animation? This is best understood by contrasting it with explicit animations. Explicit animations are animations that you start running yourself in code-behind by calling a method like StartAnimation on a Visual.

For instance, here’s an example of a gear animation and the code used to get it started.

image2

[code]

_gearMotionScalarAnimation.Duration = TimeSpan.FromSeconds(secondsPerRotation);
_gearVisuals.First().StartAnimation("RotationAngleInDegrees", _gearMotionScalarAnimation);

[/code]

Implicit animations, on the other hand, are configured and then triggered by property changes. There’s a fire-and-forget quality to implicit animations. All you have to do is wire them up and they will just keep working for you, getting recreated and then cleaned up every time the trigger fires.

Here’s how you create and configure an implicit animation in four easy steps:

  1. Create an implicit animation collection.
  2. Create the animation or group of animations.
  3. Associate the animation value to a trigger key in the collection.
  4. Add the collection to your Visual’s ImplicitAnimations property.

The following code is used to create the fruit animations in the animated GIF at the top of this post:

[code lang=”csharp”]

// Create an implicit animation collection (just one member in this case)
var implicitAnimationCollection = _compositor.CreateImplicitAnimationCollection();

// Create the animation
var offsetKeyFrameAnimation = _compositor.CreateVector3KeyFrameAnimation();
offsetKeyFrameAnimation.Target = "Offset";

// Final Value signifies the target value to which the visual will animate
// in this case it will be defined by new offset
offsetKeyFrameAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue");
offsetKeyFrameAnimation.Duration = TimeSpan.FromSeconds(3);

// Associate the animation to the trigger
implicitAnimationCollection["Offset"] = offsetKeyFrameAnimation;

// Finally, add the implicit animation to individual Visuals
foreach (var child in _root.Children)
{
child.ImplicitAnimations = implicitAnimationCollection;
}

[/code]

There are two things worth noting about this code:

  • First, only one trigger property is being used, Offset, so the ImplicitAnimationCollection has only one member.
  • Second, the animation uses the Offset property as a trigger, but also uses the Offset property for the animation itself. This is actually pretty common since you will usually want to animate the same property that sets off the transition – for instance, if an element’s scale or rotation changes you would want to create a transition animation between the start and end scale sizes or the start and end rotations.

For extra visual flair you could also decide to have a change in a Visual’s Offset trigger more than one animation – for instance, a position animation as well as a bit of spinning and pulsing. Go to the Windows UI Dev Labs GitHub repository for the full source code for this implicit animations sample.

Using implicit animations as layout animations

In order to apply implicit animations to your XAML layout, the only additional step you need to do, beyond what has been covered in the previous section, is to grab the backing Visuals for any UIElements you intend to animate.

image3

The Layout Animations demo from the Windows UI Dev Labs Sample Gallery on GitHub is basically a GridView control with several images in its Items collection.

[code lang=”xml”]

<GridView x:Name="gridView" ContainerContentChanging="gridView_ContainerContentChanging">
<GridView.Items>
<Image Source="1.jpg" Width="235" Height="200" Stretch="UniformToFill"/>
<Image Source="2.jpg" Stretch="UniformToFill"/>
<Image Source="3.jpg" Stretch="UniformToFill"/>
<Image Source="4.jpg" Stretch="UniformToFill"/>
. . .
</GridView.Items>
</GridView>

[/code]

Whenever the XAML page is resized, images inside the GridView are automatically shifted around by the underlying framework, altering the Offset property of each of the Visuals as it is moved from one position to another.
Here’s how you create and configure an implicit animation and add it to XAML elements in five easy steps:

  1. Create an implicit animation collection.
  2. Create the animation.
  3. Associate the animation value to a trigger key in the collection.
  4. In the ContainerContentChanging event handler, use the interop method GetElementVisual to peel of the backing Visual from a UIElement.
  5. Add the collection to your backing Visual’s ImplicitAnimations property.

The first three steps can all be done in the page’s constructor.

[code]

_compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;

// Create ImplicitAnimations Collection.
_elementImplicitAnimation = _compositor.CreateImplicitAnimationCollection();

// Define trigger and animation that should play when the trigger is triggered.
_elementImplicitAnimation["Offset"] = createOffsetAnimation();

[/code]

In the Layout Animations demo, the final two steps are completed in the GridView’s ContainerContentChanging event handler.

[code lang=”csharp”]

private void gridView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
var photo = args.ItemContainer;

var elementVisual = ElementCompositionPreview.GetElementVisual(photo);
elementVisual.ImplicitAnimations = _elementImplicitAnimation;
}

[/code]

It really is that simple to add fast, fluid and beautiful layout animations to your XAML page with the Visual layer.

Connected animations

For navigation transitions between pages, the Visual Layer provides a different mechanism known as connected animations to help you make your UI sweeter. Connected animations help the user stay oriented when she is performing common tasks such as context switching from a list of items to a details page.

image4

You can download the full source for this connected animations sample on GitHub.

Wrapping up

The visual power being made available to developers through the Composition APIs have basically always been a part of the UI Frameworks. They just haven’t been accessible until now. Think of this as a UI nuclear reactor being handed over to you to play with. With this awesome power, however, also comes the responsibility to create sweet UI and beautiful interactions. Go forth and be amazing.

To learn more about the topics covered in this post, you are encouraged to voraciously consume the following articles and videos:

Try out your animation skills – download Visual Studio and get designing!

The Windows team would love to hear your feedback.  Please keep the feedback coming using our Windows Developer UserVoice site. If you have a direct bug, please use the Windows Feedback tool built directly into Windows 10.