Offset Animation gets stomped. Here is how to solve it in UWP Creators Update

In Windows Anniversary update Windows Composition and XAML introduced new features of implicit animations and to support that made some policy/behavior changes on how visuals are shared among platform and the framework. Essentially both platform and framework started sharing properties on same interop visual which made it super easy for developers to animate layout and property changes using implicit animation but had a side effect i.e. if you (developer) were animating offset of a interop visual using implicit or explicit animation and framework decided to run layout your animation got stomped or cancelled as composition animations have the policy of last one wins. This abnormal behavior led you to workaround it to get to your desired behavior. You can look at Robert’s post to understand how to workaround this in Anniversary update.

In Creators update release Windows UI platform decided to address this problem with addition of a new property named Translation. As part of ElementCompositionPreview API visual layer added a new method called EnableTranslation(UIElement element, bool flag). Translation is a property that is added to the backing Visual’s property set for the UIElement, true flag adds the property to the property set.

Translation is different than Offset and both serve different purpose. Offset property is used by framework and layout system to manage apps layout. Translation once enabled is fully in app’s control and is not clobbered by layout or any changes to Offset. Composition does the heavy work of making sure that both offset and translation values are set properly to give the right UI experience.

Here is sample code on how to enable translation and animate:

ElementCompositionPreview.EnableTranslation(myelement, true);

var animation = _compositor.CreateVector3KeyFrameAnimation();
animation.Duration = TimeSpan.FromMilliSeconds(3);
animation.Target = "Translation"; 
animation.InsertKeyFrame(1f, Vector3(20f,20f,0f);

visual.StartAnimation(animation,"Translation");

The above sample will animate myElement to Vector3(20f, 20f, 0f) even if there are layout changes. You can also use translation as part of Implicit Animations as well.

Hope this helps with your scenarios.

Thanks for your feedback!

UWP Connected Animations updates with Windows Creators release

Context is one of the most important things that helps us understand what is going on, without context things become crazy and prone to interpretation. Think about it if you were writing a piece of code where you have to show something on the screen you will need context to get the right information or to understand what information to get. If a friend of yours start to talk about moon travel and how great experience it was for him, you will definitely stop him right there as ask for some context to make sense of it all.

Dictionary definition for context:

The set of circumstances or facts that surround a particular event, situation, etc.

Similarly in UX when user navigates from one page to another to consume more information about a specific topic or item they require some context to help them be comfortable in their new surroundings and to make sense of it. ConnectedAnimationService provide a rich set of APIs for Windows UWP developers to create beautiful and engaging experiences which help users maintain context as they navigate to consume content. Some easy UX wins that you can achieve by using this API are

  1. Help user understand their action better, this helps user be more confident in your app and not lost. This helps “Time to action” which is a KPI to track user experience success.
  2. You can manage where should user focus when they land on the page, what is the most important thing that user should see first and start from as they start consuming content
  3. Remove any seams from your app. With this API you can absolutely remove all the flashes from your app navigation. It will feel like one cohesive and immersive experience
  4. Users experience a playful app which is keeping them engaged and informed during the most critical navigation.

What does a connected experience look like?

Here the user is navigating from a master to detail page to consume more information about the Item.

 

Connected Animations

XAML released a new API in Anniversary Update named ConnectedAnimationService. This API lets you create experiences like above with simple API calls. Basically the API is divided into 4 parts

  1. Identify the source element that you want to animate with navigation and provide an ID
  2. Identify the destination element that source will animate to.
  3. Prepare the animation on source page right before navigation
  4. On the destination page when the target element has _loaded get the animation with the ID then start the animation with destination element as target.

This is what the APIs look like

On your source page identify the element that you want to animate when it is clicked and results into navigation In your click handler

ConnectedAnimationService.GetForCurrentView().PrepareToAnimate("ID", SourceImage);
Frame.Navigate(typeof(DestinationPage));

Use Unique ID as you can have more than one element animating from source to destination page.

On destination page: using OnNavigatedTo of page or in case of Image use ImageOpened event handler perform the following code to get the animation associated with the ID that you identified on the source page and TryStart the same animation on the destination page’s element which you want to connect.

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    ConnectedAnimation imageAnimation = 
        ConnectedAnimationService.GetForCurrentView().GetAnimation("ID");
    if (imageAnimation != null)
    {
        imageAnimation.TryStart(DestinationImage);
    }
}

