Clutter の アニメーションを使う
前回の ClutterTimeline の若干の修正でアニメーションができます。
実は、機能までのサンプルでは、 ClutterActor の派生クラスの宣言時に、 ClutterStage の場合は、
ClutterStage *stage;
などとしていたのですが、サンプルを見ると、
ClutterActor *stage;
として、ClutterStage の関数を使う場合は、
CLUTTER_STAGE (stage)
のように型変換して使用するのが一般的みたいなので、そのように変更します。
はじめは C です。
#include <clutter/clutter.h> void on_completed (ClutterTimeline *timeline, gpointer user_data) { ClutterActor *actor; gfloat x, y; actor = * (ClutterActor**)user_data; clutter_actor_get_position (actor, &x, &y); clutter_actor_save_easing_state (actor); if (x > 100) { clutter_actor_set_position (actor, 100, 100); } else { clutter_actor_set_position (actor, 200, 200); } clutter_actor_restore_easing_state (actor); } int main (int argc, char *argv[]) { ClutterActor *stage, *actor; ClutterTimeline *timeline; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return 1; stage = clutter_stage_new (); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); actor = clutter_actor_new (); clutter_actor_set_background_color (actor, clutter_color_get_static (CLUTTER_COLOR_RED)); clutter_actor_set_size (actor, 100, 100); clutter_actor_set_position (actor, 100, 100); timeline = clutter_timeline_new (2000); clutter_timeline_set_repeat_count (timeline, -1); g_signal_connect (timeline, "completed", G_CALLBACK (on_completed), &actor); clutter_timeline_start (timeline); clutter_actor_add_child (stage, actor); clutter_actor_show (stage); clutter_main (); return 0; }
肝心なのは、Actor の移動の前後を、 clutter_actor_save_easing_state() clutter_actor_restore_easing_state() で囲むことです。このようにすると、デフォルトのアニメーションで、変化の軌跡をアニメーションで動かしてくれます。
次は Gjs です。
#! /usr/bin/env gjs const Clutter = imports.gi.Clutter; function on_completed (timeline) { let [x, y] = actor.get_position(); actor.save_easing_state(); if (x > 100) { actor.set_position(100, 100); } else { actor.set_position(200, 200); } actor.save_easing_state(); } Clutter.init(null); let stage = new Clutter.Stage(); stage.connect('destroy', Clutter.main_quit); let actor = new Clutter.Actor(); actor.set_background_color(Clutter.Color.get_static (Clutter.StaticColor.RED)); actor.set_size(100, 100); actor.set_position(100, 100); let timeline = new Clutter.Timeline({duration:2000}); timeline.set_repeat_count(-1); timeline.connect('completed', on_completed); timeline.start(); stage.add_child(actor); stage.show(); Clutter.main();
こちらは、説明不要ですね。