Edje Animation: Using the Edje Library to Create Animations
One of the greatest strengths of EFL and Edje is the ability to create animations. This tutorial demonstrates how Elm_Transit can create pre-defined animations, but you can also use the Edje library to create your own animations.
Warm-up
Become familiar with the Edje, Elementary, and Evas API basics by learning about:
-
Animating on Application Start-up
Run an animation on application start-up.
-
Animating Object on Click
Animate an object when clicking.
Animating on Application Start-up
The goal of this tutorial is to create an animation target and buttons to start animations, all this in an EDC (Edje Data Collection) file.
First create an application using Basic EDC UI Application. This model provides a simple application just like the one used in the previous chapter, but with one more element: an .edc file.
Animations can be run at application startup. By default the Basic EDC UI Application model produces an empty window with a title. In this example a Tizen logo is added to the window and the behavior of the window title is changed.
The images used by the Edje file are stored in the edje/images directory of the application. Copy the Tizen logo available in shared/res/<yourapplicationname>.png into the Edje image directory edje/images. Then add the image to the Edje images collection.
images { image: "edceffects.png" COMP; image: "tizen-logo.png" COMP; }
Then add an Edje part using the small logo: this part has two states. This is the first important notion for animations. The STATE describes the appearance of a part: size, position, color, etc.
In this example, the part has two states, default and down-state:
// An image using the tizen logo part { name: "logo"; type: IMAGE; description { state: "default" 0.0; max: 63 63; min: 63 63; image { normal: "small-logo.png"; } rel1.relative: 0.1 0.0; rel2.relative: 0.0 0.0; } description { state: "down-state" 1.0; inherit: "default" 0.0; rel1.relative: 0.1 0.92; rel2.relative: 0.05 1.0; } }
The logo part has the IMAGE type. The default state contains in the first description of the part sets:
- the maximum and minimum size using the min and max statements
- the image to use in this part
- the default position.
The second state, down-state, inherits all of the default's attributes, and only changes the position to put the image at the bottom of the application window.
These two states are the start and end states of the animation. To actually create the animation, add a program to the Edge programs collection.
// Icon drop animation program { name: "animation,state1"; source: ""; signal: "load"; action: STATE_SET "down-state" 1.0; target: "logo"; transition: BOUNCE 2.5 0.0 5.0; }
This program is named animation,state1 and is started when the application receives the load signal immediately on startup. It runs the STATE_SET action so it changes the object state from default to down-state. The target of the program is the logo part.
In order to switch from one state to another, it uses a transition of the BOUNCE type with 3 parameters, the bounce_decay, the number_of_bounces, and the duration which here is set to five seconds.
This produces an falling and bouncing effect.
Also add an animation for the window title to make it move from the left to the right with a bounce effect while growing the font size.
Create a new state on the part called "txt_title" inside which both the font size and position are changed.
part { name: "txt_title"; type: TEXT; mouse_events: 0; // The default State description { state: "default" 0.0; align: 0.0 0.0; rel1 { relative: 0.0 0.0; } rel2 { relative: 0.0 0.0; } text { font: "Tizen:style=regular"; size: 24; min: 1 1; } color: 0 0 0 255; } // The "Bigger" state description { state: "Bigger" 0.0; align: 0.0 0.0; rel1 { relative: 0.75 0.0; } rel2 { relative: 0.0 0.0; } text { font: "Tizen:style=regular"; size: 28; min: 1 1; } color: 0 0 0 255; } }
Create a program to animate this part on startup, just like the small Tizen logo.
// Make the title bigger program { name: "animation,bigtitle"; source: ""; signal: "load"; action: STATE_SET "Bigger" 1.0; target: "txt_title"; transition: LINEAR 5.0; }
This program goes from the default state to the bigger state in five seconds with a LINEAR effect, automatically running on the application startup.
Animating Object on Click
All the previous animations are automatic and do not have any relation with the user's actions. Next animate a part by clicking on another one. Make the title restore its default aspect when clicking on the small logo.
The parts and the states are already defined. The animation goes back to the default state, there is no need to add any parts or states: only add a program which makes the transition when clicking on logo part.
// Make the title go back to normal program { name: "animation,normaltitle"; source: "logo"; signal: "mouse,clicked,*"; action: STATE_SET "default" 1.0; target: "txt_title"; transition: LINEAR 0.5; }
This program starts when the application receives the signal mouse,clicked,* (any button of the mouse is clicked) from the part called logo, (source). It performs the STATE_SET action and sets the default state on the target txt_file part with a LINEAR transition.
When clicking any mouse button on the small logo, the title goes back to its original state.
Rotating Parts
Next add two more buttons to the application and create programs to animate a target.
It is possible to create a button with Edje from scratch, but to save time, the SWALLOW part is used in this example to store Elementary UI components.
First create the SWALLOW parts, and then the Elementary UI components in the .c file.
// Container for the rotate button part { type: SWALLOW; name: "btn/rotate"; description { state: "default" 0.0; rel1.relative: 0.10 0.80; rel2.relative: 0.30 0.90; } }
This part is called btn/rotate, it only has a SWALLOW type and a default state with its position being on the bottom left of the screen.
// Container for the grow button part { type: SWALLOW; name: "btn/grow"; description { state: "default" 0.0; rel1.relative: 1.02 0; rel1.to: "btn/rotate"; rel2.relative: 2.02 1; rel2.to: "btn/rotate"; } }
This second SWALLOW part is very similar to the first one. It is placed relatively to btn/rotate, in order to remain next to it.
Next create the actual UI components. This is done in the .c file and is very similar to what is done for the buttons in the first chapter.
This code is added to the create_base_ui function.
// Creation button in the app window ad->button = elm_button_add(ad->win); elm_object_text_set(ad->button, "Rotate"); // Add the button to the edje layout container called "btn/rotate" elm_object_part_content_set(ad->layout, "btn/rotate", ad->button); evas_object_show(ad->button); // Creation a up button in the app window ad->btn_up = elm_button_add(ad->win); // Add the button to the edje layout container called "btn/grow" elm_object_text_set(ad->btn_up, "Grow"); elm_object_part_content_set(ad->layout, "btn/grow", ad->btn_up); evas_object_show(ad->btn_up);
In the default Basic EDC UI Application, the Edje layout is loaded by default. Create two Elementary buttons and add them to the SWALLOW containers, without having to setup sizes or positions as this is done in the SWALLOW container.
Note that the part name is very important because it is used to be merged the Elementary UI component and the SWALLOW part.
When the buttons placed and set, create the animation target. it is done in the EDC file.
Add the animation target part.
The part initialization and the default state:
// The animation target part { name: "atarget"; type: IMAGE; // Default state description { state: "default" 0.0; image { normal: "tizen-logo.png"; } color: 255 0 0 255; // red rel1 { relative: 0.3 0.3; } rel2 { relative: 0.7 0.4; } } }
This part is an image displaying a big Tizen logo, placed on the top of the screen more or less centered.
Create a state to change the color and add the map statement.
// The rotate state description { state: "rotate" 0.0; inherit: "default" 0.0; map { // Enable Map on the part on: 1; // Enable smooth rendering smooth: 1; // Enable perspective perspective_on: 1; // Apply rotations on the part rotation.x: 0; rotation.y: 0; rotation.z: 0; } color: 0 255 0 255; // green }
This part changes the color to green and defines the map. This statement makes rotations possible on an Edje part. Rotations are done around the x, y or z axes. In this example, the map is enabled and a 0° rotation is applied around each axis.
Add a state with a rotation around the z axis of 360°.
description { state: "rotate" 1.0; inherit: "rotate" 0.0; map.rotation.z: 360; }
This state inherits from the default state parameters and add a rotation around the z axis.
Finally add a state to the other button animation grow. Change the size of the animation target and add an offset.
// The grow state description { state: "grow" 0.0; color: 0 0 255 255; // blue rel1 { relative: 0.2 0.2; offset: 0.3 0.3; } rel2 { relative: 0.7 0.4; offset: 0.3 0.3; } }
The last step is to create the programs to make all these states animate.
To make the rotation animation smoother, create and chain several programs with different durations.
First create the main one: it goes from the default state to the rotate 0.0 state in 0.2 seconds.
Note that the states are all named the same way (rotate) but not with the same version. This version allows you to have more than one state with the same name, in fact the actual name of the state is the name plus the version.
// Change the color of target to green program { name: "rotate,target"; source: "btn/rotate"; signal: "mouse,clicked,*"; action: STATE_SET "rotate" 0.0; target: "atarget"; transition: SIN 0.2; after: "rotate,target,2"; }
The program starts when the btn/rotate part is clicked with any mouse button. When the animation ends, it calls the next one called rotate,target,2.
// Rotate 360° program { name: "rotate,target,2"; action: STATE_SET "rotate" 1.0; target: "atarget"; transition: SIN 0.7; after: "rotate,end"; }
This program sets the part state to rotate 1.0 in 0.7 seconds, and when done calls the next one rotate,end.
// Go back to the normal program { name: "rotate,end"; action: STATE_SET "rotate" 0.0; target: "atarget"; transition: LINEAR 0.2; }
rotate,end is the last program of the rotation effect: it sets the state to rotate 0.0 very fast.
The last program of this example is the grow effect, it switches from one state to another.
// Grow the target and go back to normal state program { name: "grow,target"; source: "btn/grow"; signal: "mouse,clicked,*"; action: STATE_SET "grow" 1.0; after: "go,default"; target: "atarget"; transition: SINUSOIDAL 1.0; }
It starts when the btn/grow part is clicked, it goes from the current state to grow 1.0 in one second. It then calls the go,default program. In this program, both size and color change during the transition.
The go,default program sets the status back default for the animation target.
// Go back to normal (default) state program { name: "go,default"; action: STATE_SET "default" 1.0; target: "atarget"; transition: SIN 1.0; }