~~Title: Elementary Animations~~ {{page>index}} ---- ===== 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|Getting Started]] * [[#Adding_Objects_to_an_Animation|Adding Objects to an Animation]] * [[#Animation_Duration|Animation Duration]] * [[#Animation_Acceleration_Mode_("Tween_Mode")|Animation Acceleration Mode ("Tween Mode")]] * [[#Animation_Repeat|Animation Repeat]] * [[#Animation_Auto-reverse|Animation Auto-reverse]] * [[#Transitions|Transitions]] * [[#Built-in_Transitions|Built-in Transitions]] * [[#Translation|Translation]] * [[#Color_Transition|Color Transition]] * [[#Rotation|Rotation]] * [[#Wipe_Effect|Wipe Effect]] * [[#Zoom_Effect|Zoom Effect]] * [[#Resizing_Effect|Resizing Effect]] * [[#Flip_Effect|Flip Effect]] * [[#Resizable_Flip_Effect|Resizable Flip Effect]] * [[#Fade_Effect|Fade Effect]] * [[#Blend_Effect|Blend Effect]] * [[#Combining_Transitions|Combining Transitions]] * [[#Animation_Chain|Animation Chain]] * [[#Animation_Timeline|Animation Timeline]] * [[#Custom_Transition|Custom Transition]] === Related Info === * [[/develop/legacy/tutorial/effects_tutorial|Effects Tutorial]] * [[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/group__Transit.html|Elementary Transit API]] ^ Elm Transit Examples ^^^^ |[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_01_explained.html|Basic Transit Usage]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_02_explained.html|Chained Transitions]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_03_explained.html|Combined effects and options]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_04_c.html|Combined effects over two objects]]| ==== 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); {{ :event_effect_elementary_transitions_coin_flip.png }} === 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. \\ ^ Elm Transit Examples ^^^^^ |[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_01_explained.html|Basic Transit Usage]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_02_explained.html|Chained Transitions]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_03_explained.html|Combined effects and options]]|[[https://build.enlightenment.org/job/nightly_elm_gcc_x86_64/lastSuccessfulBuild/artifact/doc/html/transit_example_04_c.html|Combined effects over two objects]]| ------ {{page>index}}