Jerry Nixon @Work: Mango Sample: 5 Must-Have Animations: Part 2

Jerry Nixon on Windows

Wednesday, January 4, 2012

Mango Sample: 5 Must-Have Animations: Part 2

image_thumb[18]_thumbThis article is part 2 in a three part series.

  1. Part 1: Animation guidelines
  2. Part 2: Animation 1 – 4
  3. Part 3: Animation 5: Delete Item

Must Have Animations

Let’s consider my favorite animations in native Windows Phone animations. I believe that implementing these basic animations can turn your application on its head.

Animation 1: The Turnstile

This animation “peels” off each ListBoxItem in a ListBox one at a time (from bottom to top when transitioning out, from top to bottom when transitioning in) until the list is gone. Animating the ProjectionPlane, this gives the appearance that items are coming toward you.

The start menu uses this animation with the tiles. The application list off the start menu uses this animation with the list items.

This animation takes less than a second. It has two Metro-oriented characteristics. The first is a generic illustration that the page is transitioning (the list is going away) – of course our user doesn’t know what a “page” is. Second, the currently selected item transitions last. It’s subtle, but reassures the user their selection was properly accounted.

There’s a long and complicated article on Code Project if you want to create this animation against tiles. Colin Eberhardt has an article demonstrating items in a ListBox.

Animation 2: Select Item

image_thumb[6]_thumbThis animation selects an item in a list. It is subtle. The selected item is depressed slightly. This is accomplished by using a ScaleTransform to animate the ScaleX and ScaleY properties from 1 to .75 (or some other decimal). It requires the CenterX and CenterY properties to be set to 50% of the ListBoxItem RenderSize Width.

Note: a sophisticated version of this animation leverages the ProjectionPlane to depress the selected item to the left or right side, based on the user’s touch. This additional complexity might be a bit too subtle for my taste – it also provides considerably little value to the user. FYI: Examples of this version are everywhere. It is Email, Calendar, the Application list off the start menu, even the tiles on the Start Menu.


I am basing this example on the user tapping a ListBoxItem in a ListBox. We’ll handle the SelectionChanged event, like this:


In the code above, see the ItemContainerGenerator line? This is the class in a ListBox that let’s us access the selected LIstBoxItem.

Also, see the TODO? This anonymous method let’s us do something, like navigate away from this page, as a result of the user’s selection.


In the code above, see how we are setting the element’s RenderTransform property to a new ScaleTransform? We must assume there is no transform on the item – and we will need it in order to animate it. Our ScaleTransform sets the CenterX and CenterY properties so that it will resize to the center of the existing RenderSize. In the event that you already have such a transform in your XAML, then you will need to make some adjustments. Then we create the initial storyboard and timeline.


In the code above, we are creating two double animations (for a single storyboard). One to animate ScaleX and another to animate ScaleY. We want the element to uniformly animate, so we must animate both. They are basically identical animations. THeir durations are inherited from the duration of the storyboard we set in the previous code.


In the code above, we wrap up this method by handling the Completed event. In this case, I am using an anonymous method as a callback. If you need a refresher on callbacks, check out my previous post. We need to handle the Completed event so we can do something after the animation is finished. Then we call Begin() to start the animation.

Get the code here.

Animation 3: Load Item

image_thumb[17]_thumbimage_thumb[28]_thumbThis animation is so simple and so pleasant. Instead of popping a new page’s content, content is gently raised and revealed. The raising is accomplished through TranslateTransform.Y animation. The reveal is accomplished through Opacity animation. The whole storyboard duration is .75 seconds. It gives the user that the content is “being brought in”.


The Loaded event is the right time to execute this animation. It is important that the LayoutRoot element in XAML (or whatever you call your root element) have its visibility property set to collapsed. This way the reveal is smooth.


In the code above, I am handling the Loaded event, testing the Visibility value and calling ShowHide(), my method to animate the LayoutRoot element. Setting _TopFrom to the page’s height let’s the slide animation cross the full height of the phone. It’s a pleasant effect.


In the code above, I am setting up the TranslateTransform that will let me move the LayoutRoot from the bottom of the screen to the top. I default the Visibility and Opacity property of the LayoutRoot – then later I will start the animation from those values.


In the code above, I am setting up two animations. The first is a double animation for Opacity. This animation will animate from opacityFrom to opacityTo (both method arguments). The second is a double animation for the X property of the TranslateTransform. Zero is the original position.


In the code above, I am handling the Completed event. Because ShowHide() is a generic method for both showing and hiding, it uses a callback. Since we are discussing the Item Load animation to reveal the content, we know that there is nothing to do in the callback other than just let it load.

Get all the code here.

Animation 4: Unload Item

The Unload Item animation is the opposite of the Load Item animation discussed above. Instead of revealing the item from the bottom, it dissolves the content to the bottom. The relationship between the two and the consistency with the rest of the system is very communicative to the user.


In the code above, notice that this is a simple inverse of the Reveal logic. We are sending the top to the bottom of the page, and animating Opacity to 0. When it is done, we implement the callback to GoBack(). Note that in your code GoBack() may not be a valid action. Update this code to fit your app.

Get all the code here.


Continue to Part 3.