Clutter で拡大。さらに、アニメーション

今回は ClutterActor の scale を変更して拡大縮小します。これは簡単なので、ついでに、clutter_actor_set_easing_duration() (アニメーション時間の設定)と clutter_actor_set_easing_mode() (アニメーションモード)を使って、リニアじゃない動きをさせます。easing_mode は gnome-shell の tween と対応するので、いろいろ試してみてください。
最初は、 C です。clutter_actor_set_scale() は、縦横比で指定し、 1.0 はそのまま、 2.0 だと 2倍になるといった感じです。

#include <clutter/clutter.h>

void
on_completed (ClutterTimeline *timeline, gpointer user_data) 
{
    ClutterActor *actor;
    gdouble scale_x, scale_y;
    
    actor = * (ClutterActor**)user_data;
    clutter_actor_get_scale (actor, &scale_x, &scale_y);
    clutter_actor_save_easing_state (actor);
    clutter_actor_set_easing_duration (actor, 1000);
    clutter_actor_set_easing_mode (actor, CLUTTER_EASE_OUT_BOUNCE);
    if (scale_x > 1.0)
    {
        clutter_actor_set_scale (actor, 1.0, 1.0);
    }
    else
    {
        clutter_actor_set_scale (actor, 2.0, 2.0);
    }
    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;
}

特に説明はしません。次は Gjs ですが、説明も無しです。

#! /usr/bin/env gjs
const Clutter = imports.gi.Clutter;

function on_completed (timeline) 
{
    let [scale_x, scale_y] = actor.get_scale();
    actor.save_easing_state();
    actor.set_easing_duration(1000);
    actor.set_easing_mode(Clutter.AnimationMode.EASE_OUT_BOUNCE);
    if (scale_x > 1.0) {
        actor.set_scale(1.0, 1.0);
    } else {
        actor.set_scale(2.0, 2.0);
    }
    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();

さて、感がいい人は解ると思いますが、飽きちゃいました。ごめんなさい。後2回ぐらいで終了します。layout と constraint は、また調べて書くかもしれません。