Tag Archives: Animation

New Lights and PropertySet Interop – XAML and Visual Layer Interop, Part Two

In the last post, we explored using XamlCompositionBrushBase and LoadedImageSurface to create custom CompositionBrushes that can be used to paint XAML elements directly in your markup. In today’s post, we’ll continue our look into the new improvements made to the XAML and Visual Layer Interop APIs available in the Windows 10 Creators Update.

In this blog series, we’ll cover some of these improvements in the Creators Update and look at the following APIs:

  • In Part 1:
    • XamlCompositionBrushBase – easily paint a XAML UIElement with a CompositionBrush
    • LoadedImageSurface – load an image easily and use with Composition APIs
  • In Part 2, today’s post:
    • XamlLights – apply lights to your XAML UI with a single line of XAML
    • PointerPositionPropertySet – create 60 FPS animations using pointer position, off the UI thread!
    • Enabling the Translation property – animate a XAML UI Element using Composition animation

If you’d like to review the previously available ElementCompositionPreview APIs, for example working with “hand-in” and “hand-out” Visuals, you can quickly catch up here.

Lighting UI with XamlLights

A powerful new feature in the Creators Update is the ability to set and use a Lighting effect directly in XAML by leveraging the abstract XamlLight class.

Creating a XamlLight starts just like a XamlCompositionBrushBase does, with an OnConnected and OnDisconnected method (see Part One here), but this time you inherit from the XamlLight subclass to create your own unique lighting that can be used directly in XAML. Microsoft uses this with the Reveal effect that comes with the Creators Update.

To see this in action, let’s build a demo that creates the animated GIF you see at the top of this post. It combines everything you learned about XamlCompositionBrushBase and LoadedImageSurface in the last post, but this example has two XamlLights: a HoverLight and an AmbientLight.

Let’s begin with creating the AmbientLight first. To get started, we begin similarly to the XamlCompositionBrushBase with an OnConnected and OnDisconnected method. However, for a XamlLight we set the CompositionLight property of the XamlLight subclass.


public class AmbLight : XamlLight
{
    protected override void OnConnected(UIElement newElement)
    {
        Compositor compositor = Window.Current.Compositor;

        // Create AmbientLight and set its properties
        AmbientLight ambientLight = compositor.CreateAmbientLight();
        ambientLight.Color = Colors.White;

        // Associate CompositionLight with XamlLight
        CompositionLight = ambientLight;

        // Add UIElement to the Light's Targets
        AmbLight.AddTargetElement(GetId(), newElement);
    }

    protected override void OnDisconnected(UIElement oldElement)
    {
        // Dispose Light when it is removed from the tree
        AmbLight.RemoveTargetElement(GetId(), oldElement);
        CompositionLight.Dispose();
    }

    protected override string GetId() => typeof(AmbLight).FullName;
}

With ambient lighting done, let’s build the SpotLight XamlLight. One of the main things we want the SpotLight to do is follow the user’s pointer. To do this, we can now use GetPointerPositionPropertySet method of ElementCompositionPreview to get a CompositionPropertySet we can use with a Composition ExpressionAnimation (PointerPositionPropertySet is explained in more detail in the PropertySets section below).

Here is the finished XamlLight implementation that creates that animated spotlight. Read the code comments to see the main parts of the effects, particularly how the resting position and animated offset position are used to create the lighting.


public class HoverLight : XamlLight 
{
    private ExpressionAnimation _lightPositionExpression;
    private Vector3KeyFrameAnimation _offsetAnimation;

    protected override void OnConnected(UIElement targetElement)
    {
        Compositor compositor = Window.Current.Compositor;

        // Create SpotLight and set its properties
        SpotLight spotLight = compositor.CreateSpotLight();
        spotLight.InnerConeAngleInDegrees = 50f;
        spotLight.InnerConeColor = Colors.FloralWhite;
        spotLight.OuterConeAngleInDegrees = 0f;
        spotLight.ConstantAttenuation = 1f;
        spotLight.LinearAttenuation = 0.253f;
        spotLight.QuadraticAttenuation = 0.58f;

        // Associate CompositionLight with XamlLight
        this.CompositionLight = spotLight;

        // Define resting position Animation
        Vector3 restingPosition = new Vector3(200, 200, 400);
        CubicBezierEasingFunction cbEasing = compositor.CreateCubicBezierEasingFunction( new Vector2(0.3f, 0.7f), new Vector2(0.9f, 0.5f));
        _offsetAnimation = compositor.CreateVector3KeyFrameAnimation();
        _offsetAnimation.InsertKeyFrame(1, restingPosition, cbEasing);
        _offsetAnimation.Duration = TimeSpan.FromSeconds(0.5f);

        spotLight.Offset = restingPosition;

        // Define expression animation that relates light's offset to pointer position 
        CompositionPropertySet hoverPosition = ElementCompositionPreview.GetPointerPositionPropertySet(targetElement);
        _lightPositionExpression = compositor.CreateExpressionAnimation("Vector3(hover.Position.X, hover.Position.Y, height)");
        _lightPositionExpression.SetReferenceParameter("hover", hoverPosition);
        _lightPositionExpression.SetScalarParameter("height", 15.0f);

        // Configure pointer entered/ exited events
        targetElement.PointerMoved += TargetElement_PointerMoved;
        targetElement.PointerExited += TargetElement_PointerExited;

        // Add UIElement to the Light's Targets
        HoverLight.AddTargetElement(GetId(), targetElement);
    }

