August 3rd, 2016

Creating Animations with Xamarin.Forms

Animations are a great way to add polish to your user interface and make your app stand out. Xamarin.Forms includes its own animation infrastructure that allows for easy creation of simple animations, while also being versatile enough to create complex animations. The Xamarin.Forms animation classes target different properties of visual elements, with a typical animation progressively changing a property from one value to another over a period of time. Note that there is no XAML interface for the Xamarin.Forms animation classes. However, animations can be encapsulated in behaviors and then referenced from XAML.

In this blog post, I’m going to explore creating and cancelling animations using the ViewExtensions class in Xamarin.Forms to create compelling animations that run on iOS, Android, and Windows.

Introduction to Animations

The ViewExtensions class provides a number of extension methods that can be used to create simple animations that rotate, scale, translate, and fade VisualElement instances. By default, each animation takes 250 milliseconds. However, a duration for each animation can be specified when creating the animation.

The extension methods provided by the ViewExtensions class are TranslateTo, ScaleTo, RelScaleTo, RotateTo, RelRotateTo, RotateXTo, RotateYTo, and FadeTo. Each method is asynchronous and returns a Task<bool> object. The return value is false if the animation completes, and true if the animation is cancelled. The animation methods should typically be used with the await operator, which makes it possible to easily determine when an animation has completed. However, if there’s a requirement to let an animation complete in the background, then the await operator can be omitted. In this scenario, the animation extension methods will quickly return after initiating the animation, with the animation occurring in the background.

The ViewExtensions class also includes a CancelAnimations method that can be used to cancel any animations.

Performing Simple Animations

Each extension method in the ViewExtensions implements a single animation operation that progressively changes a property from one value to another value over a period of time.

Rotation

The following code example from the sample application demonstrates using the RotateTo method to animate the Rotation property of an Image:

await image.RotateTo (360, 2000);

This code animates the Image instance by rotating up to 360 degrees over 2 seconds (2000 milliseconds). The RotateTo method obtains the current Rotation property value for the start of the animation, and then rotates from that value to its first argument (360).

In addition, Xamarin.Forms supports relative rotation and rotation with anchors. For more information, see Relative Rotation and Scaling and Rotation with Anchors.

Scaling

The following code example from the sample application demonstrates using the ScaleTo method to animate the Scale property of an Image:

await image.ScaleTo (2, 2000);

This code animates the Image instance by scaling up to twice its size over 2 seconds (2000 milliseconds). The ScaleTo method obtains the current Scale property value (default value of 1) for the start of the animation, and then scales from that value to its first argument (2). This has the effect of expanding the size of the image to twice its size.

In addition, Xamarin.Forms supports relative scaling and scaling with anchors. For more information, see Relative Scaling and Scaling and Rotation with Anchors.

Translation

The following code example from the sample application demonstrates using the TranslateTo method to animate the TranslationX and TranslationY properties of an Image:

await image.TranslateTo (-100, -100, 1000);

This code animates the Image instance by translating it horizontally and vertically over 1 second (1000 milliseconds). The TranslateTo method simultaneously translates the image 100 pixels to the left, and 100 pixels upwards. This is because the first and second arguments are both negative numbers. Providing positive numbers would translate the image to the right, and down.

Fading

The following code example from the sample application demonstrates using the FadeTo method to animate the Opacity property of an Image:

await image.FadeTo (1, 4000);

This code animates the Image instance by fading it in over 4 seconds (4000 milliseconds). The FadeTo method obtains the current Opacity property value for the start of the animation, and then fades in from that value to its first argument (1).

Cancelling Animations

An application can cancel one or more animations with a call to the static ViewExtensions.CancelAnimations method, as demonstrated in the following code example from the sample application:

ViewExtensions.CancelAnimations (image);

This will immediately cancel all animations that are currently running on the Image instance.

Compound Animations

It’s also possible to create sequential animations with subsequent animation methods executing after the previous method has completed. These can be created with the await operator, as demonstrated in the following code example from the sample application:

await image.TranslateTo (-100, 0, 1000);    // Move image left
await image.TranslateTo (-100, -100, 1000); // Move image up
await image.TranslateTo (100, 100, 2000);   // Move image diagonally down and right
await image.TranslateTo (0, 100, 1000);     // Move image left
await image.TranslateTo (0, 0, 1000);       // Move image up

In this example, the Image is translated over 6 seconds (6000 milliseconds). The translation of the Image uses five translation animations, with the await operator indicating that each animation executes sequentially. Therefore, subsequent animation methods execute after the previous method has completed.

Composite Animations

Composite animations can be created by mixing awaited and non-awaited animations and using the Task.WhenAny and Task.WhenAll methods to run multiple asynchronous methods concurrently. Both methods return a Task object and accept a collection of methods that each return a Task object.

The following code example, from the sample application, demonstrates using the Task.WhenAll method to run multiple asynchronous animation methods concurrently:

// 10 minute animation
uint duration = 10 * 60 * 1000;

await Task.WhenAll (
  image.RotateTo (307 * 360, duration),
  image.RotateXTo (251 * 360, duration),
  image.RotateYTo (199 * 360, duration)
);

In this example, the Task.WhenAll method call contains three tasks, each of which executes over 10 minutes. Each Task makes a different number of 360 degree rotations: 307 rotations for RotateTo, 251 rotations for RotateXTo, and 199 rotations for RotateYTo. These values are prime numbers, therefore ensuring that the rotations aren’t synchronized and hence won’t result in repetitive patterns.

The following screenshots show the multiple rotations in progress on each platform:multiple-rotations

Controlling Velocity Changes

The animation extension methods in the ViewExtensions class allow an easing function to be specified as the final method parameter. The easing function, specified by the Easing class, controls how an animation speeds up or slows down as it runs.

The following code example demonstrates specifying different easing functions in a compound animation:

await image.TranslateTo(0, 200, 2000, Easing.BounceIn);
await image.ScaleTo(2, 2000, Easing.CubicIn);
await image.RotateTo(360, 2000, Easing.SinInOut);
await image.ScaleTo(1, 2000, Easing.CubicOut);
await image.TranslateTo(0, -200, 2000, Easing.BounceOut);

By specifying an easing function for an animation, the animation velocity becomes non-linear and produces the effect provided by the easing function. For example, the BounceIn easing function bounces the animation at the beginning, the CubicIn easing function slowly accelerates the animation, and the SinInOut easing function smoothly accelerates the animation at the beginning and smoothly decelerates the animation at the end.

Omitting an easing function when creating an animation causes the animation to use the default Linear easing function, which produces a linear velocity.

In addition, custom easing functions can be created. For more information, see Custom Easing Functions.

Wrapping Up

The ViewExtensions class provides extension methods that can be used to create simple animations that rotate, scale, translate, and fade VisualElement instances. In addition, the ViewExtensions class also includes a CancelAnimations method that can be used to cancel any animations.

The animation extension methods in the ViewExtensions class also allow an easing function to be specified as the final method parameter. The easing function, specified by the Easing class, controls how an animation speeds up or slows down as it runs.

For more information, see Animation.

Author

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Elijah Black

    This was helpful, thanks 🙂