Elementary Animations

Elementary transitions (Elm_Transit) allow you to apply various transition effects, such as translation and rotation, to Evas objects. Elementary transitions are mostly based on Ecore animators, but provide some transition methods at a higher level of abstraction. Elementary transitions provide a simpler way of animating objects than Ecore animators or Edje animations.

To use Elementary transitions, you must create an Elm_Transit object and define the desired transitions using the methods of this object. After the transitions are registered, they will be automatically managed: their callback functions will be called for the set duration, and they will be deleted upon completion.

Use Elementary transitions only when Edje animations are not sufficient. Edje animations are better at handling transitions, have more flexibility, and can be manipulated inside themes. The only drawback is that Edje animations have their own definition language. If you want to code with the C language, use Elementary transitions.

Table of Contents

Getting Started

The first thing you need to do when creating an transition with Elm_Transit is to build your transit object using the elm_transit_add() function:

Elm_Transit *transit = elm_transit_add();

You now have an Elm_Transit instance that will allow you to perform transitions on one or more objects. The transit object holds the information about the target objects and the transition effects that will be used. The transit object also contains information about animation duration, number of repetitions, auto-reverse, and so on. The transit object starts playing as soon as the application enters the main loop.

Adding Objects to an Animation

You can add your Evas objects to your transition using the elm_transit_object_add() function:

void elm_transit_object_add (Elm_Transit* transit,
                             Evas_Object* obj
                            )
  • transit handles the transition.
  • obj is the Evas object to animate.
The Evas object can be a low-level component, such as a rectangle, but also a widget, such as a button, image, or calendar.

If you want to animate an Evas object handled by a container, such as a box, you need to either unpack the object before the animation or animate the whole container.

If you want to know which objects are currently in your transition, use the elm_transit_objects_get() function. You will get a list of all the objects that are subject to the transition.

At any time, you can remove objects from the transition:

void elm_transit_object_remove(Elm_Transit *transit,
                               Evas_Object *obj
                              )
  • transit handles the transition.
  • obj is the Evas object to remove from the transition.
After you have added at least one Evas object to your transition, if the list of objects gets emptied somehow, be it because the transition has been terminated or all objects have been deleted, the transition will be automatically deleted. Otherwise, you will have to delete the transition by yourself using the elm_transit_del() function. If you delete the transit while the transition is running, the transition will stop.

Adding Images to an Animation

If you do not want to manage widgets for animating images, Elm_Transit provides a helper function for directly manipulating images:

Elm_Transit* elm_transit_effect_image_animation_add(Elm_Transit *transit,
                                                    Eina_List   *images
                                                   )
  • transit handles the transition.
  • images is a list of the image paths.
This list and its contents will be deleted after the effect ends by the elm_transit_effect_image_animation_context_free() function.

You can now define your image transitions exactly the same way as with any Evas object.

The following example shows how to use Elm_Transit with images:

char buf[PATH_MAX];
Eina_List *images = NULL;
Elm_Transit *transit = elm_transit_add();
snprintf(buf, sizeof(buf), "%s/images/btn_default.png", PACKAGE_DATA_DIR);
images = eina_list_append(images, eina_stringshare_add(buf));
snprintf(buf, sizeof(buf), "%s/images/btn_hover.png", PACKAGE_DATA_DIR);
images = eina_list_append(images, eina_stringshare_add(buf));
elm_transit_effect_image_animation_add(transit, images);

Animation Duration

With Elm_Transit, setting the transition duration is mandatory. To set the duration, use the elm_transit_duration_set() function:

void elm_transit_duration_set(Elm_Transit *transit,
                              double      duration
                             )
  • transit handles the transition.
  • duration is the duration in seconds.
The purpose of Elm_Transit is to abstract the low-level details of object interpolation, so you cannot create an infinite transition by specifying the duration. However, you can make your transition last forever using the repeat function.

The following example shows how to make a complete revolution of the target Evas object in 2 seconds:

Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_rotation_add(transit, 0.0, 360);
elm_transit_duration_set(transit, 2.0);
elm_transit_go(transit);

To get the duration of the transition, use the elm_transit_duration_get() function.

Animation Acceleration Mode ("Tween Mode")