    private void MoveToRestingPosition()
    {
        // Start animation on SpotLight's Offset 
        CompositionLight?.StartAnimation("Offset", _offsetAnimation);
    }

    private void TargetElement_PointerMoved(object sender, PointerRoutedEventArgs e)
    {
        if (CompositionLight == null) return;

        // touch input is still UI thread-bound as of the Creators Update
        if (e.Pointer.PointerDeviceType == Windows.Devices.Input.PointerDeviceType.Touch)
        {
            Vector2 offset = e.GetCurrentPoint((UIElement)sender).Position.ToVector2();
            (CompositionLight as SpotLight).Offset = new Vector3(offset.X, offset.Y, 15);
        }
        else
        {
            // Get the pointer's current position from the property and bind the SpotLight's X-Y Offset
            CompositionLight.StartAnimation("Offset", _lightPositionExpression);
        }
    }

    private void TargetElement_PointerExited(object sender, PointerRoutedEventArgs e)
    {
        // Move to resting state when pointer leaves targeted UIElement
        MoveToRestingPosition();
    }

    protected override void OnDisconnected(UIElement oldElement)
    {
        // Dispose Light and Composition resources when it is removed from the tree
        HoverLight.RemoveTargetElement(GetId(), oldElement);
        CompositionLight.Dispose();
        _lightPositionExpression.Dispose();
        _offsetAnimation.Dispose();
    }

    protected override string GetId() => typeof(HoverLight).FullName;
}

Now, with the HoverLight class done, we can add both the AmbLight and the HoverLight to previous ImageEffectBrush (find ImageEffectBrush in the last post):


<Grid>
            <Grid.Background>
                <brushes:ImageEffectBrush ImageUriString="ms-appx:///Images/Background.png" />
            </Grid.Background>
 
            <Grid.Lights>
                <lights:HoverLight/>
                <lights:AmbLight/>
            </Grid.Lights>
</Grid>

Note: To add a XamlLight in markup, your Min SDK version must be set to Creators Update, otherwise you can set it in the code behind.

For more information, go here to read more about using XamlLight and here to see the Lighting documentation.

Using CompositionPropertySets

When you want to use the values of the ScrollViewer’s Offset or the Pointer’s X and Y position (e.g. mouse cursor) to do things like animate effects, you can use ElementCompositionPreview to retrieve their PropertySets. This allows you to create amazingly smooth, 60 FPS animations that are not tied to the UI thread. These methods let you get the values from user interaction for things like animations and lighting.

Using ScrollViewerManipulationPropertySet

This PropertySet is useful for animating things like Parallax, Translation and Opacity.


// Gets the manipulation <ScrollViewer x:Name="MyScrollViewer"/>
CompositionPropertySet scrollViewerManipulationPropertySet = 
    ElementCompositionPreview.GetScrollViewerManipulationPropertySet(MyScrollViewer);

To see an example, go to the Smooth Interaction and Motion blog post in this series. There is a section devoted to using the ScrollViewerManipulationPropertySet to drive the animation.

Using PointerPositionPropertySet (new!)

New in the Creators Update, is the PointerPositionPropertySet. This PropertySet is useful for creating animations for lighting and tilt. Like ScrollViewerManipulationPropertySet, PointerPositionPropertySet enables fast, smooth and UI thread independent animations.

A great example of this is the animation mechanism behind Fluent Design’s RevealBrush, where you see lighting effects on the edges on the UIElements. This effect is created by a CompositionLight, which has an Offset property animated by an ExpressionAnimation using the values obtained from the PointerPositionPropertySet.


// Useful for creating an ExpressionAnimation
CompositionPropertySet pointerPositionPropertySet = ElementCompositionPreview.GetPointerPositionPropertySet(targetElement);
ExpressionAnimation expressionAnimation = compositor.CreateExpressionAnimation("Vector3(param.Position.X, param.Position.Y, height)");
expressionAnimation.SetReferenceParameter("param", pointerPositionPropertySet);

To get a better understanding of how you can use this to power animations in your app, let’s explore XamlLights and create a demo that uses the PointerPositionPropertySet to animate a SpotLight.

Enabling Translation Property – Animating a XAML Element’s Offset using Composition Animations

