Clutter 0.8.2 Reference Manual |
---|
With a large application containing many animations, the use of just timelines can become unweldy 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 simply a 'function of time' (not pixel alpha!). It is created by referencing a source timeline and a function which produces a value between 0 and %CLUTTER_ALPHA_MAX dependant on the timeline position. Various prebuilt alpha functions are included with Clutter these include
%CLUTTER_ALPHA_RAMP_INC |
Increasing ramp function |
%CLUTTER_ALPHA_RAMP_DEC |
Decreasing ramp function |
%CLUTTER_ALPHA_RAMP |
Full ramp function |
%CLUTTER_ALPHA_SINE_INC |
Increasing sine function |
%CLUTTER_ALPHA_SINE_DEC |
Decreasing sine function |
%CLUTTER_ALPHA_SINE_HALF |
Half sine function |
%CLUTTER_ALPHA_SINE |
Full sine function |
%CLUTTER_ALPHA_SQUARE |
Square waveform ("step") function |
%CLUTTER_ALPHA_SMOOTHSTEP_INC |
Increasing smooth transition step function |
%CLUTTER_ALPHA_SMOOTHSTEP_DEC |
Decreasing smooth transition step function |
%CLUTTER_ALPHA_EXP_INC |
Increasing exponential function |
%CLUTTER_ALPHA_EXP_DEC |
Decreasing exponential function |
A Behaviour is created with a #ClutterAlpha and a set of limits for whatever the behaviour modifys actor wise. The current #ClutterAlpha value is then mapped to a value between these limits and this value set on any applied actors. With the #ClutterAlpha's underlying timeline playing the produced value will change and the behaviour will animate the 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 the path dependant on the current alpha value over time. The actual motion will depend on the chosen #ClutterAlphaFunc - a #CLUTTER_ALPHA_RAMP_INC making it to move at constant speed along the path, a #CLUTTER_ALPHA_SINE making it alternate from one end of the path to the other with non constant speed.
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 function set to %CLUTTER_ALPHA_RAMP_INC the actor will follow the path at a constant velocity, but when changing to %CLUTTER_ALPHA_SINE_INC the actor initially accelerates before quickly decelerating.
The behaviours included in Clutter are
#ClutterBehaviourBspline |
Moves actors along a B-spline path |
#ClutterBehaviourDepth |
Changes the depth of actors |
#ClutterBehaviourEllipse |
Moves actors along an ellipsis |
#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.
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 (); pixbuf = gdk_pixbuf_new_from_file ("ohpowers.png", NULL); actor = clutter_texture_new_from_pixbuf (pixbuf); clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor); timeline = clutter_timeline_new_for_duration (4000); /* milliseconds */ clutter_timeline_set_loop (timeline, TRUE); /* Set an alpha func to power the behaviour */ alpha = clutter_alpha_new_full (timeline, CLUTTER_ALPHA_SINE, NULL, NULL); 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 */ g_object_unref (behave); g_object_unref (timeline); return 0; }
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 behaviour together.
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 essentially a the last applied behaviour taking precedence.
Tips for implementing a new behaviour can be found here.