This site has been retired. For up to date information, see handbook.gnome.org or gitlab.gnome.org.


[Home] [TitleIndex] [WordIndex

Vala Clutter Samples

Animated Actors

using Clutter;

class ClutterDemo {

    private Stage stage;
    private Actor[] rectangles;

    const string[] colors = {
        "blanched almond",
        "OldLace",
        "MistyRose",
        "White",
        "LavenderBlush",
        "CornflowerBlue",
        "chartreuse",
        "chocolate",
        "light coral",
        "medium violet red",
        "LemonChiffon2",
        "RosyBrown3"
    };

    public ClutterDemo () {
        stage = new Stage();    
        stage.set_size(512,512);
        stage.background_color = Color () { alpha = 255 };

        rectangles = new Actor[colors.length];
        stage.hide.connect (Clutter.main_quit);

        create_rectangles ();
        stage.show ();
    }

    private void create_rectangles () {
        for (int i = 0; i < colors.length; i++) {
            var r = new Actor();

            r.width = r.height = stage.height / colors.length;
            r.background_color = Color.from_string (colors[i]);

            var point = Point.alloc();
            point.init(0.5f,0.5f) ;
            r.pivot_point = point;

            r.y = i * r.height;

            stage.add_child (r);

            rectangles[i] = r;
        }
    }

    public void start () {
        var transitions = new PropertyTransition[rectangles.length];
        for (int i = 0; i < rectangles.length; i++) {
            var transgroup = new TransitionGroup();
            var transition = new PropertyTransition ("x");
            transition.set_to_value(stage.width/2 - rectangles[i].width/2);
            transition.set_duration(2000);
            transition.set_progress_mode (AnimationMode.LINEAR);
            transgroup.add_transition(transition);

            transition = new PropertyTransition ("rotation_angle_z");
            transition.set_to_value(500.0);
            transition.set_duration(2000);
            transition.set_progress_mode (AnimationMode.LINEAR);
            transgroup.add_transition(transition);
            
            transgroup.set_duration(2000);
            rectangles[i].add_transition("rectAnimation", transgroup);
            transitions[i] = transition;
        }
        transitions[transitions.length - 1].completed.connect (() => {
                var CONGRATS_EXPLODE_DURATION = 3000;
                var text = new Text.full ("Bitstream Vera Sans 40",
                    "Congratulations!",
                    Color.from_string ("white"));

                var point = Point.alloc();
                point.init(0.5f, 0.5f);
                text.pivot_point = point;
                text.x = stage.width / 2 - text.width / 2;
                text.y = -text.height;    // Off-stage
                stage.add_child (text);


                var transition = new PropertyTransition ("y");
                transition.set_to_value(stage.height/2 - text.height/2);
                transition.set_duration(CONGRATS_EXPLODE_DURATION / 2);
                transition.set_progress_mode(AnimationMode.EASE_OUT_BOUNCE);
                text.add_transition("rectAnimation", transition);

                for (int i = 0; i < rectangles.length; i++) {
                    var transgroup = new TransitionGroup();
                    /* "x" property transition */
                    transition = new PropertyTransition("x");
                    transition.set_to_value(Random.next_double() * stage.width );
                    transition.set_duration(CONGRATS_EXPLODE_DURATION);
                    transgroup.add_transition(transition);
                    transition.set_progress_mode(AnimationMode.EASE_OUT_BOUNCE);

                    /* "y" property transition */
                    transition = new PropertyTransition("y");
                    transition.set_to_value(Random.next_double() * stage.height/2 +
                            stage.height/2);
                    transition.set_duration(CONGRATS_EXPLODE_DURATION);
                    transition.set_progress_mode(AnimationMode.EASE_OUT_BOUNCE);
                    transgroup.add_transition(transition);

                    /* "opacity" property transition */
                    transition = new PropertyTransition("opacity");
                    transition.set_to_value(0);
                    transition.set_duration(CONGRATS_EXPLODE_DURATION );
                    transition.set_progress_mode(AnimationMode.EASE_OUT_BOUNCE);
                    transgroup.add_transition(transition);

                    /* TransitionGroup duration seems to be set explicitely -
                     * at least so large value as the longest duration among
                     * included Transitions */
                    transgroup.set_duration(CONGRATS_EXPLODE_DURATION);
                    transgroup.delay = CONGRATS_EXPLODE_DURATION/3;

                    rectangles[i].add_transition("transbox", transgroup);
                }
        });
    }
}

int main (string[] args) {
    if ( Clutter.init (ref args) < 0) {
        stderr.printf("Failed to initialize clutter\n");
        return 1;
    }
    var demo = new ClutterDemo ();
    demo.start ();
    Clutter.main ();
    return 0;
}

Animated Actors - original, compilable as for clutter 1.16.4, but using deprecated APIs

Requires Vala >= 0.7.9

using Clutter;

class ClutterDemo {

    private Stage stage;
    private Rectangle[] rectangles;

    const string[] colors = {
        "blanched almond",
        "OldLace",
        "MistyRose",
        "White",
        "LavenderBlush",
        "CornflowerBlue",
        "chartreuse",
        "chocolate",
        "light coral",
        "medium violet red",
        "LemonChiffon2",
        "RosyBrown3"
    };

    public ClutterDemo () {
        stage = Stage.get_default ();

        rectangles = new Rectangle[colors.length];
        stage.hide.connect (Clutter.main_quit);

        create_rectangles ();

        stage.color = Color () { alpha = 255 };
        stage.show_all ();
    }

    private void create_rectangles () {
        for (int i = 0; i < colors.length; i++) {
            var r = new Rectangle ();

            r.width = r.height = stage.height / colors.length;
            r.color = Color.from_string (colors[i]);
            r.anchor_gravity = Gravity.CENTER;
            r.y = i * r.height + r.height / 2;

            stage.add_actor (r);

            rectangles[i] = r;
        }
    }

    public void start () {
        var animations = new Animation[rectangles.length];
        for (int i = 0; i < rectangles.length; i++) {
            animations[i] = rectangles[i].animate (
                                      AnimationMode.LINEAR, 5000,
                                      x: stage.width / 2,
                                      rotation_angle_z: 500.0);
        }
        animations[animations.length - 1].completed.connect (() => {
            var text = new Text.full ("Bitstream Vera Sans 40",
                                      "Congratulations!",
                                      Color.from_string ("white"));

            text.anchor_gravity = Gravity.CENTER;
            text.x = stage.width / 2;
            text.y = -text.height;    // Off-stage
            stage.add_actor (text);
            text.animate (AnimationMode.EASE_OUT_BOUNCE, 3000,
                          y: stage.height / 2);

            for (int i = 0; i < rectangles.length; i++) {
                rectangles[i].animate (
                        AnimationMode.EASE_OUT_BOUNCE, 3000,
                        x: Random.next_double () * stage.width,
                        y: Random.next_double () * stage.height / 2
                                                 + stage.height / 2,
                        rotation_angle_z: rectangles[i].rotation_angle_z,
                        opacity: 0);
            }
        });
    }
}

void main (string[] args) {
    Clutter.init (ref args);
    var demo = new ClutterDemo ();
    demo.start ();
    Clutter.main ();
}

$ valac --pkg clutter-1.0 clutter-demo.vala
$ ./clutter-demo

clutter-rectangles.png

Blender models

Requires Vala (>= 0.9.5)

You can import 3D models inside your Clutter application using the Mash library which reads PLY formatted files (Blender is able to export in PLY).

The following code will render and rotate a model on the Y axis.

int main (string[] args)
{
  Clutter.init (ref args);

  if (args.length != 2 && args.length != 3)
    {
      stderr.printf ("usage: %s <ply-file> [texture]\n", args[0]);
      return 1;
    }

  var stage = Clutter.Stage.get_default ();

  try
    {
      var model = new Mash.Model.from_file (Mash.DataFlags.NONE, args[1]);

      if (args.length > 2)
        {
          try
            {
              var texture = new Cogl.Texture.from_file (args[2], Cogl.TextureFlags.NONE, Cogl.PixelFormat.ANY);
              var material = new Cogl.Material ();
              material.set_layer (0, texture);
              model.set_material (material);
            }
          catch (Error e)
          {
            warning (e.message);
          }
        }

      model.set_size (stage.width * 0.7f, stage.height * 0.7f);
      model.set_position (stage.width * 0.15f, stage.height * 0.15f);

      var center_vertex = Clutter.Vertex ();
      center_vertex.x = stage.width * 0.35f;
      center_vertex.y = 0.0f;
      center_vertex.z = 0.0f;

      var anim = model.animate (Clutter.AnimationMode.LINEAR, 3000,
                                "rotation-angle-y", 360.0f,
                                "fixed::rotation-center-y", ref center_vertex);
      anim.loop = true;

      stage.add_actor (model);

      /* Enable depth testing only for this actor */
      model.paint.connect (() => { Cogl.set_depth_test_enabled (true); });
      model.paint.connect_after (() => { Cogl.set_depth_test_enabled (false); });
    }
  catch (Error e)
  {
    warning (e.message);
  }

  stage.show ();

  Clutter.main ();

  return 0;
}

Fetch a sample model: TheMonkey.ply. The compilation command is a bit hard-coded due to missing features in the Vala GIR parser:

$ valac --pkg atk --pkg clutter-1.0 --pkg Mash-0.1 mash-demo.vala -X -I/usr/include/mash-0.1 -X -lmash-0.1
$ ./mash-demo TheMonkey.ply

You can pass a texture as second argument to mash-demo.

mash-monkey.png


Vala/Examples


2024-10-23 11:37