Custom Animations

Before Creators update ConnectedAnimationService provided only a default animation which meant your app navigation will look the same as everyone else. Creators update adds this much needed ability for developers to provide custom animations to have beautiful transitions that differentiate your app from others.

There are 4 components that you can customize

  1. Crossfade – Let’s you to customize how elements crossfade as source element reaches destination
  2. OffsetX – Let’s you customize the X channel of Offset.
  3. OffsetY – Let’s you customize the Y channel of Offset.
  4. Scale – Let’s you customize scale of the element as it animates

Customize X channel of your Offset

 

//OffsetX Custom Animation

 var customXAnimation = _compositor.CreateScalarKeyFrameAnimation();
 customXAnimation.InsertExpressionKeyFrame(0.5f, "FinalValue - 25f"); //You can also use StartingValue in case you need to use starting value to customize animation.
 customXAnimation.InsertExpressionKeyFrame(1f, "FinalValue");

ConnectedAnimationService.GetForCurrentView().GetAnimation("ID").SetAnimationComponent(ConnectedAnimationComponent.OffsetX, customXAnimation);

 

Customize Y channel of your Offset animation

//OffsetY Custom Animation

var customYAnimation = _compositor.CreateScalarKeyFrameAnimation();
customYAnimation.InsertExpressionKeyFrame(0.5f, "FinalValue - 25f"); //You can also use StartingValue in case you need to use starting value to customize animation.
customYAnimation.InsertExpressionKeyFrame(1f, "FinalValue");

ConnectedAnimationService.GetForCurrentView().GetAnimation("ID").SetAnimationComponent(ConnectedAnimationComponent.OffsetY, customYAnimation);

Simlarly you can also provide custom animations to define your crossfade and Scale to accomplish your scenario.

//CrossFade Custom Animation
 ConnectedAnimationService.GetForCurrentView().GetAnimation("ID").SetAnimationComponent(ConnectedAnimationComponent.CrossFade, scalarKeyFrameAnimation);
 
//Scale Custom Animation
ConnectedAnimationService.GetForCurrentView().GetAnimation("ID").SetAnimationComponent(ConnectedAnimationComponent.Scale, scalarKeyFrameAnimation);
 

Coordinate Animations across pages

Connected animations help you connect different pages together with context that animates across pages. Destination page where the element is animating to will have more information about object that user selected to help connect the dots between 2 different pages and with the element animating creators update released a new functionality with ConnectedAnimationService which lets you coordinate elements on the destination page with the animating element. E.g. In the sample below the text on the right is animating with the incoming image where as the text is on the destination page. If item which was clicked was on the right side then text seems to come from right whereas if the image is coming from left the text also animates in from left.

The text panel is only on the destination page and not on source page. Text block on your destination page in XAML looks like this

<StackPanel x:Name="DescriptionRoot" Grid.Column="1" Margin="0,80">
 <TextBlock Foreground="White" FontSize="18">Caption Text</TextBlock>
 <TextBlock Margin="0,10,0,0" Foreground="White" HorizontalAlignment="Left" FontSize="14" MaxWidth="500" TextWrapping="Wrap">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras lobortis nulla sit amet aliquet viverra. Etiam gravida luctus orci, at egestas leo auctor sed.</TextBlock>
 </StackPanel>

Now on your Destination page’s onNavigatedTo Event where you perform TryStart(…) with the incoming animation you provide list of elements that you want to coordinate as parameter and framework will do the work of coordinating animations across pages.

protected override void OnNavigatedTo(NavigationEventArgs e)
 {
 base.OnNavigatedTo(e);
 ConnectedAnimationService
 .GetForCurrentView()
 .GetAnimation("BorderSource")
 .TryStart(DestinationElement, new[] { DescriptionRoot });

 }

