Fast and fluid animations bring apps to life. In Windows 8 Consumer Preview, you will notice that animations are an integral part of the user experience. When you log in to your PC, the items in the Start menu animate in. When you launch an immersive app or zoom into the Start menu, the experience is enriched with a smooth animation. Animations can tell the user what happened as a result of a specific action. This visual feedback instills user confidence in the app’s responsiveness. Even a simple addition or deletion of an item in a list can be made fluid, modern, and informative using a subtle animation (as seen in  Jensen Harris’s //build/ session, around minute 25:00).

This short video demonstrates UI enriched with smooth animations.


Download this video to view it in your favorite media player:
High quality MP4 | Lower quality MP4

In Windows 8, animations are a key component of the Metro style personality and you can bring this personality to your own apps!

Here is what’s in this blog post:

  1. A brief overview of the animation engine
  2. How to get started using the Animation Library
  3. Custom animations and how to take advantage of the animation engine improvements
  4. Tips ‘n tricks for incorporating animations in your Metro style apps.

Independent animation

A big part of the Windows 8 experience is smooth and glitch-free animations, which are achieved through a capability called independent animation. An independent animation is an animation that runs independently from thread running the core UI logic. (A dependent animation runs on the UI thread.) In Windows 8 many of the animated elements are composed by a composition engine that runs on a separate thread. The engine’s work is offloaded from the CPU to the GPU. Moving composition to a non-UI thread means that the animation won’t jitter or be blocked by the app working on the UI thread (such as JavaScript code execution or sync operations). The GPU hardware is optimized for delivering visually rich graphics and makes use of video memory resources. Using the GPU greatly improves performance, allowing animations to run at a smooth and consistent frame rate.

You don’t need additional markup to make your animation take advantage of the independent animation capability. The system determines when it is possible to compose the animation independently. To make animations in your apps performant and smooth, you need to follow the independent animation guidelines in the Dev Center. These guidelines are most useful when creating custom animations, which we'll dive into later in this post.

Now, let’s get started with learning how you can enhance your apps by first making use of the metro-style animations that are provided in the Animation Library.

Animation Library

The Animation Library is a suite of Metro style animations that has been built specifically to take advantage of the platform’s independent animation capability. These animations are used throughout Windows UI and are also available for your Metro app. Think of this library as providing a palette of animations that do the right thing for you and are already designed to be fast and fluid.

As app developers ourselves, we love this feature because we don’t have to spend time creating animations that have the Windows 8 look and feel. Simply use the Animation Library and your app now is part of the Windows experience.

This library animates the Windows UI itself. These animations are clean and purposeful. We put a lot of attention into getting the timing and animation curves exactly right so that the user gets fast and fluid feedback when they interact with the Windows UI. So when designing animations in your app, we recommend that you first look at the Animation Library to find the best animation that fits your need.

It doesn’t matter if you are using HTML or XAML, the Animation Library provides you with a way to use the right animations and ensures that your UI will be fast and fluid. Let’s look at some examples.

JavaScript example

The JavaScript/HTML Personality Library is built with CSS3 animations and transitions. These animations are used for app navigation, content transitions and Windows 8 controls.

A simple yet compelling animation is the EnterPage animation. Use it when displaying content for the first time or transitioning between pages in a running app.

This example demonstrates how you can use this simple API in your app.

HTML

<html>
<body>
<div id="input">
Some content here
</div>
<button onclick="runAnimation()", Run animation&lt;/button>
</body>
</html>

CSS

<style>
#input
{
background-color:blue;
}
</style>

JavaScript

<script>       
function runAnimation(){
enterPage = WinJS.UI.Animation.enterPage(input);
}
</script>

XAML example

In XAML, the built-in Animation Library entails two concepts: Theme transitions and theme animations.

Theme transitions are typically used to animate visuals on the screen as they are loading, unloading or changing location on the screen. XAML layout system triggers these built-in animations in response to changes in the layout of the page.

These layout triggers include:

  1. Adding a UIElement to the page or visual tree.
  2. Removing a UIElement from the page or visual tree.
  3. Updating the layout properties of an existing UIElement on the page or visual tree that causes its location or size to be updated.

A particular theme transition may respond to any or all of the layout triggers. The EntranceThemeTransition responds to trigger #1 and animates UIElements as they are added to the page or visual tree. In the next example, all of Grid’s children are animated using EntranceThemeTransition.

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

<!-- Grid's children go here -->
</Grid>

Theme animations are built-in animations that are typically run on user interaction and you must trigger them to run. The easiest way to run a theme animation is to call the Begin method on Storyboard class. If you are familiar with the VisualStateManager (VSM), a theme animation can be put inside a visual state of a control. This example shows how to trigger a theme animation using the Begin method:

XAML

<Grid Background="{StaticResource ApplicationPageBackgroundBrush}">
<Grid.Resources>
<Storyboard x:Name="downAnimation">
<TapDownThemeAnimation TargetName="rectangle"/>
</Storyboard>
<Storyboard x:Name="upAnimation">
<TapUpThemeAnimation TargetName="rectangle"/>
</Storyboard>
</Grid.Resources>

<Rectangle x:Name="rectangle"
PointerPressed="Rectangle_PointerPressed"
PointerReleased="rectangle_PointerReleased"/>
</Grid>

Code


private void Rectangle_PointerPressed(object sender, PointerEventArgs e)
{
downAnimation.Begin();
}

private void rectangle_PointerReleased(object sender, PointerEventArgs e)
{
upAnimation.Begin();
}

Custom animations

As powerful as the Animation Library is, it can’t cover all your scenarios. For such cases, you can build your own custom animations that the system runs independently (see Animating for design guidance on building your own animations). This is where you need to be more careful about how to build an animation so that it doesn’t end up running on the UI thread.

You can still use dependent animations in your app. We encourage you to follow the independent animation guidance for custom animations but if your scenario requires animations that cannot be independently animated then the animation can still be run dependently.

The examples here demonstrate the use of a 3D non-affine independent animation that is not in the Animation Library.

JavaScript

For JavaScript apps, you can access the independent animation capability for custom animations via the CSS3 Animation and Transition syntax newly introduced to the Microsoft web platform in IE10. Independent animation supports only properties that don’t require re-layout or re-rendering. That means, independent animation for JavaScript apps is applicable to and supported only for CSS Animations/Transitions that target CSS3 2D and 3D Transforms or Opacity. Animations of other CSS properties run dependently on the UI thread.

Example of HTML custom animation

The example here demonstrates a simple CSS 3D flip.

HTML

<html>
<head>
<title>Html animations CSS3</title>
</head>
<body>
<div id="parent">
<div id="box" onclick="className='move'" >Click me for CSS Change!</div>
</div>
</body>
</html>

CSS

<style>
body
{
background-color:gray;
}
#box
{
position: relative;
background-color:green;
width:300px;
height:300px
}

#box.move
{
-ms-transition-property: -ms-transform;
-ms-transition-duration: 1s;
-ms-transition-timing-function: ease-in;
-ms-transform: rotateY(-180deg);
-ms-transform-origin: 50% 50%;
}

#parent{-ms-perspective: 600px;}
</style>

XAML

For XAML apps, a specific subset of properties are supported independently (you can find more info in the Windows 8 Developer Center). These properties include canvas positioning, opacity, render transforms, projections, clips and color.

Animating any property, besides the list we just looked at, results in a dependent animation. Meaning, the animation runs on the UI thread and thus will be at a risk of glitching. To encourage the development of fast and fluid UI XAML runs only independent animations unless you explicitly enable dependent animations. If you want to run a dependent animation, you can use the EnableDependentAnimation property on Timeline. There’s also a global static AllowDependentAnimations property that you can set to false to disable all dependent animations in your app.

Example of a XAML custom animation

The next example shows how to animate properties on PlaneProjection that the system runs independently. The animation concepts and syntax are exactly the same as in other XAML technologies but have been enhanced in Windows 8 to run independently, resulting in better performance characteristics for apps.

<Grid>
<Grid.Resources>
<Storyboard x:Name="customAnimation">
<DoubleAnimation Storyboard.TargetProperty="RotationY" Storyboard.TargetName="projection"
Duration="0:0:1" To="-180" />
</Storyboard>
</Grid.Resources>

<Grid Background="Red" Height="400" Width="600" PointerPressed="Grid_PointerPressed">
<Grid.Projection>
<PlaneProjection x:Name="projection"/>
</Grid.Projection>

<!-- Grid's children go here -->

</Grid>
</Grid>
 
private void Grid_PointerPressed(object sender, PointerEventArgs e)
{
customAnimation.Begin();
}

Best practices for independent animations

As with all systems, there are some limitations for independent animation. These limitations are different for the HTML and XAML platforms. In general you get independent animations except for these cases:

  1. Animating property that affects layout: These properties, such as CSS Width, trigger re-layout and are not supported independently.
  2. State of the animating element doesn’t follow independent animation guidelines: Independent animations that don’t follow the guidelines (see Animating post) are not supported by the system.
  3. Insufficient system resources: If the system doesn’t have sufficient resources (e.g. Video memory) then the animation falls back to dependent composition.

Here are a few guidelines for independent animations.

JavaScript

  1. Avoid infinite animation: When using independent animations, the GPU is allocating video memory. In CSS it is possible to specify –ms-iteration-count: infinite. When you set this property value, the specified animation will continue to run forever. This means your app holds on to the animating element’s video memory until you stop the animation. To stop an infinite animation, you can remove the –ms-animation-name value or change the animating element’s display property to be display: none.
  2. Don’t toggle the CSS Visibility property: When you set an independent animating element to visibility: hidden and then back to visibility: visible, this element is no longer independent. The animation continues but now it is composed on the UI thread.
  3. Place independent animating elements on top: Because independent composition uses your GPU, there is a limit to how much your system can compose independently. If your independent animation is behind other UI elements, those UI elements on top will also be composed independently. By doing this you are unnecessarily consuming video memory. To avoid this problem, make sure to have all independent animations on top of all other UI elements. If your independent animation is very low in the stack, it is at risk of falling back to a dependent animation.

    You can have your independent animations on top by:

    • Giving your independent animating elements a high z-index.
    • Using non-negative z-indexes for independently animating elements.
    • Not overlapping your independent animation with other elements.
  4. Don’t use large surfaces and too many independent animations: Similar to making placing your independent animation on top, be aware of how big your animating element is and how many you are animating at one time. Independent animations are limited by the system’s GPU. If you go beyond this limit, your animations fall back to the dependent UI thread. If you are noticing your animations not being smooth, you can use the IsIndependentlyComposed API to query your element.
  5. Use IsIndependentlyComposed API: You can use this API to determine if an HTML element is being composed independently from the UI thread. This property will return true for independentl animating elements, subscrollers and elements that overlap and independently animating element.

XAML

  1. Scale the elements for Height and Width animations: Animating Height and/or Width properties of UIElement results in a dependent animation because these properties require layout changes which can only be done on the UI thread. To have a similar effect of animating Height or Width, you can animate the Scale of the control. ScaleTransform are animated independently, this approach provides for a better frame rate.
  2. Don’t animate cache content: If you set the CacheMode property (UIElement.CacheMode) of an element to BitmapCache, then all animations in the visual sub-tree are run dependently. This is because we have to recreate the entire cache in every frame. The solution is to simply not animate cached content.
  3. Don’t use infinite animations of Progress controls: ProgressRing and ProgressBar have infinite animations that can continue on running even if the control is not visible in the page, which may prevent the CPU from going into low power or idle mode. We recommend that you set ProgressRing.IsActive and ProgressBar.IsIndeterminate properties to false when you’re not showing the respective controls.

In closing

We are excited about the fast and fluid user experiences that independent animation enables for Windows 8 apps. We hope that you find the Animation Library and the support for custom animations that run independently of the UI thread useful when you create compelling user experiences in your Metro style apps for Windows 8.

-- Angelina Gambo and Hamid Mahmood
    Program Managers, Windows