As discussed in our previous blog post, property sharing between the Framework Layer and the Visual Layer used to be tricky prior to the Creators Update. The following Visual properties are shared between UIElements and their backing Visuals:

  • Offset
  • Scale
  • Opacity
  • TransformMatrix
  • InsetClip
  • CompositeMode

Prior to the Creators update, Scale and Offset were especially tricky because, as mentioned before, a UIElement isn’t aware of changes to the property values on the hand-out Visual, even though the hand-out Visual is aware of changes to the UIElement. Consequently, if you change the value of the hand-out Visual’s Offset or Size property and the UIElement’s position changes due to a page resize, the UIElement’s previous position values will stomp all over your hand-out Visual’s values.

Now with the Creators Update, this has become much easier to deal with as you can prevent Scale and Offset stomping by enabling the new Translation property on your element, by way of the ElementCompositionPreview object.


ElementCompositionPreview.SetIsTranslationEnabled(Rectangle1, true);

//Now initialize the value of Translation in the PropertySet to zero for first use to avoid timing issues. This ensures that the property is ready for use immediately.

var rect1VisualPropertySet = ElementCompositionPreview.GetElementVisual(Rectangle1).Properties;
rect1VisualPropertySet.InsertVector3("Translation", Vector3.Zero);

Then, animate the visual’s Translation property where previously you would have animated its Offset property.


// Old way, subject to property stomping:
visual.StartAnimation("Offset.Y", animation);
// New way, available in the Creators Update
visual.StartAnimation("Translation.Y", animation);

By animating a different property from the one affected during layout passes, you avoid any unwanted offset stomping coming from the XAML layer.

Wrapping up

In the past couple posts, we explored some of the new features of XAML and Composition Interop and how using Composition features in your XAML markup is easier than ever. From painting your UIElements with CompositionBrushes and applying lighting, to smooth off-UIThread animations, the power of the Composition API is more accessible than ever.

In the next post, we’ll dive deeper into how you can chain Composition effects to create amazing materials and help drive the evolution of Fluent Design.

Resources

Smooth as Butter Animations in the Visual Layer with the Windows 10 Creators Update

The Windows 10 Creators Update marks the third major release of the Windows UI platform APIs. With each release, an attempt is frequently made to simplify features introduced in prior releases. This encourages Universal Windows Platform (UWP) developers to standardize on these features. The new hide and show implicit animations are an example of this.

At the same time, too much standardization can potentially lead to conformity, so with each new release more powerful visual features like the new custom animations are also added, which allow developers who are willing and able to dive into them to customize their user interfaces and stand out from the crowd. This inherent tension between ease of use and the power to customize rewards developers for their efforts while also making sure that no one gets left behind.

Hide and show animations for page transitions

Page transitions, often accompanied by state transitions as visual elements, are added to the visual tree of the new page. In fact, a lot of interactivity in UWP simply involves deciding which content to show and which content to hide as the state of the app changes. More often than not, this is tied to changing the value of the Visibility properties of the elements on the screen.

In the Creators Update, two new implicit animation techniques have been added to help you make these transitions more fluid: ElementCompositionPreview.SetImplicitShowAnimation and ElementCompositionPreview.SetImplicitHideAnimation. Whenever a UIElement is loaded or when that element’s Visibility property is set to Visible, the implicit animation associated with it using SetImplicitShowAnimation will play. Similarly, whenever the user navigates away from a page or when a UIElement is hidden, an animation associated with it using the SetImplicitHideAnimation method will be invoked. These two mechanisms make it easier for you to include motion as an inherent aspect of all your visual elements, while providing a seamless experience for your users.

Connected animations

Implicit animations are great for animating controls inside a page. For navigation transitions between pages, however, the Visual Layer provides a different mechanism known as connected animations to help you make your UI even 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.

The Windows UI platform APIs provide a class named the ConnectedAnimationService to coordinate animations between the source page and the destination page during navigation. You access the service by calling the static GetForCurrentView method. Then in the source page, you invoke PrepareToAnimate, passing in a unique key and the image that should be used for the transition animation.


ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("MyUniqueId", image);

In the destination page, you retrieve the image from your ConnectedAnimationService service and invoke TryStart on the ConnectedAnimation while passing in the destination UIElement.


var animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("MyUniqueId");
if (animation != null)
{
    animation.TryStart(DestinationImage);
};

In the Anniversary Update you did not have much control over this animation technique. Everyone got pretty much the same standard one. With the Creators Update, on the other hand, you have lots of new superpowers to personalize your transitions with:

  • Coordinated animations
  • Custom animations
  • Better image animations

Just to reiterate the point made in the introduction, the goal in designing the Windows UI platform APIs is to provide an awesome experience out of the box so you can copy the standard samples and get beautiful, fast and visually appealing visuals. At the same time, this shouldn’t ever take away from your ability to personalize the user experience to create something truly unique and wonderful with powerful new tools, like coordinated animations and custom animations.

