mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 01:50:42 -05:00
cookbook: Refactored reusable animation example
Extracted the animation into its own JSON definition, then create a new script and get the animation each time a rectangle is clicked. Removes the need to reparent onto the background and copy property values to the rectangle after the animation, and generally much cleaner.
This commit is contained in:
parent
acc28cf60c
commit
d4190cbf8c
63
doc/cookbook/examples/animations-reuse-animation.json
Normal file
63
doc/cookbook/examples/animations-reuse-animation.json
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type" : "ClutterGroup",
|
||||||
|
"id" : "rig"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"type" : "ClutterAnimator",
|
||||||
|
"id" : "bounce",
|
||||||
|
"timeline" : {
|
||||||
|
"type" : "ClutterTimeline",
|
||||||
|
"id" : "bounce_timeline",
|
||||||
|
"duration" : 2500
|
||||||
|
},
|
||||||
|
|
||||||
|
"properties" : [
|
||||||
|
{
|
||||||
|
"object" : "rig",
|
||||||
|
"name" : "x",
|
||||||
|
"ease-in" : true,
|
||||||
|
"keys" : [
|
||||||
|
[ 0.2, "easeOutCubic", 100.0 ],
|
||||||
|
[ 0.6, "easeOutCubic", 150.0 ],
|
||||||
|
[ 0.8, "linear", 350.0 ],
|
||||||
|
[ 1.0, "linear", 500.0 ]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"object" : "rig",
|
||||||
|
"name" : "y",
|
||||||
|
"ease-in" : true,
|
||||||
|
"keys" : [
|
||||||
|
[ 0.2, "easeOutCubic", 200.0 ],
|
||||||
|
[ 0.6, "easeOutBounce", 200.0 ],
|
||||||
|
[ 0.8, "linear", 200.0 ],
|
||||||
|
[ 1.0, "linear", 0.0 ]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"object" : "rig",
|
||||||
|
"name" : "scale-x",
|
||||||
|
"ease-in" : true,
|
||||||
|
"keys" : [
|
||||||
|
[ 0.2, "easeOutElastic", 2.0 ],
|
||||||
|
[ 0.6, "easeOutBounce", 4.0 ],
|
||||||
|
[ 0.8, "linear", 4.0 ],
|
||||||
|
[ 1.0, "linear", 1.0 ]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"object" : "rig",
|
||||||
|
"name" : "scale-y",
|
||||||
|
"ease-in" : true,
|
||||||
|
"keys" : [
|
||||||
|
[ 0.2, "easeOutElastic", 2.0 ],
|
||||||
|
[ 0.6, "easeOutBounce", 4.0 ],
|
||||||
|
[ 0.8, "linear", 4.0 ],
|
||||||
|
[ 1.0, "linear", 1.0 ]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
53
doc/cookbook/examples/animations-reuse-ui.json
Normal file
53
doc/cookbook/examples/animations-reuse-ui.json
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type" : "ClutterStage",
|
||||||
|
"id" : "stage",
|
||||||
|
"width" : 550,
|
||||||
|
"height" : 400,
|
||||||
|
"color" : "#333355ff",
|
||||||
|
|
||||||
|
"signals" : [
|
||||||
|
{ "name" : "destroy", "handler" : "clutter_main_quit" }
|
||||||
|
],
|
||||||
|
|
||||||
|
"children" : [
|
||||||
|
|
||||||
|
{
|
||||||
|
"type" : "ClutterRectangle",
|
||||||
|
"id" : "rect1",
|
||||||
|
"color" : "red",
|
||||||
|
"width" : 50,
|
||||||
|
"height" : 50,
|
||||||
|
"reactive" : true,
|
||||||
|
"signals" : [
|
||||||
|
{ "name" : "button-press-event", "handler" : "foo_button_pressed_cb" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"type" : "ClutterRectangle",
|
||||||
|
"id" : "rect2",
|
||||||
|
"color" : "blue",
|
||||||
|
"width" : 50,
|
||||||
|
"height" : 50,
|
||||||
|
"reactive" : true,
|
||||||
|
"signals" : [
|
||||||
|
{ "name" : "button-press-event", "handler" : "foo_button_pressed_cb" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"type" : "ClutterRectangle",
|
||||||
|
"id" : "rect3",
|
||||||
|
"color" : "green",
|
||||||
|
"width" : 50,
|
||||||
|
"height" : 50,
|
||||||
|
"reactive" : true,
|
||||||
|
"signals" : [
|
||||||
|
{ "name" : "button-press-event", "handler" : "foo_button_pressed_cb" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
@ -1,12 +1,38 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
|
#define UI_FILE "animations-reuse-ui.json"
|
||||||
|
#define ANIMATION_FILE "animations-reuse-animation.json"
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_load_script (ClutterScript *script,
|
||||||
|
gchar *filename)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
clutter_script_load_from_file (script, filename, &error);
|
||||||
|
|
||||||
|
if (error != NULL)
|
||||||
|
{
|
||||||
|
g_critical ("Error loading ClutterScript file %s\n%s", filename, error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
foo_button_pressed_cb (ClutterActor *actor,
|
foo_button_pressed_cb (ClutterActor *actor,
|
||||||
ClutterEvent *event,
|
ClutterEvent *event,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
ClutterScript *script = CLUTTER_SCRIPT (user_data);
|
ClutterScript *ui = CLUTTER_SCRIPT (user_data);
|
||||||
|
ClutterStage *stage = CLUTTER_STAGE (clutter_script_get_object (ui, "stage"));
|
||||||
|
|
||||||
|
ClutterScript *script = clutter_script_new ();
|
||||||
|
|
||||||
|
_load_script (script, ANIMATION_FILE);
|
||||||
|
|
||||||
ClutterAnimator *bounce;
|
ClutterAnimator *bounce;
|
||||||
ClutterActor *rig;
|
ClutterActor *rig;
|
||||||
@ -18,13 +44,22 @@ foo_button_pressed_cb (ClutterActor *actor,
|
|||||||
"bounce", &bounce,
|
"bounce", &bounce,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/* don't allow animation to be reused until it is complete */
|
/* remove the button press handler */
|
||||||
if (clutter_timeline_is_playing (bounce_timeline))
|
g_signal_handlers_disconnect_matched (actor,
|
||||||
return TRUE;
|
G_SIGNAL_MATCH_FUNC,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
foo_button_pressed_cb,
|
||||||
|
NULL);
|
||||||
|
|
||||||
clutter_actor_set_position (rig, 0, 0);
|
/* add a handler to clean up when the animation completes */
|
||||||
|
g_signal_connect_swapped (bounce_timeline,
|
||||||
|
"completed",
|
||||||
|
G_CALLBACK (g_object_unref),
|
||||||
|
script);
|
||||||
|
|
||||||
clutter_actor_set_scale (rig, 1.0, 1.0);
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), rig);
|
||||||
|
|
||||||
clutter_actor_reparent (actor, rig);
|
clutter_actor_reparent (actor, rig);
|
||||||
|
|
||||||
@ -33,72 +68,13 @@ foo_button_pressed_cb (ClutterActor *actor,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the actor's position to the rig's position
|
|
||||||
* but parented to the background;
|
|
||||||
* remove the click handler so the rectangle can't be animated again
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
_move_to_background_cb (ClutterActor *actor,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
ClutterActor *background = CLUTTER_ACTOR (user_data);
|
|
||||||
|
|
||||||
gfloat x, y;
|
|
||||||
clutter_actor_get_position (clutter_actor_get_parent (actor), &x, &y);
|
|
||||||
|
|
||||||
gdouble scale_x, scale_y;
|
|
||||||
clutter_actor_get_scale (clutter_actor_get_parent (actor), &scale_x, &scale_y);
|
|
||||||
|
|
||||||
clutter_actor_reparent (actor, background);
|
|
||||||
|
|
||||||
clutter_actor_set_position (actor, x, y);
|
|
||||||
clutter_actor_set_scale (actor, scale_x, scale_y);
|
|
||||||
|
|
||||||
g_signal_handlers_disconnect_matched (actor,
|
|
||||||
G_SIGNAL_MATCH_FUNC,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
foo_button_pressed_cb,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
foo_rig_animation_complete_cb (ClutterTimeline *timeline,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
ClutterScript *script = CLUTTER_SCRIPT (user_data);
|
|
||||||
|
|
||||||
ClutterContainer *rig;
|
|
||||||
ClutterActor *background;
|
|
||||||
|
|
||||||
clutter_script_get_objects (script,
|
|
||||||
"rig", &rig,
|
|
||||||
"background", &background,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
clutter_container_foreach (rig,
|
|
||||||
CLUTTER_CALLBACK (_move_to_background_cb),
|
|
||||||
background);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
clutter_init (&argc, &argv);
|
clutter_init (&argc, &argv);
|
||||||
|
|
||||||
gchar *filename = "animations-reuse.json";
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
ClutterScript *script = clutter_script_new ();
|
ClutterScript *script = clutter_script_new ();
|
||||||
clutter_script_load_from_file (script, filename, &error);
|
_load_script (script, UI_FILE);
|
||||||
|
|
||||||
if (error != NULL)
|
|
||||||
{
|
|
||||||
g_critical ("Error loading ClutterScript file %s\n%s", filename, error->message);
|
|
||||||
g_error_free (error);
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
clutter_script_connect_signals (script, script);
|
clutter_script_connect_signals (script, script);
|
||||||
|
|
||||||
|
@ -1,124 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"type" : "ClutterStage",
|
|
||||||
"id" : "stage",
|
|
||||||
"width" : 550,
|
|
||||||
"height" : 400,
|
|
||||||
"color" : "#333355ff",
|
|
||||||
|
|
||||||
"signals" : [
|
|
||||||
{ "name" : "destroy", "handler" : "clutter_main_quit" }
|
|
||||||
],
|
|
||||||
|
|
||||||
"children" : [
|
|
||||||
|
|
||||||
{
|
|
||||||
"type" : "ClutterRectangle",
|
|
||||||
"id" : "rect1",
|
|
||||||
"color" : "red",
|
|
||||||
"width" : 50,
|
|
||||||
"height" : 50,
|
|
||||||
"reactive" : true,
|
|
||||||
"signals" : [
|
|
||||||
{ "name" : "button-press-event", "handler" : "foo_button_pressed_cb" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"type" : "ClutterRectangle",
|
|
||||||
"id" : "rect2",
|
|
||||||
"color" : "blue",
|
|
||||||
"width" : 50,
|
|
||||||
"height" : 50,
|
|
||||||
"reactive" : true,
|
|
||||||
"signals" : [
|
|
||||||
{ "name" : "button-press-event", "handler" : "foo_button_pressed_cb" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"type" : "ClutterRectangle",
|
|
||||||
"id" : "rect3",
|
|
||||||
"color" : "green",
|
|
||||||
"width" : 50,
|
|
||||||
"height" : 50,
|
|
||||||
"reactive" : true,
|
|
||||||
"signals" : [
|
|
||||||
{ "name" : "button-press-event", "handler" : "foo_button_pressed_cb" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"type" : "ClutterGroup",
|
|
||||||
"id" : "background"
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"type" : "ClutterGroup",
|
|
||||||
"id" : "rig"
|
|
||||||
}
|
|
||||||
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"type" : "ClutterAnimator",
|
|
||||||
"id" : "bounce",
|
|
||||||
"timeline" : {
|
|
||||||
"type" : "ClutterTimeline",
|
|
||||||
"id" : "bounce_timeline",
|
|
||||||
"duration" : 3000,
|
|
||||||
|
|
||||||
"signals" : [
|
|
||||||
{ "name" : "completed", "handler" : "foo_rig_animation_complete_cb" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
"properties" : [
|
|
||||||
{
|
|
||||||
"object" : "rig",
|
|
||||||
"name" : "x",
|
|
||||||
"ease-in" : true,
|
|
||||||
"keys" : [
|
|
||||||
[ 0.2, "easeOutCubic", 100.0 ],
|
|
||||||
[ 0.6, "easeOutCubic", 150.0 ],
|
|
||||||
[ 0.8, "linear", 350.0 ],
|
|
||||||
[ 1.0, "linear", 500.0 ]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"object" : "rig",
|
|
||||||
"name" : "y",
|
|
||||||
"ease-in" : true,
|
|
||||||
"keys" : [
|
|
||||||
[ 0.2, "easeOutCubic", 200.0 ],
|
|
||||||
[ 0.6, "easeOutBounce", 200.0 ],
|
|
||||||
[ 0.8, "linear", 200.0 ],
|
|
||||||
[ 1.0, "linear", 0.0 ]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"object" : "rig",
|
|
||||||
"name" : "scale-x",
|
|
||||||
"ease-in" : true,
|
|
||||||
"keys" : [
|
|
||||||
[ 0.2, "easeOutElastic", 2.0 ],
|
|
||||||
[ 0.6, "easeOutBounce", 4.0 ],
|
|
||||||
[ 0.8, "linear", 4.0 ],
|
|
||||||
[ 1.0, "linear", 1.0 ]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"object" : "rig",
|
|
||||||
"name" : "scale-y",
|
|
||||||
"ease-in" : true,
|
|
||||||
"keys" : [
|
|
||||||
[ 0.2, "easeOutElastic", 2.0 ],
|
|
||||||
[ 0.6, "easeOutBounce", 4.0 ],
|
|
||||||
[ 0.8, "linear", 4.0 ],
|
|
||||||
[ 1.0, "linear", 1.0 ]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
Loading…
Reference in New Issue
Block a user