2007-07-26 Matthew Allum <mallum@openedhand.com>

* Makefile.am:
        * clutter-animation.sgml:
        * clutter-docs.sgml:
        An initial shot at some general animation documentation.
        Needs some love.
This commit is contained in:
Matthew Allum 2007-07-26 14:00:20 +00:00
parent de27074b48
commit 63ba487c0e
4 changed files with 222 additions and 2 deletions

View File

@ -1,3 +1,11 @@
2007-07-26 Matthew Allum <mallum@openedhand.com>
* Makefile.am:
* clutter-animation.sgml:
* clutter-docs.sgml:
An initial shot at some general animation documentation.
Needs some love.
2007-07-25 Emmanuele Bassi <ebassi@openedhand.com>
* clutter-sections.txt: Rename clutter_behaviour_clear() to

View File

@ -74,13 +74,15 @@ HTML_IMAGES=
# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
content_files= \
subclassing-ClutterActor.sgml \
clutter-animation.sgml \
version.xml
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
# These files must be listed here *and* in content_files
# e.g. expand_content_files=running.sgml
expand_content_files= \
subclassing-ClutterActor.sgml
subclassing-ClutterActor.sgml \
clutter-animation.sgml
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
# Only needed if you are using gtkdoc-scangobj to dynamically query widget

View File

@ -0,0 +1,206 @@
<chapter id="clutter-animations">
<chapterinfo>
<author>
<firstname>Matthew</firstname>
<surname>Allum</surname>
<affiliation>
<address>
<email>mallum@openedhand.com</email>
</address>
</affiliation>
</author>
</chapterinfo>
<title>Creating Animations with Clutter</title>
<para>
Clutter has a powerful and flexible framework for animating
actors. The basis of which is the #ClutterTimeline class which
reprents a period of time in frames. A #ClutterTimeline takes two
parameters, a total number of frames and a frame rate (in frames per
second). Once created, a signal ("new-frame") can be attached and
then on starting (clutter_timeline_start()) the signal callback wil
be called every time a new frame is reached. With the callback also
receiving the current frame number this information can be used to
modify actor properties and thus produce an animation.
</para>
<example id="clutter-timeline-example">
<para>
The following example demonstrates rotating an actor with a timeline.
</para>
<programlisting>
#include &lt;clutter/clutter.h&gt;
void
on_new_frame (ClutterTimeline *timeline,
gint frame_num,
gpointer data)
{
ClutterActor *actor = CLUTTER_ACTOR(data);
clutter_actor_rotate_z (actor, (gdouble)frame_num,
clutter_actor_get_width (actor)/2,
clutter_actor_get_height (actor)/2);
}
int
main (int argc, char *argv[])
{
ClutterTimeline *timeline;
ClutterActor *stage, *actor;
GdkPixbuf *pixbuf;
clutter_init (&amp;argc, &amp;argv);
stage = clutter_stage_get_default ();
pixbuf = gdk_pixbuf_new_from_file ("an-image.png", NULL);
actor = clutter_texture_new_from_pixbuf (pixbuf);
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
clutter_actor_set_position (actor, 100, 100);
timeline = clutter_timeline_new (360, 60); /* num frames, fps */
g_object_set(timeline, "loop", TRUE, NULL); /* have it loop */
g_signal_connect (timeline, "new-frame", G_CALLBACK (on_new_frame), actor);
clutter_actor_show_all (stage);
clutter_timeline_start (timeline);
clutter_main();
return 0;
}
</programlisting>
</example>
<para>
Timelines will 'drop' frames if it appears the application cannot
keep up with the requested framerate. The first and last frames are
guaranteed to be called however. Read the #ClutterTimeline
documentation for more information on how they can be manipulated.
</para>
<para>
Timelines on there own are useful for simple animations but can be
come very unweldy for more complex multiple actor animations. Also
they can lead to much code duplication. The #ClutterAlpha and
#ClutterBehaviour classes build on timelines to offer further
animation functionality and avoid these problems.
</para>
<para>
A #ClutterAlpha is a 'function if time' (note, not pixel alpha!). It is
created by passing both a #ClutterTimelime and a
#ClutterAlphaFunc. The Alpha then produces a value between 0 and
CLUTTER_ALPHA_MAX. This value is dependant on both the position of
the Alpha's supplied timeline and the supplied function used by the
Alpha.
</para>
<para>
Clutter comes with many predefined #ClutterAlphaFunc's including:
#CLUTTER_ALPHA_RAMP_INC - A rising alpha value over time,
#CLUTTER_ALPHA_RAMP_DEC - A decreasing alpha value over time,
#CLUTTER_ALPHA_SINE, A sinewave etc.
</para>
<para>
A #ClutterBehaviour is then '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.
</para>
<example id="clutter-timeline-example">
<para>
The following example demonstrates an ellipse behaviour in action.
</para>
<programlisting>
#include &lt;clutter/clutter.h&gt;
int
main (int argc, char *argv[])
{
ClutterTimeline *timeline;
ClutterBehaviour *behave;
ClutterAlpha *alpha;
ClutterActor *stage, *actor;
GdkPixbuf *pixbuf;
clutter_init (&amp;argc, &amp;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 (100, 26); /* num frames, fps */
g_object_set(timeline, "loop", TRUE, NULL); /* have it loop */
/* Set an alpha func to power 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 */
0.0, /* angle begin */
360.0); /* angle end */
clutter_behaviour_apply (behave, actor);
clutter_actor_show_all (stage);
clutter_timeline_start (timeline);
clutter_main();
return 0;
}
</programlisting>
</example>
<para>
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.
</para>
<para>
Properties of the behaviour, alpha and timeline can be changed on
the fly making animations
</para>
</chapter>

View File

@ -3,6 +3,7 @@
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
<!ENTITY version SYSTEM "version.xml">
<!ENTITY clutter-SubclassingActor SYSTEM "xml/subclassing-ClutterActor.sgml">
<!ENTITY clutter-animation SYSTEM "xml/clutter-animation.sgml">
]>
<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
@ -11,7 +12,7 @@
<releaseinfo>Version &version;</releaseinfo>
<copyright>
<year>2006</year>
<year>2007</year>
<holder>OpenedHand LTD</holder>
</copyright>
@ -105,6 +106,7 @@
<part id="clutteranimation">
<title>Clutter Animation Support</title>
<chapter>
<title>Base Classes</title>
@ -169,6 +171,8 @@
&clutter-SubclassingActor;
&clutter-animation;
</part>
<index>