Elm_Transit supports a number of built-in interpolation methods. By default, all interpolations are linear. If you want to change the animation's dynamics, use the elm_transit_tween_mode_set() function:

void elm_transit_tween_mode_set(Elm_Transit *          transit,
                                Elm_Transit_Tween_Mode tween_mode
                               )
  • transit handles the transition.
  • tween_mode is the tween mode of the transition.

tween_mode can be one of the following:

  • ELM_TRANSIT_TWEEN_MODE_LINEAR Constant speed.
  • ELM_TRANSIT_TWEEN_MODE_SINUSOIDAL Starts slow, increase speed over time, then decrease again and stop slowly, v1 being a power factor.
  • ELM_TRANSIT_TWEEN_MODE_DECELERATE Starts fast and decrease speed over time, v1 being a power factor.
  • ELM_TRANSIT_TWEEN_MODE_ACCELERATE Starts slow and increase speed over time, v1 being a power factor.
  • ELM_TRANSIT_TWEEN_MODE_DIVISOR_INTERP Start at gradient v1, interpolated via power of v2 curve.
  • ELM_TRANSIT_TWEEN_MODE_BOUNCE Start at 0.0 then “drop” like a ball bouncing to the ground at 1.0, and bounce v2 times, with decay factor of v1.
  • ELM_TRANSIT_TWEEN_MODE_SPRING Start at 0.0 then “wobble” like a spring rest position 1.0, and wobble v2 times, with decay factor of v1.
  • ELM_TRANSIT_TWEEN_MODE_BEZIER_CURVE Since 1.13: Follow the cubic-bezier curve calculated with the control points (x1, y1), (x2, y2)

To get the current tween mode, use the elm_transit_tween_mode_get() function.

Animation Repeat

To set a transition to repeat, use the elm_transit_repeat_times_set() function:

void elm_transit_repeat_times_set(Elm_Transit * transit,
                                  int           repeat
                                 )
  • transit is the transition you want to repeat.
  • repeat is the number of times the transition repeats.
If the repeat argument is set to 0, the transition will not loop at all. If set to 1, the transition will run twice. If set to a negative value, the transition will repeat forever.

To get the repeat value, use the elm_transit_repeat_times_get() function. The default value is 0.

The following example shows how to make an Evas object spin for 3 complete revolutions in 6 seconds:

Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_rotation_add(transit, 0.0, 360);
elm_transit_duration_set(transit, 2.0);
elm_transit_repeat_set(transit, 3.0);
elm_transit_go(transit);

Animation Auto-reverse

Elm_Transit provides a helper function for automatically reversing the transition once it finishes:

void elm_transit_auto_reverse_set(Elm_Transit * transit,
                                  Eina_Bool     reverse
                                 )
  • transit is the transition you want to reverse.
  • reverse is the reverse state. If the reverse state is set to EINA_TRUE, this function will perform the same transition backwards as soon as the first transition is complete.
Reversing the transition doubles the duration of the transition. Moreover, if the transition is set to repeat, the transition will run back and forth until the repeat count is finished.

You can calculate the duration as follows if both auto-reverse and repeat are set: 2 * duration * repeat.

The following example shows how to make an object perform half a turn and then reverse the animation to its original position in 4 seconds:

Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_rotation_add(transit, 0.0, 360);
elm_transit_duration_set(transit, 2.0);
elm_transit_auto_reverse_set(transit, EINA_TRUE);
elm_transit_go(transit);

To determine whether the auto-reverse mode is enabled, use the elm_transit_auto_reverse_get() function.

Transitions

We distinguish two main transition types:

  • Transitions that are applied to the properties of objects, such as position, size, angle, and color.
  • Transitions from one object to another, where the first object is hidden to let the second one appear.

All transitions are based on the same principle: we set the starting and the ending values for the properties we want to animate, we then set the lifespan of the animation, and finally we inquire the preferred interpolation method (such as linear, acceleration, or bounce).

You must declare the transitions after the parent window has been created, since the transition effects make use of the geometric properties of the parent window. If the parent window does not yet exist when calculating the interpolation, the interpolation may end up being based on wrong information.

Built-in Transitions

Elm_Transit provides several built-in transition definitions that are useful for the most common cases, so you that will not have to code them from scratch.