Coordinated animations

A coordinated animation is a type of animation that appears alongside your connected animation and which works in coordination with your connected animation target. A coordinated animation gives extra visual flair to your page transition.

In the coordinated animation sample above, caption text that is not present in the source page is added to the destination page. The caption text is animated in tandem with the connected animation. We are doing two things here (in designer terms): providing context between the source and the destination using our connected animation while also adding visual interest with a coordinated animation at the destination. In user experience terms, though, all we’re doing is making the app’s transition animations look really cool.

Coordinated animations are fortunately also easy to implement. The TryStart method of the ConnectedAnimation class provides an override that allows you to pop in an array of visual elements you want to animate in a coordinated fashion. Let’s say that your caption text is in a visual element that you’ve named “DescriptionRoot.” You can add this as a coordinated animation by tweaking the previous code like so:


var animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("MyUniqueId");
if (animation != null)
{
    animation.TryStart(DestinationImage, new UIElement[] { DescriptionRoot });
};

That’s a lot of power packed into a little argument.

Custom animations

By default, the connected animations in the navigation sample move in a straight line from the origin position in the source page to the target position in the destination page. If you select a box in the far-left column, it will move more or less straight up, while if you select a box in the top row, it will more or less move directly left to get to that target position. But what if you could put some English on this?

You can with custom animations, introduced in the Creators Update. The custom animations feature lets you modulate your transitions in four ways:

  • Crossfade – Lets you customize how elements crossfade as source element reaches destination
  • OffsetX – Lets you customize the X channel of Offset
  • OffsetY – Lets you customize the Y channel of Offset
  • Scale – Lets you customize scale of the element as it animates

In order to customize a particular part of a connected animation, you will need to create a keyframe animation and add it to your page transition using the SetAnimationComponent call like so:


var animation = ConnectedAnimationService.GetForCurrentView().GetAnimation("MyUniqueId");

var customXAnimation = Window.Compositor.CreateScalarKeyFrameAnimation();
customXAnimation.Duration = ConnectedAnimationService.GetForCurrentView().DefaultDuration;
customXAnimation.InsertExpressionKeyFrame(0.0f, "StartingValue");
customXAnimation.InsertExpressionKeyFrame(0.5f, "FinalValue + 25");
customXAnimation.InsertExpressionKeyFrame(1.0f, "FinalValue");

animation.SetAnimationComponent(ConnectedAnimationComponent.OffsetX, customXAnimation);

Note that you use expressions to get the starting and ending values of the connected animation.

Awesome image animations

The Creators Update also introduces improved image interpolation for connected animations where the image size and even the relative dimensions are changing between the source and the destination—for instance transitioning from a square to a rectangular image.

This interpolation happens automagically so you have less to worry about.

Implicit animation support for property sets and shadows

Finally, animation capabilities are also extended in the Creators Update by allowing you to apply implicit animations to property sets and shadows.

This change provides developers with even more creative flexibility and the ability to modify shadows in interesting new ways, as shown in the code sample below.


var shadowBlurAnimation = compositor.CreateScalarKeyFrameAnimation();
shadowBlurAnimation.InsertExpressionKeyFrame(1.0f, "this.FinalValue");
shadowBlurAnimation.Duration = TimeSpan.FromSeconds(1);
shadowBlurAnimation.Target = "BlurRadius";

//Associating animations with triggers 
implicitAnimationShadow["BlurRadius"] = shadowBlurAnimation;
implicitAnimationShadow["Opacity"] = shadowOpacityAnimation;
implicitAnimationShadow["Scale"] = shadowScaleAnimation;

implicitAnimationVisual["Translation"] = translationAnimation;
            

//Applying Implicit Animations to objects 
content.Properties.ImplicitAnimations = implicitAnimationVisual;
shadow.DropShadow.ImplicitAnimations = implicitAnimationShadow;

Wrapping up

The visual power being made available to developers through the Windows UI platform APIs have basically always been a part of the UI Framework. They just haven’t always 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:

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


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

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:


// 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; 
}

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.


<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>

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.


_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();

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


private void gridView_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args) 
{ 
    var photo = args.ItemContainer; 
 
    var elementVisual = ElementCompositionPreview.GetElementVisual(photo); 
    elementVisual.ImplicitAnimations = _elementImplicitAnimation; 
}

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.

Smooth Interaction and Motion with the Visual Layer

The Composition APIs come with a robust animation engine that provides quick and fluid motion running in a separate process from your Universal Windows Platform (UWP) app. This provides a consistent 60 frames per second when running your app on an IoT device as well as on a screaming gaming machine. It is, quite simply, fast.

blogpost4-1

The Composition APIs also provide something you probably have never had access to before: the ability to create high-performing, low-level manipulation-driven custom animations like the one shown above.  Preview releases of the Composition APIs have already given you the ability to control animations with the XAML ScrollViewer’s ManipulationPropertySet. The Windows 10 Anniversary Update allows you to go even further, with the goal of empowering developers to use many types of input to drive animation.