Image Interpolation

Sometimes we have different sized images across pages i.e. a square image performs a connected animation to destination where the image is defined as rectangle. With Creators update you don’t have to think about it a bit, platform performs the magic to automatically interpolation between image sizes. Just make sure you TryStart(..) the ConnectedAnimationService in your image control which has defined size _loaded event.

Conclusion

Connected animations provides your users a delightful and seamless experience which also makes them feel in control. Users don’t feel lost as they jump from one page to another. With the new updates in Creators release you can make connected animations your own and have a differentiated experience which delights your users and gets you that 5 star rating.

Resources

You can look at a running sample from Windows UI Sample Gallery – Navigation Flow For Show/Hide and Page transitions in this sample please refer to this post.

Complete Sample Gallery – Windows UI Samples

 

Let me know in the comments section if this was helpful and what else would you want to talk about.

Thanks!

Create custom page transitions with Windows Creators Update

Have you ever wonder what would happen if things suddenly show up and disappear in front of you, you will be surprised right? Similarly Apps consist of so many objects/Controls and pages, if they did the same thing i.e. appear and disappear suddenly then users will be surprised and it will be an awful experience. Apps consist of different pages to create an IA (Information Architecture) that helps users to easily understand different aspects of the app and consume content. Transitioning from one page to another is an experience which in inevitable and is experienced by all users. Page transitions are one of the most critical animation as it helps users to orient themselves and understand new page which is coming into view and what to expect, providing a great user experience and making it seamless will make users feel in control and be in love with your application. Not having any sort of transition leaves users with a bad taste as change is very sudden, not cohesive, jarring and does not provide any help to me as a user to understand what’s next.

As a UWP developer before Creators update could you could only use XAML theme transitions to achieve some page transition. The drawback of theme transitions is that developers cannot customize them to their needs to create their own app personality. There are also apps which don’t use any transition animations and users see a hard cut between pages which is jarring and very sudden.

Transitions

A transition is made up of two main components

  1. From – The state the user is transitioning from. It could be a page or state or value.
  2. To – The state the user is transitioning to. It could be a page or state or value.

Let’s look at a sample which shows some great page transitions and try and break it down

If you look the video closely you will notice few things

  1. There is a fade out animation which happens on the source page as user navigates away from it by clicking an item
  2. There is a connected Animation which helps Item 4 animate across pages – this is not covered in this post
  3. On the destination page there is a dark grey box that is animating down from top to its position
  4. On the destination page there is a light grey box that is animating from bottom to its position

Animating element as they Show

Elements appear on the screen due to multiple reasons, navigation loads a new page, objects appear on the page due to data binding or user added something to the page. In the video above user navigates to a new page to view more details about an item. If you don’t do anything in your UWP app elements will pop on the screen as they are added to the visual tree. It is not a very pleasant experience for the user as objects might appear in random order, asynchronous operations make this problem even worst.

To solve this problem Windows Creators Update has added a new API to the Implicit Animations named SetImplicitShowAnimation(…). This API lives on Windows.UI.XAML.Hosting.ElementCompositionPreview Class.

ElementCompositionPreview.SetImplicitShowAnimation(UIElement element, ICompositionAnimationBase animation);
 

//Sample usage to animate top border to its position as it shows on the screen
// Add a translation animation that will play when this element is shown
 var topBorderOffsetAnimation = _compositor.CreateScalarKeyFrameAnimation();
 topBorderOffsetAnimation.Duration = TimeSpan.FromSeconds(0.45);
 topBorderOffsetAnimation.Target = "Translation.Y";
 topBorderOffsetAnimation.InsertKeyFrame(0, -450.0f);
 topBorderOffsetAnimation.InsertKeyFrame(1, 0);
 ElementCompositionPreview.SetIsTranslationEnabled(TopBorder, true);
 ElementCompositionPreview.SetImplicitShowAnimation(TopBorder, topBorderOffsetAnimation);
 