All these built-in effects are implemented as follows:

Elm_Transit *transit = elm_transit_add();
elm_transit_effect_add(transit,
                       elm_transit_effect_translation_op,
                       elm_transit_effect_translation_context_new(),
                       elm_transit_effect_translation_context_free);
  • transit: The Elm_Transit object that contains the target Evas objects and all the information needed to setup the transition.
  • elm_transit_effect_translation_op: The callback function that performs the transition (resizing interpolation in this example).
  • elm_transit_effect_translation_context_new(): The callback function that returns the context used in the transition for calculations. In this example, the context is the coordinates of the before and after objects.
  • elm_transit_effect_translation_context_free: The callback function that frees up the memory once the transition is complete.

All the definitions above can be rewritten as follows:

Elm_Transit *transit = elm_transit_add();
elm_transit_effect_translation_add(transit, from_x, from_y, to_x, to_y);

Translation

To perform a translation on an Evas object, use the following method:

Elm_Transit_Effect* elm_transit_effect_translation_add(Elm_Transit * transit,
                                                       Evas_Coord    from_dx,
                                                       Evas_Coord    from_dy,
                                                       Evas_Coord    to_dx,
                                                       Evas_Coord    to_dy
                                                      )
  • transit is the transit object that contains (among other things) all the Evas objects subject to the translation.
  • from_dx: The starting X coordinate (source).
  • from_dy: The starting Y coordinate (source).
  • to_dx: The ending X coordinate (destination).
  • to_dy: The ending Y coordinate (destination).

The following example shows how to slide an Evas object (a rectangle) on a 45-degree diagonal, from bottom-left to top-right, at a constant speed, and in 1 second:

Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, rectangle);
elm_transit_effect_translation_add(transit, 0, 0, 280, 280);
elm_transit_duration_set(transit, 1);
elm_transit_go(transit);

Color Transition

Color transitions allow you to dynamically change the color of Evas objects. The first argument is the transit object, while the other arguments will be used to define the color transition using RGB colors. There is also an alpha channel that controls the opacity of the color (the background of the object, not the object itself).

Elm_Transit_Effect * elm_transit_effect_color_add(Elm_Transit * transit,
                                                  unsigned int  from_r,
                                                  unsigned int  from_g,
                                                  unsigned int  from_b,
                                                  unsigned int  from_a,
                                                  unsigned int  to_r,
                                                  unsigned int  to_g,
                                                  unsigned int  to_b,
                                                  unsigned int  to_a
                                                 )
  • transit: The transit object that contains (among other things) all the Evas objects subject to the translation.
  • from_r: The start value for “Red”.
  • from_g: The start value for “Green”.
  • from_b: The start value for “Blue”.
  • from_a: The start value for “Alpha”.
  • to_r: The end value for “Red”.
  • to_g: The end value for “Green”.
  • to_b: The end value for “Blue”.
  • to_a: The end value for “Alpha”.

The following example shows how to transit a rectangle from red to blue in 3 seconds:

Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, rectangle);
elm_transit_effect_color_add(transit,         // Target object
                             255, 0, 0, 255,  // From color
                             0, 0, 255, 255); // To color
elm_transit_duration_set(transit, 3);
elm_transit_go(transit);

Rotation

Elm_Transit_Effect* elm_transit_effect_rotation_add(Elm_Transit * transit,
                                                    float         from_degree,
                                                    float         to_degree
                                                   )
  • transit: The transit object that contains (among other things) all the Evas objects subject to the translation.
  • from_degree: The start degree of rotation.
  • to_degree: The end degree of rotation.

This function can be used to perform a rotation on any Evas object. It works the same way as the other transit effects and takes two arguments for the starting and ending angles. Note that if you apply a rotation on multiple objects, they will individually mill around and not act as a group. If you want several objects to revolve around a common point, you must encapsulate the objects into a single parent object and apply the rotation to the parent object. The following example shows how to achieve this:

// Parent container
Evas_Object *parent = elm_box_add(my_window);
evas_object_show(parent);
elm_box_horizontal_set(parent, EINA_TRUE);
elm_box_homogeneous_set(parent, EINA_TRUE);
 