This post will briefly cover the basics of expression animations. It will move on to a demonstration of how to drive expression animations from a ScrollViewer ManipulationPropertySet and, more importantly, why you really want to even if you don’t realize it yet. Finally, it will touch on the new InteractionTracker and give you an indication of just how much more powerful you are today as a developer than you were at the end of July.

A fast and fluid overview of expression animations

The Visual Layer supports both keyframe animations as well as expression animations. If you have worked with XAML animations before, then you are probably already familiar with how keyframes work. In a keyframe animation, you set values for some property you want to change over time and also assign the duration for the change: in the example below, a start value, a middle value, and then an ending value. The animation system will take care of tweening your animation – in other words, generating all the values between the ones you have explicitly specified.


ScalarKeyFrameAnimation blurAnimation = _compositor.CreateScalarKeyFrameAnimation();
blurAnimation.InsertKeyFrame(0.0f, 0.0f);
blurAnimation.InsertKeyFrame(0.5f, 100.0f);
blurAnimation.InsertKeyFrame(1.0f, 0.0f);
blurAnimation.Duration = TimeSpan.FromSeconds(4);
blurAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
_brush.StartAnimation("Blur.BlurAmount", blurAnimation);

A keyframe animation is a fire-and-forget mechanism that is time based. There are situations, however, when you need your animations to be coordinated and actually driving each other instead of simply moving in synchronized fashion.

blogpost4-2

In the demo above (source code), each gray gear is animated based on the animation of the gear preceding it. If the preceding gear suddenly goes faster or reverses direction, it forces the following gear to do the same. A keyframe animations can’t create motion effects that work in this way, but expression animations can. They are able to do so because, while keyframe animations are time based, expression animations are reference based.

The critical code that hooks up the gears for animation in the demo is found in the following section that calls the CreateExpressionAnimation method on the Compositor instance. The expression basically says that the animation should reference and be driven by the RotationAngleInDegrees property of the Visual that is indicated by the parameter “previousGear”. In the next line, the reference parameter is assigned. In the final line, the current Visual’s RotationAngleInDegrees property is finally animated based on the value referred to in the ExpressionAnimation object.


private void ConfigureGearAnimation(Visual currentGear, Visual previousGear)
{
    // If rotation expression is null then create an expression of a gear rotating the opposite direction
    _rotationExpression = _rotationExpression ?? _compositor.CreateExpressionAnimation("-previousGear.RotationAngleInDegrees");

    // put in placeholder parameters
    _rotationExpression.SetReferenceParameter("previousGear", previousGear);

    // Start the animation based on the Rotation Angle in Degrees.
    currentGear.StartAnimation("RotationAngleInDegrees", _rotationExpression);
}

But if an animation can be driven by another animation, you may be wondering, couldn’t we also drive an animation with something more concrete like user input? Why, yes. Yes, we can.

The beauty of the ScrollViewer ManipulationPropertySet

Driving an animation from a ScrollViewer using XAML-Composition interop is fairly easy. With just a few lines of code, you can add an animation to a pre-existing ScrollViewer control by taking advantage of the GetScrollViewerManipulationPropertySet method on the ElementCompositionPreview class.

You would use this technique if you wanted to add a parallax effect to your XAML or to create a sticky header that stays in place as content scrolls beneath it. In the demo illustrated below (source code), a ScrollViewer is even used to drive a parallax effect on a ListView.

blogpost4-3

Adding parallax behavior to a XAML page can be accomplished in just a few lines, as the following sample code by James Clarke demonstrates.


CompositionPropertySet scrollerManipProps = ElementCompositionPreview.GetScrollViewerManipulationPropertySet(myScroller);

Compositor compositor = scrollerManipProps.Compositor;

// Create the expression
ExpressionAnimation expression = compositor.CreateExpressionAnimation("scroller.Translation.Y * parallaxFactor");

// wire the ParallaxMultiplier constant into the expression
expression.SetScalarParameter("parallaxFactor", 0.3f);

// set "dynamic" reference parameter that will be used to evaluate the current position of the scrollbar every frame
expression.SetReferenceParameter("scroller", scrollerManipProps);

// Get the background image and start animating it's offset using the expression
Visual backgroundVisual = ElementCompositionPreview.GetElementVisual(background);
backgroundVisual.StartAnimation("Offset.Y", expression);

The even more beautiful InteractionTracker

Driving expression animations with a ScrollViewer is extremely powerful, but what if you want to drive animations using touch gestures instead? What if you want to pull items toward you with your finger, as in the demo below (source code), or animate multiple flying images across and into the screen as happens in the demo at the top of this post (source code)?

blogpost4-4