Let’s talk about the code a bit.

This animation will automatically play on the TopBorder when it appears on the screen. Animation should be associated with UIElement before it is loaded. Animation provided as part of SetImplicitShowAnimation will only trigger at the time when Visuals enter the tree. Associate these animations on page’s constructor or when the object is created but has not yet loaded. If you associate these animations in Loaded Event then the animation will NOT play as the element is already in the tree and framework will not trigger this animation as it has passed the Show stage.

Visibility.Visible is another UIElement property which acts like a trigger to play any show animations associated with the UIElement.

Using Implicit Show animations can help you to create beautiful page transitions and animate elements into view gracefully without popping and flashing. You can also associate Show animation on the Page element itself to create FadeIn type of transitions.

Translation: If you have used Composition or the Visual layer before then you will notice this new property named Translation to help with offset stomping issue. App developers should use Translation to move their Visuals as Framework uses Offset for Layout. More on this topic in a coming post.

Animating elements as they hide

As Frame navigates to a new page users experience a sudden disappearance of objects and the page they are navigating from or in a general case when users delete some object from a page they just suddenly poof/disappear from the page rather than gracefully hiding using animations. In the video above user is navigating from source page to view details of a specific item. It has been very tough for developers to animate objects as they hide as once the object is removed it gets removed from the visual tree without giving any chance and opportunity to run any animation.

To solve this problem Creators Update added a new API to the Implicit Animation named SetImplicitHideAnimation(…), this API again lives on Windows.UI.XAML.Hosting.ElementCompositionPreview.

ElementCompositionPreview.SetImplicitHideAnimation(UIElement element, ICompositionAnimationBase animation);

//This API is very similar to Show animations above. Let's look at an example usage based on our Sample.
// Add a translation animation that will play when this element exits the scene
 var mainContentExitAnimation = _compositor.CreateScalarKeyFrameAnimation();
 mainContentExitAnimation.Target = "Translation.Y";
 mainContentExitAnimation.InsertKeyFrame(1, 30);
 mainContentExitAnimation.Duration = TimeSpan.FromSeconds(0.4);
 ElementCompositionPreview.SetIsTranslationEnabled(MainContent, true);
 ElementCompositionPreview.SetImplicitHideAnimation(MainContent, mainContentExitAnimation);

This code snippet is animating the translation. The animation will start as soon as element is marked to be removed from the tree. Framework does the heavy lifting of understanding that there is an animation associated with the element which is to be removed and hangs on to it till it finishes the animation. From a developers perspective it is removed from the Visual and UIElement collection and will not be returned if you try to enumerate its parent’s children.

Note: Framework retains the complete sub-tree/children of the element which is playing its animation as part of hiding. Another point worth noting here is that Hide animations are recursive in nature i.e. if you remove an element which has hide animation and contains children which have hide animations then removing the parent will kick off animations on children too. E.g. ListView with has ListItems, both have hide animations associated with them. If you remove the ListView then framework will trigger all the hide animations on all the elements under ListView. Developers do not have to go an individually remove items to play their animations framework does this by itself.

Visibility.Collapse also participates in Hide animations. i.e. if UIElement has a hide animation and the visibility is collapsed then element will collapse using the hide animation.

End to End Page Transition

Page Transitions are tricky but also is a great opportunity to bring a great seamless experience to users and help them better understand your application by setting context, helping them focus on things and areas where they need to pay attention or take action, orienting the users as they see a new page in front of them will increase your apps engagement and satisfaction.

Implicit show and hide animations, makes it easy for you to create these beautiful seamless experiences by just defining animations that you want to play and let the framework and platform do the rest of animating objects as they show and hide on the screen.

Resources

You can look at a running sample from Windows UI Sample Gallery – Navigation Flow It also has some connected animations which is posted here.

Complete Sample Gallery – Windows UI Samples

Thanks!

Immersive users in your app.