// Button 1
Evas_Object *btn1 = elm_button_add(parent);
elm_object_text_set(btn1, "Btn1");
elm_box_pack_start(parent, btn1);
evas_object_show(btn1);
 
// Button 2
Evas_Object *btn2 = elm_button_add(parent);
elm_object_text_set(btn2, "Btn2");
elm_box_pack_end(parent, btn2);
evas_object_show(btn2);
 
// Make the parent container do a 360 degrees spin
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, parent);
elm_transit_effect_rotation_add(transit, 0.0, 360);
elm_transit_duration_set(transit, 2.0);
elm_transit_go(transit);

Wipe Effect

The wipe effect is designed to dynamically hide or show any element on the scene.

Elm_Transit_Effect* elm_transit_effect_wipe_add(Elm_Transit *                transit,
                                                Elm_Transit_Effect_Wipe_Type type,
                                                Elm_Transit_Effect_Wipe_Dir  dir
                                               )

In addition to the Elm_Transit instance passed as the first argument, the function takes the following arguments:

  • type: The wipe type Elm_Transit_Effect_Wipe_Type defines whether to show or hide the target elements. The value can be one of the following:
    • ELM_TRANSIT_EFFECT_WIPE_TYPE_HIDE: Hide the object during the animation.
    • ELM_TRANSIT_EFFECT_WIPE_TYPE_SHOW: Show the object during the animation.
  • dir: The wipe direction Elm_Transit_Effect_Wipe_Dir defines in which direction the target will progressively appear or disappear. The value can be one of the following:
    • ELM_TRANSIT_EFFECT_WIPE_DIR_LEFT
    • ELM_TRANSIT_EFFECT_WIPE_DIR_RIGHT
    • ELM_TRANSIT_EFFECT_WIPE_DIR_UP
    • ELM_TRANSIT_EFFECT_WIPE_DIR_DOWN

The following example shows how to make an object disappear progressively from left to right:

Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_wipe_add(transit,
                            ELM_TRANSIT_EFFECT_TYPE_HIDE,
                            ELM_TRANSIT_EFFECT_WIPE_DIR_RIGHT);
elm_transit_duration_set(transit, 2.0);
elm_transit_go(transit);

Zoom Effect

Elm_Transit provides a zoom function.

Elm_Transit_Effect* elm_transit_effect_zoom_add(Elm_Transit * transit,
                                                float         from_rate,
                                                float         to_rate
                                               )
  • transit: The transit object that contains (among other things) all the Evas objects subject to the translation.
  • from_rate: The starting level of the zoom.
  • to_rate: The ending level of the zoom.

The from_rate argument defines the scale of the target objects at the beginning of the animation. A value of 1 represents the initial scale of the objects.

Setting the value of the to_rate argument to 2 will double the size of the target objects (double the width and double the height). When using this effect, the width and height of a target object will remain proportional to one another. If you want to customize the zoom effect, use the elm_transit_effect_resizing_add() function.

The following example shows how to implement a zoom-out transition. At the end of the 2-secondstransition, the animated object will be half its original size.

Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_zoom_add(transit, 1, 0.5);
elm_transit_duration_set(transit, 2.0);
elm_transit_go(transit);

Resizing Effect

The resizing effect allows you to design an interpolation of the width and height attributes of one or more target elements.

Elm_Transit_Effect* elm_transit_effect_resizing_add(Elm_Transit * transit,
                                                    Evas_Coord    from_w,
                                                    Evas_Coord    from_h,
                                                    Evas_Coord    to_w,
                                                    Evas_Coord    to_h)
                                                   )
  • transit: The transit object that contains (among other things) all the Evas objects subject to the translation.
  • from_w: The starting width.
  • from_h: The starting height.
  • to_w: The ending width.
  • to_h: The ending height.

The from_w and from_h arguments define the size at the beginning of the animation. The to_w and to_h arguments define the size at the end.

If you are planning to use this method to hide an Evas object by setting one of the length attributes to zero, consider using the elm_transit_effect_wipe_add() function instead.

The following example shows how to make a rectangle exchange its width and height properties in a 2-second transition:

Evas_Coord w, h;
evas_object_geometry_get(my_evas_object, NULL, NULL, &w, &h);
 
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, my_evas_object);
elm_transit_effect_resize_add(transit,            // Transition object
                              w, h,               // Original sizing
                              h, w);              // Target sizing
elm_transit_duration_set(transit, 2.0);
elm_transit_go(transit);

Flip Effect

This transition combines the target Evas objects in pairs, so that one object will show up while the other one disappears. This association relates the even objects in the transit list of objects with the odd ones. The even objects are shown at the beginning of the animation, and the odd objects shown when the transition is complete. In other words, the effect applies to each pair of objects in the order in which they are listed in the transit list of objects.

The flip effect itself is a pseudo-3D effect where the first object in the pair is the front object and the second one is the back object. When the transition launches, the front object rotates around a preferred axis in order to let the back object take its place.

Elm_Transit_Effect* elm_transit_effect_flip_add(Elm_Transit *                transit,
                                                Elm_Transit_Effect_Flip_Axis axis,
                                                Eina_Bool                    cw
                                               )
  • transit is the transit object.
  • axis is the prefered axis of rotation:
    • ELM_TRANSIT_EFFECT_FLIP_AXIS_X
    • ELM_TRANSIT_EFFECT_FLIP_AXIS_Y
  • cw is the direction of the rotation:
    • EINA_TRUE is clockwise.
    • EINA_FALSE is counterclockwise.

The following example shows how to create a coin that flips indefinitely. Note that we use images as Elementary widgets for demonstration purposes. You can use the elm_transit_effect_image_animation_add() function if you do not want to bother creating widgets.

// Coin Heads
Evas_Object *coin_heads = elm_image_add(win);
if (!elm_image_file_set(coin_heads, IMG_DIR"/coin_heads.png", NULL))
   printf("error: could not load image");
elm_win_resize_object_add(win, coin_heads);
 
// Coin Tails
Evas_Object *coin_tails = elm_image_add(win);
if (!elm_image_file_set(coin_tails, IMG_DIR"/coin_tails.png", NULL))
   printf("error: could not load image");
elm_win_resize_object_add(win, coin_tails);
 
// Transition definition
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, coin_heads);
elm_transit_object_add(transit, coin_tails);
elm_transit_duration_set(transit, 2.0);
elm_transit_auto_reverse_set(transit, EINA_TRUE);
elm_transit_repeat_times_set(transit, -1);
elm_transit_effect_flip_add(transit, ELM_TRANSIT_EFFECT_FLIP_AXIS_X, EINA_TRUE);
elm_transit_go(transit);

Resizable Flip Effect

In the flip example above, we used two objects that have the same size. However, you may sometimes want to flip from one object to another object with different size attributes. The most common example would be using buttons with dimensions that depend on their contents (such as labels). If you decide to use the classic elm_transit_effect_flip_add() function, the size of the object will change at the moment one object becomes completely hidden and the other one begins to show up. If you wish to interpolate the size attributes as well, use the elm_transit_effect_resizable_flip_add() function:

Elm_Transit_Effect* elm_transit_effect_resizable_flip_add(Elm_Transit *                transit,
                                                          Elm_Transit_Effect_Flip_Axis axis,
                                                          Eina_Bool                    cw
                                                         )
  • transit is the transit object.
  • axis is the preferred axis of rotation:
    • ELM_TRANSIT_EFFECT_FLIP_AXIS_X
    • ELM_TRANSIT_EFFECT_FLIP_AXIS_Y
  • cw is the direction of the rotation:
    • EINA_TRUE is clockwise.
    • EINA_FALSE is counterclockwise.

This function works the exact same way as the standard flip effect function.

Fade Effect

This effect is used to transition from one Evas object to another one using a fading effect: the first object will slowly disappear to let the second object take its place.

Elm_Transit_Effect* elm_transit_effect_fade_add(Elm_Transit *transit)

This effect is applied to each pair of objects in the order in which they are listed in the transit list of objects. The first object in the pair will be the before object and the second one will be the after object.

Building on the coin flip example, the following example shows how to fade out one face of the coin while fading in the other face:

Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, coin_heads);
elm_transit_object_add(transit, coin_tails);
elm_transit_duration_set(transit, 2.0);
elm_transit_effect_fade_add(transit);
elm_transit_go(transit);