In order to achieve these effects, you would use the new InteractionTracker and VisualInteractionSource classes. InteractionTracker is a state machine that can be driven by active input. This is what you hook up to your animations. The VisualInteractionSource class, on the other hand, determines what kind of input you will use to drive your InteractionTracker.

picture5

The following sample code demonstrates a basic implementation of an InteractionTracker that is driven by touch input. The viewportVisual is simply the backing Visual for the root element on the page. You use this as the VisualInteractionSource for the tracker. In doing so, you specify that you are tracking X and Y manipulations. You also indicate that you want to track inertial movement.


_tracker = InteractionTracker.Create(_compositor);

var interactionSource = VisualInteractionSource.Create(viewportVisual);

interactionSource.PositionXSourceMode = InteractionSourceMode.EnabledWithInertia;
interactionSource.PositionYSourceMode = InteractionSourceMode.EnabledWithInertia;

_tracker.InteractionSources.Add(interactionSource);

Hooking the tracker up to an expression animation works basically the same way as hooking up a gear Visual to another gear Visual, as you did earlier. You call the CreateExpressionAnimation factory method on the current Compositor and reference the Position property of the tracker. You then animate the Offset property of the Visual you want to add motion to your expression.


var positionExpression = _compositor.CreateExpressionAnimation("-tracker.Position");
positionExpression.SetReferenceParameter("tracker", _tracker);

contentVisual.StartAnimation("Offset", positionExpression);


Those are the basics of driving animation from almost any input. What you do with this amazing new power is entirely up to you.

Wrapping up

Expression animations and Visual Layer Interactions are both topics that can become very deep, very fast. To help you through these deeper waters, we highly recommend the following videos and articles:

Get started now – download Visual Studio.

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.

Beautiful apps made possible and easy with Windows.UI

If you are into creating sweet UI, then you’re definitely going to want to dig into the new Visual Layer with Windows.UI.Composition. The Windows.UI.Composition namespace allows Universal Windows Platform (UWP) developers to use a new Visual Layer that will get them closer to the metal, graphically speaking, while still using familiar technologies like XAML and C#. By getting closer to the metal, actually down to the system compositor level, developers are able to get great visual performance and custom UI experiences. By working through the XAML layer, developers get the ease of use they have come to expect out of UWP. This is basically a best of both worlds scenario that puts great responsibility in the developer’s hands. And with great responsibility, as we all know, comes great power.

image1

Windows.UI.Composition first debuted in the Windows 10 November 2015 update. With the Anniversary edition, it is getting a whole host of new effects, such as the blur effect, as well as new animation capabilities such as:

Light

A Composition Light supports ambient, distant, point and spot lights. When these lights target a visual, the visual and all of its descendants are aware of and respond to this light source. A SceneLightingEffect describes how content responds to light with reflective properties and providing an illusion of depth with a normal map.

Shadow

Shadows are here. Rectangular shadows are the default, but if you supplying a mask, a DropShadow will mimic your contents shape

BackdropBrush

You can use a BackdropBrush to apply an effect (or a chain of effects) to a region behind a SpriteVisual. For example blurring the background behind a single element you want to focus attention on.

image2

So why do you need all these graphical and UX superpowers? In addition to giving pizzazz to your UWP apps, access to the system compositor level also helps your users to accomplish their tasks faster and more fluidly. For instance, when you use Composition effects to blur a background in response to a click, you are focusing the user’s attention on her current task and removing distractions. This is the sort of subtle UI implementation that actually makes your user’s life easier – and it works best when your user doesn’t even know that you did anything for them. They are just left with the impression that your app is easy to use and feels fast, even if they can’t exactly put their finger on the reason.

The Visual family

To better understand the basic principles of Windows.UI.Composition it’s necessary to introduce you to the visual family. In order to get fast and fluid effects, you need direct access to something called the system compositor (also referred to as the DWM). The system compositor is agnostic to the UI thread and doesn’t really care about being on the UI thread or blocking threads. Things happen very quickly at the system compositor level, where everything that is about to be sent to the display screen gets put together. This is also where you get to add additional effects if you want to just before shipping all your visuals to the display.

The visual family is made up of Visuals, ContainerVisuals and SpriteVisuals. The SpriteVisual class inherits from container visual, and the ContainerVisual class inherits from the base Visual class. There is also a Compositor class which acts as the senior member of the visual family. It quite literally creates visual objects if you need them and also manages the relationship between an application and the system compositor process.

The visual family is a lot of fun. Let’s say your XAML, many levels above, has a Grid object. That Grid will have a member of the visual family assigned to it. In technical parlance, we say that the Grid is backed by a visual. Once you grab hold of this backing visual, you can start to animate it using the composition animation system. If it is a ContainerVisual, then you can add additional visuals to it. Finally, you can also create sprite visuals, using the compositor factory class, in order add brush effects to your visual using the Windows.UI.Composition effects system.

Effects system