We want users to love our apps and use it everyday and rave about them. When we go to a brick and mortar store or a shopping complex or restaurants first impressions matter, we make some assumptions about the place and start shaping our expectations. In same way when users launch an app they also set expectations based on what app shows as it starts up. Some very successful apps know this and have great start up experiences and you can see that in their star ratings and downloads as well. Simple changes to app launch behavior can help ship an app that stands out in the app store.

App launch

Mostly splash screens with product icon or company name is the first thing users experiences when they launch an app and that too for a second or so before the scene hard cuts into content. At this inflection point if app doesn’t do a good job to retain users attention then statistically there is a high chance of users abandoning the app.

Statistics show 1 sec delay in launch can cause 7% reduction in conversion 

Image Credit: Kissmetrics.com

An app is considered slow and unresponsive if it takes greater than or equal to 1 second to be interactive. App needs to show an experience to the where the time for user to see something interesting and interactive in the app is approximately 500ms.

Some of apps with great app startup experience are

  1. Facebook on iOS
  2. Safari on iOS
  3. Wunderlist on iOS

Let’s look at Facebook launch or startup experience for a second. As soon as users press the Facebook icon on iOS user see app chrome.

User did not see any Facebook product icon, within some milliseconds app transitions to more interactive points in the app and sets users orientation on what to expect

and eventually after some time (milliseconds) content fades in instead of the grey bars.

These apps look smooth as they open and rather than UI feeling jumpy they are interactive, responsive, keep my attention and smoothly fades in content in its place.

When users open an app

In very general terms most OS do the following things when user clicks or presses an app icon to start an app.

  1. If the app is not running then OS first has to identify app binaries to load which takes some milliseconds
  2. After OS related binaries are loaded OS will try to load the framework binaries required to launch the app which takes milliseconds
  3. Now if you are making database connections or disk connections, app platform has to load those binaries to make those operations
  4. Once required binaries are available then framework starts its process of laying out the app in the app window – this is the first time user will see something from the app. Before this if users will only see your splash screen which might not be useful as that is not the intent of the user.

#3 and #4 are the opportunities for app authors to make creative decisions to create beautiful experiences.

Things that you can do to improve perceived performance

  1. Consider making your default/first page just a simple layout page that shows your app structure – think rectangles and basic colors.
  2. Once the structure is loaded then figure out the user ask i.e. which deep link page was requested. That is if your app supports deep linking, if not then you don’t have to worry about this.
  3. For the page requested let the default page handle routing so that you can centralize the app loading experience.
  4. This is the time when you should start showing either content requested or some sort of loading indicator, if you have to make network connections to get content.
  5. If you have to show loading indicators as it takes time to get content then do not show a general purpose loading bar in middle of the app. this is old and doesn’t give a great experience and helps keep user attention.
  6. One great technique I like is showing the user layout of the app in simple blocks. This helps users to understand how to read/consume content when it becomes available.
  7. Show some simple indicator that things are happening E.g. Facebook uses this simple card animations to show it is loading posts
    Image Credit: Medium.com
  8. How can this be built:
    1. Use simple and static animations to represent this loading indicators
    2. Have different layout loading indicator animations to represent different layouts based on deep links or app orientation.
    3. Resources on default page and the ones used for animations should be static and not data bound. Resources for these animations should be part of the app package so that latency to read these from disk is small as compared to getting these from the web
    4. Fade in content in place of loading indicators as an when it is ready.

As a user of your app: 

  1. I understand the app structure and know how it will layout
  2. I see things happening in progression rather than long halts
  3. I don’t get the impression that app is hung or is not working
  4. As layout starts appearing on the screen with loading indicators I know what and where to expect content when it is available
  5. I am constantly seeing changes on the screen which keeps my attention with the app rather than just killing it and moving on to something else as app takes a long time to load
  6. I don’t see apps name or logo again on its splash screen for a long time and feel like I’m getting to my content quickly.

These are simple changes that can improve your app performance and improve users perceived app performance. Stage your app launch so that it helps you to load content easily and helps users to understand the app in the process.

 

Thanks!