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.
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.
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.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.elm_transit_del()
function. If you delete the
transit while the transition is running, the transition will stop.
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.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);
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.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.
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.
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.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);
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.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.
We distinguish two main transition types:
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.
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);
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 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);
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);
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);
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);
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.
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);
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);
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.
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.
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.
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);
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.
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).
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.
Elm Transit Examples | ||||
---|---|---|---|---|
Basic Transit Usage | Chained Transitions | Combined effects and options | Combined effects over two objects |