If you remember WPF bitmap effects, then you know what the effects system in Windows.UI.Composition does – it does all that but also a ton more. In case you are unfamiliar with WPF bitmap effects, though, the effects system lets you manipulate effects such as 2D affine transforms, arithmetic composites, blends, color source, composite, contrast, exposure, grayscale, gamma transfer, hue rotate, invert, saturate, sepia, temperature and tint.

New anniversary additions: Linear transform, distant specular, distant diffuse, spot specular, spot diffuse, point specular, point diffuse, and Gaussian blur. Shorthand effects: opacity, crossfade, alphamask and tint.  These are helpers that make it easier to implement common operations.

image3

The effects system also lets you animate, customize and chain these effects in order to create even cooler visual experiences. Chaining effects allows an application to use multiple effects simultaneously. Animation support allows you to have dynamic effects that change value over time or in reaction to user events.

Animations system

The animation system lets you set up KeyFrames and expressions to move backing visuals and custom visuals across the screen, perform transforms and clips and also animate effects. The animation system ensures that your animations will run at 60 frames per second and will be independent of the UI thread.

image4

Keyframe animations are your classic tweening animations: you specify the visual properties of your visual at different points in time and add easing functions to determine how you want your visual to automatically transition between those set points. Expression animations, on the other hand, let developers create mathematical relationships between visual properties and discrete values that will get evaluated and updated every frame. Developers can reference properties on composition objects, use mathematical function helpers and even reference Input to derive these mathematical relationships. The animation engine in Anniversary Update also adds the ability to:

  • Create custom UI-thread independent manipulation experiences using the InteractionTracker.
  • Create connected animations that can animate content across pages in an application.
  • Create layout animations that run automatically in response to XAML layout updates.
  • Create animations that automatically run on visual property changes using implicit animations.

XAML interop

XAML Interop is the magic goo that lets you apply the effects and animations we have been discussing to your XAML elements. It what lets you grab a backing visual and manipulate it.

A useful way to think of the relationship between the XAML layer and the Composition layer is in terms of movie making with a green screen. Everything that happens in front of the screen involving actors and stunts is equivalent to what you do in XAML. That’s where accessibility and hit testing and real physical things happen. Windows.UI.Composition effects and animations happen in the green screen and really happen after the fact. That’s where the computer effects and heavy mathematics happens to make what the actors are doing look like something considerably different and more visually appealing before it gets shown to the film’s audience.

image5

XAML Interop actually works in both directions. In addition to grabbing backing visuals off of the XAML visual tree, you can also insert what are called composition islands into the visual tree from the Composition layer. Finally, in order to support more complex and interesting scenarios, XAML Interop also lets you use the direct manipulation of a scroll viewer as input for Composition animations.

The sample gallery

The best way to deep dive into Windows.UI.Composition is by pulling down the sample code that the Composition team created and published to Github. The Windows UI Dev Labs samples, as they’re called, are extensive and visually rich. The samples extend from simple photo effects to complex parallax animations on XAML controls.

image6

Don’t hesitate. It’s hard to really grasp the magnitude of the visual capabilities you are getting with Windows.UI.Composition until you see for yourself all that it empowers you to do.

Wrapping up

In addition to diving into the sample gallery on Github, which is highly recommended, you can also learn more about Windows Composition through the following articles, videos and blog posts.

Polishing Your App with Animations and Audio Cues

There are plenty of well-designed apps out there. Often what distinguishes a great Universal Windows Platform (UWP) app from a good one is the small touches, like animations and audio cues. This post will provide guidance on some of the subtle nuances that can help you take your app to the next level. It will also extend some of the topics we have already covered in this series, such as color, navigation and visual communication and visual clues.

As you apply animations and audio cues in your app, it is important to remember that these elements are no longer optional. Contemporary app users expect regular feedback to let them know that their app is working and in constant motion. An app that lacks visual and audio flare is often seen as unresponsive or glitchy.

Animations that call attention

Animations are a dynamic way to add flare to your app, and they can be applied in many different ways. Sometimes, the purpose of an animation is to draw your attention, as with a call to action. At other times, animations are used as transitions between different states or screens in your app as you navigate. As a general rule, you want your animations to be subtle, smooth and unobtrusive.

Animation Polished Okay Overblown
Simple Button Click Shift in color

or slight variation in light/shadow

Skeuomorphic button up/button down Special effects involving particles or light effects
Card Click & Release Card rises from the surface, and shows slight motion toward the selected action, then flips around to reveal the result Card enlarges to show content Card performs an effect that calls attention to itself, rather than to the content

Animated assets possess their own style in the same way that design assets do. Just as you want your icons and buttons to look like they come from the same set or template, you want your animations to look as if they share the same style. Additionally, the animations should share a similar pattern of motion when they are applied to elements or events.

Flipboard

In the video above, Flipboard takes advantage of in-app animations with every page turn. As users move from page to page, the pages flip over as if they were in an actual magazine.