If you simply want to hide an object with a fade transition, consider using a transparent after object.

Blend Effect

Another transition involving at least two Evas objects is the blend effect. This transition makes the before object blurry before the after object appears.

elm_transit_effect_blend_add(Elm_Transit *transit)

The argument is the transition target of the blend effect.

Building on the coin flip example, the following example shows how to blur out one face of the coin while blurring in the other face:

Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, coin_heads);
elm_transit_object_add(transit, coin_tails);
elm_transit_duration_set(transit, 2.0);
elm_transit_effect_blend_add(transit);
elm_transit_go(transit);

If you simply want to hide an object with a blur transition, consider using a transparent after object.

Combining Transitions

To use multiple transitions at the same time on the same objects, simply declare the transitions one after the other.

Building on the coin flip example, the following example shows how to roll the coin on the ground using a rotation and a translation effect:

Evas_Object *coin_heads = elm_image_add(parent);
if (!elm_image_file_set(coin_heads, IMG_DIR"/coin_heads.png", NULL))
   printf("error: could not load image");
evas_object_resize(coin_heads, 100, 100);
evas_object_show(coin_heads);
 
Elm_Transit *transit = elm_transit_add();
elm_transit_object_add(transit, coin_heads);
elm_transit_duration_set(transit, 5.0);
elm_transit_effect_translation_add(transit, 0, 0, 3.1415 * 2 * 100, 0);
elm_transit_effect_rotation_add(transit, 0, 360);
elm_transit_go(transit);

Animation Chain

Now that we have listed all the effects that can be implemented using Elm_Transit, we will see how to chain transitions into sequences. To create complex, chained animations without worrying about synchronization between the transitions, use the elm_transit_chain_transit_add() function. This function takes as arguments two Elm_Transit objects and will automatically take care of the chaining for you: the second transition will start as soon as the first transition is finished.

The following example shows how to move a datetime widget on a square trajectory:

Evas_Object *dt = elm_datetime_add(parent);
evas_object_resize(dt, 350, 50);
evas_object_show(dt);
 
// The first transition
Elm_Transit *t1 = elm_transit_add();
elm_transit_object_add(t1, dt);
elm_transit_duration_set(t1, 2);
elm_transit_effect_translation_add(t1, 0, 0, 100, 0);
 
// The second transition
Elm_Transit *t2 = elm_transit_add();
elm_transit_object_add(t2, dt);
elm_transit_duration_set(t2, 2);
elm_transit_effect_translation_add(t2, 100, 0, 100, 100);
 
// The third transition
Elm_Transit *t3 = elm_transit_add();
elm_transit_object_add(t3, dt);
elm_transit_duration_set(t3, 2);
elm_transit_effect_translation_add(t3, 100, 100, 0, 100);
 
// The fourth transition
Elm_Transit *t4 = elm_transit_add();
elm_transit_object_add(t4, dt);
elm_transit_duration_set(t4, 2);
elm_transit_effect_translation_add(t4, 0, 100, 0, 0);
 
// Chaining the transitions
elm_transit_chain_transit_add(t1, t2);
elm_transit_chain_transit_add(t2, t3);
elm_transit_chain_transit_add(t3, t4);
 
// Starting the transitions
elm_transit_go(t1);

Note that we cannot use transition chaining to make a loop animation, since the transit object is automatically destroyed as soon as the transition completes. Therefore, you cannot do something like this:

elm_transit_chain_transit_add(t4, t1);

To create a looped animation chain, you have to use low-level components provided by the Ecore and Evas transition libraries, or you can use the elm_transit_del_cb_set() function to define a callback function for when a transition gets deleted. This way, you could recreate your objects and reiterate the transition chain as soon as the last transition ends.

void elm_transit_del_cb_set(Elm_Transit *      transit,
                            Elm_Transit_Del_Cb cb,
                            void *             data
                           )
  • transit is the transition object.
  • cb is the callback function to run on transition delete.
  • data is the data to pass to the callback function.

You can severe the chain relationship between two transits by using the elm_transit_chain_transit_del() function:

