Chapter 5. Animations

Animation can explain whatever the mind of man can conceive.

Walt Disney

1. Introduction

Clutter actors have a variety of properties (position, size, rotation in 3D space, scale, opacity) which govern their visual appearance in the UI. They may also have constraints on how they are aligned and/or positioned relative to each other.

The Clutter animation API provides a means of changing properties and constraints as a function of time: moving, scaling, rotating, changing opacity and colour, modifying postional constraints, etc.

Note

Clutter also makes it possible to animate non-visual properties if desired.

1.1. High level overview

Here are the main concepts behind animation in Clutter:

  • An animation changes one or more properties of one or more actors over time: their rotation in a particular dimension (x, y, z), scale, size, opacity etc.

  • An animation has an associated timeline. Think of this as analogous to the "thing" you're controlling when you watch a video on the internet: it's what you control with the play/pause button and what is measured by the bar showing how far through the video you are. As with the controls on a video player, you can play/pause/skip a Clutter timeline; you can also rewind it, loop it, and play it backwards.

    Note

    If a timeline is reversed, the progress along the timeline is still measured the same way as it is in the forward direction: so if you start from the end of the timeline and run it backwards for 75% of its length, the progress is reported as 0.25 (i.e. 25% of the way from the start of the timeline).

  • The duration of a timeline (e.g. 500 milliseconds, 1 second, 10 seconds) specifies how long its animation will last. The timeline can be inspected to find out how much of it has elapsed, either as a value in milliseconds or as a fraction (between 0 and 1) of the total length of the timeline.

  • An animation is divided into frames. The number of frames which make up the animation isn't constant: it depends on various factors, like how powerful your machine is, the state of the drivers for your hardware, and the load on he system. So you won't always get the same number of frames in an animation of a particular duration.

  • The change to a property in an animation occurs over the course of the timeline: the start value of the property heads toward some target value. When it reaches the end of the timeline, the property should have reached the target value.

  • Exactly how the property changes over the course of the timeline is governed by an alpha. This is the trickiest idea to explain, so it has its own section below.

1.2. Alphas

An alpha is generated for each frame of the animation. The alpha varies between -1.0 and 2.0, and changes during the course of the animation's timeline; ideally, the value should start at 0.0 and reach 1.0 by the end of the timeline.

The alpha for any given frame of the animation is determined by an alpha function. Usually, the alpha function will return a value based on progress along the timeline. However, the alpha function doesn't have to respect or pay attention to the timeline: it can be entirely random if desired.

To work out the value of a property at a given frame somewhere along the timeline for a given alpha:

  1. Determine the difference between the start value and the target end value for the property.

  2. Multiply the difference by the alpha for the current frame.

  3. Add the result to the start value.

The shape of the plot of the alpha function over time is called its easing mode. Clutter provides various modes ranging from CLUTTER_LINEAR (the alpha value is equal to progress along the timeline), to modes based on various polynomial and exponential functions, to modes providing elastic and bounce shapes. See the ClutterAlpha documentation for examples of the shapes produced by these functions. There is also a good interactive demo of the modes on Robert Penner's site.

Most of the time, you can use the built-in Clutter easing modes to get the kind of animation effect you want. However, in some cases you may want to provide your own alpha function. Here's an example (based on the quintic ease in mode from clutter-alpha.c):

static gdouble
_alpha_ease_in_sextic (ClutterAlpha *alpha,
                       gpointer      dummy G_GNUC_UNUSED)
 {
  ClutterTimeline *timeline = clutter_alpha_get_timeline (alpha);
  gdouble p = clutter_timeline_get_progress (timeline);

  return p * p * p * p * p * p;
}

An alpha function just has to have a specified method signature and return a gdouble value when called. As stated above, you'd typically base the return value on the timeline progress; the function above shows how you get the timeline associated with the alpha, so you can apply the alpha function to it.

1.3. Clutter's animation API

All of the animation approaches in Clutter use the same basic underpinnings (as explained above), but the API provides varying levels of abstraction and/or ease of use on top of those underpinnings.

  • Implicit animations (created using clutter_actor_animate() and related functions) are useful where you want to apply a simple or one-off animation to an actor. They enable you to animate one or more properties using a single easing mode; however, you only specify the target values for the properties you're animating, not the start values.

  • ClutterAnimator provides support for declarative animations (defined using ClutterScript). You can animate multiple actors with this approach, and have more control over the easing modes used during an animation: while implicit animations only allow a single easing mode for all properties, ClutterAnimator supports multiple easing modes for each property; key frames are used to indicate where in the animation each easing mode should be applied.

  • ClutterState enables you to describe states: property values across one or more actors, plus the easing modes used to transition to those values. It can also be combined with ClutterAnimator for finer grained definition of transitions if desired.

    States are particularly useful if you need actors to animate between a known set of positions/sizes/opacities etc. during their lifecycles (e.g. animating a list of items in a menu, or for animations in a picture viewer where you click on thumbnails to display a full view of a photograph).

The recipes in this section show when and where it is appropriate to use each of these approaches.