Animations do not have to be limited to reactions to user actions, either. They can be used for notifications, confirmations and indicators. For example:

  • App start or close
  • App action beginning or finishing
  • When a notification is received, such as a message from your app or another app

Animations do not need to be elaborate, time-consuming, or expensive to design. In fact, simpler is usually better. You can do much with simple transforms: size, color, opacity and position. For example, a button state change can be communicated with a small offset in position and a slight fade effect (a change in opacity).

How long should an animation stick around?

Like a good joke, animations are all about timing and pace. A movement that lasts too long will make your users impatient. A motion that is too quick can annoy or even agitate your users. The goal of a finely tuned animation is to find that happy medium between too quick and too slow.

Fortunately, motion designers have actually put a number to this happy medium. A good animation or audio cue will last between 150 and 350 milliseconds—in other words, around a sixth to a third of a second. Once you find an interval that works for you, try to use it consistently throughout your app.

Animations that transition

App navigation is enhanced through the use of transition effects. Having one page disappear while another takes its place is simply too jarring. Instead, one page should either fade or slide out smoothly while the other fades or slides in.

You already know that you want animations to last from 150 ms to 350 ms. Since transitions actually combine two motions, one leaving and one entering, a full transition will last from 300 ms to 700 ms. To make your transitions even more pleasing, however, you should vary the rate at which the transitions occur by adding an easing effect.

Easing reflects how movement occurs in the real world. Objects do not typically go from inactivity to a constant velocity and then back to a state of inactivity. Instead, they ease into motion, going slowly at first and then accelerating to achieve a desired speed. Adding easing to your transitions makes animations appear more natural and organic.

There are many mathematical formulas governing easing effects. As with many things, however, the simplest approach is often the best. If you can keep track of the difference between an Ease-in and an Ease-out, you are most of the way to mastering transition animations.

IMAGE1

An Ease-in effect starts off slow and then speeds up. It basically eases into the motion.

IMAGE2

An Ease-out is the diametrical opposite of an Ease-in. It basically starts off fast and then slows down. When in doubt, the Ease-out should be your go to when reaching for an easing. The Ease-in Ease-out, as you would expect, is slow-fast-slow. It imitates the motion of a vehicle such as a train or a car, and can be a very satisfying effect.

IMAGE3

Here is a real-life example of transition animation that uses both easing and a subtle bounce animation to accentuate the behavior and beauty of the app. Controls in the left rail of FontCandy animate as they open to reveal the actual options. The animations include easing and bouncing, which accentuates the beauty of the app itself.

Font Candy

There are also variations of each of these easing effects such as sine, cubic, quad, and quint. You should play with these different effects and find something that you like. Once you do, try to use your preferred easing effect consistently throughout your app.

Sound effects

Every place you have an animation you could also employ audio, either instead of or in addition to the visual effect. Again, you want to go for subtlety rather than fanfare. If your audio effect seems fun or impressive, imagine the effect it might have if repeatedly played while a frustrated user tries to successfully complete a task. For example, if your error sound is an “Uh oh,” you might just drive your user away.

Conversely, some people will find any audio distracting, so it is a best practice to ensure your app has a setting that allows users to disable all audio cues and background audio in your app.

Duolingo

Best practices for sound design

As user patterns emerge in app design, sound effects have become simple, impactful, and purposeful. The touch of a keyboard, turning a device on/off, notification of an email/text message, the refresh of an application. When it comes to audio UI design, it is always wise to ask yourself, what does this sound bring to the app?

In game design, for example, sound effects and background music help make the experience rich and tell a story. In other types of apps, however, numerous sound effects can distract the user from accomplishing their tasks. Use sound effects with discretion for apps, suit them to the nature of your app, and ensure they feel intentional.

In some cases, you might also want to consider adding subtle haptic feedback. This is an obvious option for apps that are designed for a quiet setting but can also be valuable in providing a tactile experience where a user may otherwise miss something. For example, a fleeting pulse to confirm a button press, the success of a drag and drop gesture, or even the appearance of something important in a reading list. Different tactile patterns could be used to convey different feedback.

Wrapping Up

Whether you are lone developer or a small development team, the skillful application of design know-how can take your app from good to great, even if there is no designer on your staff. What’s more, putting great design principles into practice at the start of your process may save you wasted coding time down the road while also resulting in a more seamless, pleasing user experience.

For more information, see:

Get started with Windows Visual Studio!

MSDN Magazine: Special Windows 10 Issue

MSDN magazine has released a special Windows 10 issue. The issue spans a large number of topics from Visual Studio tooling to game development to user experience to notifications.

If you don’t get the print magazine, don’t worry, all the articles are online for free.

Here is the complete list of articles:

Some of these topics have been covered by Building Apps blog in the past but most have been expanded for the magazine. If you have any topics you’re looking for Building Apps blog to cover, please tell us in the comments or at @WindowsDev