void elm_transit_chain_transit_del(Elm_Transit * transit,
                                   Elm_Transit * chain_transit
                                  )
  • transit is the first transition in the chain.
  • chain_transit is the second transition in the chain.

To get the current chain transit list, use the elm_transit_chain_transits_get() function.

Animation Timeline

After you have defined all the properties that define your transition, start the transition with the elm_transit_go() function:

void elm_transit_go(Elm_Transit *transit)

You can maintain full control over the execution process even after the transition has started. You can pause the transition by setting the paused argument to EINA_TRUE:

elm_transit_paused_set(Elm_Transit * transit,
                       Eina_Bool     paused
                      )

You can resume the transition by using the same method but setting the paused argument to EINA_FALSE. If you want to know whether the transition is currently paused, use the elm_transit_paused_get() function.

You can remain informed about the present transition flow and get the current frame by using the elm_transit_progress_value_get() function. This function will return the timeline position of the animation, ranging between 0.0 (start) and 1.0 (end).

Custom Transition

Elm_Transit provides a standard function for defining any effect of your choosing that will be applied to some context data:

elm_transit_effect_add(Elm_Transit *                    transit,
                       Elm_Transit_Effect_Transition_Cb transition_cb,
                       Elm_Transit_Effect *             effect,
                       Elm_Transit_Effect_End_Cb        end_cb
                      )
  • transit is the transition target of the new effect.
  • transition_cb is the transition callback function.
  • effect is the new effect.
  • end_cb is the callback function to call at the end of the effect.

As described earlier in this programming guide, this function embraces three callbacks that will allow you to define every aspects of your transition from its creation to its deletion. The following is an example of how to build a custom resizing animation.

First, we define a structure capable of holding the context information about resizing an Evas object:

typedef struct
{
   struct _size
   {
      Evas_Coord w, h;
   }
   from, to;
}
Custom_Effect;

We can now implement our custom resizing callback function. This function takes the following arguments:

  • data is the context data that holds the custom properties of our transition, which are used as parameters to calculate the interpolation.
  • transit is the transit object that contains the list of our Evas objects to animate and all the information about duration, auto-reverse, looping, and so on.
  • progress is the progress (position along the animation timeline) that ranges from 0.0 to 1.0 and allows us to calculate the desired interpolation for each frame.
static void
_custom_op(void *data, Elm_Transit *transit, double progress)
{
   if (!data) return;
   Evas_Coord w, h;
   Evas_Object *obj;
   const Eina_List *elist;
   Custom_Effect *custom_effect = data;
   const Eina_List *objs = elm_transit_objects_get(transit);
   if (progress < 0.5)
     {
        h = custom_effect->from.h + (custom_effect->to.h * progress * 2);
        w = custom_effect->from.w;
     }
   else
     {
        h = custom_effect->from.h + custom_effect->to.h;
        w = custom_effect->from.w + (custom_effect->to.w * (progress - 0.5) * 2);
     }
   EINA_LIST_FOREACH(objs, elist, obj)
      evas_object_resize(obj, w, h);
}

The callback function above resizes our Evas objects in two steps. During the first half of the transition, only the height changes, while the width remains the same. During the second half, it is the other way around until we get to the desired size.

You must then define the context used by your animation:

static void*
_custom_context_new(Evas_Coord from_w, Evas_Coord from_h, Evas_Coord to_w, Evas_Coord to_h)
{
   Custom_Effect *custom_effect;
 
   custom_effect = calloc(1, sizeof(Custom_Effect));
   if (!custom_effect) return NULL;
 
   custom_effect->from.w = from_w;
   custom_effect->from.h = from_h;
   custom_effect->to.w = to_w - from_w;
   custom_effect->to.h = to_h - from_h;
 
   return custom_effect;
}

You must define the function that will take care of deleting all the context objects used by your custom transition and free up the allocated memory:

static void
_custom_context_free(void *data, Elm_Transit *transit __UNUSED__)
{
   free(data);
}

Finally, apply your custom transition to your Elm_Transit object:

Elm_Transit *transit = elm_transit_add();
elm_transit_effect_add(transit,
                       _custom_op,
                       _custom_context_new(),
                       _custom_context_free);

If you want to delete an effect from your effects list, use the elm_transit_effect_del() function.