Animations Walt Disney Animation can explain whatever the mind of man can conceive.
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. Clutter also makes it possible to animate non-visual properties if desired.
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. 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.
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: Determine the difference between the start value and the target end value for the property. Multiply the difference by the alpha for the current frame. 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): 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.
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.
Inverting Animations
Problem You want to have an animation exactly mirroring another one that you just played.
Solution Reverse the direction of the ClutterTimeline associated with the animation. For example, here's how to invert an implicit animation which moves an actor along the x axis. The direction of the animation is inverted when the movement along the x axis is completed; it is also inverted if the mouse button is pressed on the actor. First, set up the animation: Next, add a function for inverting the timeline: Then add a function which calls _invert_timeline when the animation completes. More importantly, the callback should stop emission of the "completed" signal by the animation. This prevents the ClutterAnimation underlying the implicit animation from being unreferenced; which in turn allows it to be inverted: Finally, the click callback function uses the same _invert_timeline function if the animation is playing; but if the animation is stopped, it will start it instead:
Discussion If you are using ClutterAnimator rather than implicit animations, clutter_animator_get_timeline() enables you to get the underlying timeline; you could then use the techniques shown above to invert it. ClutterState enables a different approach to "inverting" an animation: rather than having a single animation which you invert, you would define two or more keys for an actor (or set of actors) and transition between them. For the example above, you would define two keys: one for the actor's initial position; and a second for the actor at x = 300.0. You would also define the transition between them: 2000 milliseconds with a CLUTTER_EASE_IN_OUT_CUBIC easing mode. With the states defined, you would then use clutter_state_set_state() inside callbacks to animate the actor between the two x positions. Behind the scenes, ClutterState would handle the animations and timelines for you.
Fading an actor out of or into view
Problem You want to animate an actor so that it fades out of or into view.
Solution Animate the actor's opacity property. You can do this using any of the approaches provided by the animation API. Here's how to fade out an actor (until it's completely transparent) using implicit animations: Here's an example of a rectangle fading out using this animation: Video showing an actor fading out using implicit animations CLUTTER_EASE_OUT_CUBIC is one of the Clutter easing modes; see the introduction for more details about what these are and how to choose one. Here's an example of the transitions you could use to fade an actor in and out using ClutterState: You would then trigger an animated state change as events occur in the application (e.g. mouse button clicks): Here's an example of this animation fading in then out again: Video showing an actor fading in then out using ClutterState ClutterState is most useful where you need to animate an actor backwards and forwards between multiple states (e.g. fade an actor in and out of view). Where you just want to fade an actor in or out once, clutter_actor_animate() is adequate.
Discussion Reducing an actor's transparency to zero does not make it inactive: the actor will still be reactive even if it's not visible (responding to key events, mouse clicks etc.). To make it really "disappear", you could use clutter_actor_hide() once you'd made the actor fully transparent.