## Behaviours

With a large application containing many animations, the use of just timelines can become unwieldy and difficult to manage, with much code duplication in the "new-frame" handlers that can require over-complex code changes for minor animation modifications. To ease these problems the ClutterAlpha and ClutterBehaviour classes were created.

ClutterAlpha and ClutterBehaviour attempt to generalise the "new-frame" function by defining common actions (or behaviours) that can be quickly modified, applied to multiple actors or mixed on a single actor.

A ClutterAlpha is a 'function of time' (and does not refer to the alpha channel of a RGBA color). It is created by referencing a source timeline and an "easing mode" whichproduces a value between -1.0 and 2.0 depending on the progress of the timeline. Clutter provides various easing modes, as described by the ClutterAnimationMode enumeration. It is also possible to register new animation modes using the function `clutter_alpha_register_func()` or to provide a custom ClutterAlphaFunc for a specific ClutterAlpha instance.

A ClutterBehaviour is created with a ClutterAlpha and a set of parameters for whatever the behaviour modifies in an actor. The value of a ClutterAlpha during the animation is then mapped to a value for the behaviour parameters and then applied on the actors referenced by the ClutterBehaviour. With the ClutterAlpha's underlying timeline playing the produced value will change and the behaviour will animate an actor.

A ClutterBehaviour is effectively 'driven' by a supplied ClutterAlpha and when then applied to an actor it will modify a visual property or feature of the actor dependant on the Alpha's value. For example, a path-based behaviour applied to an actor will alter its position along a ClutterPath, depending on the current alpha value over time. The actual progress of the motion will depend on the chosen "easing mode".

Multiple behaviours can of course be applied to an actor as well as a single behaviour being applied to multiple actors. The separation of timelines, alphas and behaviours allows for a single timeline to drive many behaviours each potentially using different alpha functions. Behaviour parameters can also be changed on the fly.

Figure 5. Effects of alpha functions on a path

> The actors position between the path's end points directly correlates to the ClutterAlpha's current alpha value driving the behaviour. With the ClutterAlpha's animation mode set to `CLUTTER_LINEAR` the actor will follow the path at a constant velocity, but when changing to `CLUTTER_EASE_SINE_IN_OUT` the actor initially accelerates before quickly decelerating.

The behaviours included in Clutter are:

ClutterBehaviourDepth | Changes the depth of actors
ClutterBehaviourEllipse | Moves actors along an elliptical path
ClutterBehaviourOpacity | Changes the opacity of actors
ClutterBehaviourPath | Moves actors along a path
ClutterBehaviourRotate | Rotates actors along an axis
ClutterBehaviourScale | Changes the scaling factors of actors

Example 10. Using a ClutterBehaviour

The following example demonstrates an ellipse behaviour in action.

    #include <clutter/clutter.h>

    int
    main (int argc, char *argv[])
    {
      ClutterTimeline  *timeline;
      ClutterBehaviour *behave;
      ClutterAlpha     *alpha;
      ClutterActor     *stage, *actor;
      GdkPixbuf        *pixbuf;

      clutter_init (&argc, &argv);

      stage = clutter_stage_get_default ();

      actor = clutter_texture_new_from_file ("ohpowers.png, NULL);
      clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);

      /* set up the animation to be 4 seconds long */
      timeline = clutter_timeline_new (4000);
      clutter_timeline_set_loop (timeline, TRUE);

      /* set up a sinusoidal easing mode to power the behaviour; the
       * alpha will take a reference on the timeline so we can safely
       * release the reference we hold
       */
      alpha = clutter_alpha_new_full (timeline, CLUTTER_EASE_SINE_IN_OUT);
      g_object_unref (timeline);

      /* the behaviour will own the alpha by sinking its floating
       * reference (if needed)
       */
      behave = clutter_behaviour_ellipse_new (alpha,
    					  200,               /* center x */
    					  200,               /* center y */
    					  400,               /* width */
    					  300,               /* height */
    					  CLUTTER_ROTATE_CW, /* direction */
    					  0.0,               /* initial angle */
    					  360.0);            /* final angle */

      clutter_behaviour_apply (behave, actor);

      clutter_actor_show_all (stage);

      clutter_timeline_start (timeline);

      clutter_main();

      /* clean up; behaviours are top-level objects */
      g_object_unref (behave);

      return 0;
    }

### Note

The parameters of a ClutterBehaviour can be changed whilst a animation is running.

There can be many ClutterAlpha's attached to a single timeline. There can be many behaviours for a ClutterAlpha. There can be many behaviours applied to an actor. A ClutterScore can be used to chain many behaviours together.

### Warning

Combining behaviours that effect the same actor properties (i.e two separate paths) will cause unexpected results. The values will not be merged in any way with only the last applied behaviour taking precedence.

### Note

Tips for implementing a new behaviour can be found here.