Animations

You can change an object on the screen at certain intervals using an
animation. To create an animation, you must first determine the duration
of the animation, and then define a callback function that performs the
actual animation with that duration.

In the following example, 2 square rectangles are animated. One of them
simply moves on the screen, while the other also changes its color and
size while moving.

The following example uses the same Basic UI template as the square
drawing example. For more information on how to create the project with
the template, see Squares on the Canvas.

To implement animations in an application:

  1. Create a new project and specify the project name as AnimatorEx.

  2. After the project is created, open the .c source file in the src
    folder and add the new code to the create_base_gui() function to
    create 2 rectangles and 2 animations.

    The following functions are used to create the animations:

    • ecore_animator_frametime_set() specifies a frame time interval
      for an animation. For example, if you specify the interval as
      1/50, 50 frame events occur in 1 second. The unit is seconds.

    • ecore_animator_timeline_add() creates an Animator object
      with a limited time specified in seconds by the first parameter.
      Once the runtime of the animator has elapsed, it is
      deleted automatically.

      The second parameter indicates the frame event callback function
      that actually defines the animation details, and the third
      parameter indicates the user data, which generally passes an
      object or application data to which you apply the animation.

      The callback function can return ECORE_CALLBACK_RENEW to keep
      the animator running or ECORE_CALLBACK_CANCEL to stop it and
      automatically delete it at any time.

    • ecore_animator_add() creates an Animator object. The first
      parameter indicates the frame event callback function that
      actually defines the animation details, and the second parameter
      indicates the user data.

      The ecore_animator_timeline_add() function is exactly like the
      ecore_animator_add() function, except that the animator only
      runs for a limited time.

    • ecore_timer_add() creates a timer to call the given function
      in the given period of time. The first parameter is the interval
      in seconds, and the second parameter is the given function.

      If this function returns ECORE_CALLBACK_RENEW, the timer is
      rescheduled for the next interval given in the first parameter.
      If it returns ECORE_CALLBACK_CANCEL, the timer is
      deleted automatically. The third parameter indicates the user
      data to pass to the function when it is called.

    The label is not used in this example, so annotate it.

    /*
       Conformant
       Create and initialize elm_conformant
       elm_conformant is mandatory for the base GUI to have a proper size
       when the indicator or virtual keypad is visible
    */
    ad->conform = elm_conformant_add(ad->win);
    elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
    elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE);
    evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    elm_win_resize_object_add(ad->win, ad->conform);
    evas_object_show(ad->conform);
    /*
       Label
       Create an actual view of the base GUI
       Modify this part to change the view
    */
    #if 0 /* _NOT_USED */
        ad->label = elm_label_add(ad->conform);
        elm_object_text_set(ad->label, "<align=center>Hello Tizen</align>");
        evas_object_size_hint_weight_set(ad->label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
        elm_object_content_set(ad->conform, ad->label);
        evas_object_show(ad->label);
    #endif
    
    /* Evas */
    Evas *evas = evas_object_evas_get(ad->conform);
    
    /* Rect */
    Evas_Object * rect = evas_object_rectangle_add(evas);
    
    evas_object_color_set(rect, 0, 0, 255, 255);
    evas_object_resize(rect, 50, 50);
    evas_object_show(rect);
    
    Evas_Object *rect2 = evas_object_rectangle_add(evas);
    evas_object_color_set(rect2, 0, 55, 0, 255);
    evas_object_resize(rect2, 50, 50);
    evas_object_show(rect2);
    
    /* Animation */
    ecore_animator_frametime_set(1. / 50);
    Ecore_Animator *anim = ecore_animator_timeline_add(5, _advance_frame, rect);
    Ecore_Animator *anim2 = ecore_animator_add(_advance_frame3, rect2);
    Ecore_Timer *timer1 = ecore_timer_add(10, _start_second_anim, rect);
    Ecore_Timer *timer2 = ecore_timer_add(5, _freeze_third_anim, rect2);
    Ecore_Timer *timer3 = ecore_timer_add(10, _thaw_third_anim, rect2);
    
    /* Show the window after the base GUI is set up */
    evas_object_show(ad->win);
    
  3. Create the frame event callback functions by adding them to the top
    of the create_base_gui() function:

    • The code of the _advance_frame() timeline animation frame
      event callback function specifies the new size, position, and
      color of the square. It changes the blue square to red and grows
      it larger as it moves toward the bottom right. The style applied
      to the animation is ECORE_POS_MAP_LINEAR, which keeps the
      animation moving at a certain speed.
    • The code of the _advance_frame2() timeline animation frame
      event callback function also specifies the size, position, and
      color of a square. The style applied to the animation is
      ECORE_POS_MAP_BOUNCE, which creates a vibration like a
      bouncing ball. It slows to a stop after bouncing off the
      ending point.
    • The code of the _advance_frame3() timeline animation frame
      event callback function increases the X coordinate of an object
      by 2 at every frame. The static variable x is used in order to
      increase the X coordinate whenever this function is called. When
      the X coordinate becomes greater than 250, it starts back
      from 0. The evas_object_move() function changes the position
      of an object.

    The ecore_animator_pos_map() function returns the resulting value
    that is mapped onto the position of the current animation. The
    returned values range between 0 and 1. The resulting value when the
    animation starts is 0, and it gradually increases and eventually
    reaches 1 when the animation stops.

    The second parameter of the timeline animation event function must
    be passed to the first parameter of the
    ecore_animator_pos_map() function. For the second parameter, enter
    the style of the animation. The style types are described in the
    _Ecore_Pos_Map enumeration (in
    mobile
    and
    wearable applications)
    that defines the position mappings for the animation. For the third
    and fourth parameter, enter the intensity and tempo of the
    speed change.

    The _advance_frame() function is only valid for 5 seconds, since
    its runtime (specified by the first parameter of the
    ecore_animator_timeline_add() function) is 5 seconds. Therefore,
    the _advance_frame() function is automatically deleted after
    5 seconds. The freeze_third_anim() function is called 5 seconds
    after the application starts, and the ecore_animator_freeze()
    function pauses the animation. The thaw_third_anim() and
    _start_second_anim() functions are called 10 seconds after the
    application starts, and the ecore_animator_thaw() function
    restarts the animation.

    static Eina_Bool
    _advance_frame(void *data, double pos)
    {
        double frame = ecore_animator_pos_map(pos, ECORE_POS_MAP_LINEAR, 12, 15);
        evas_object_resize(data, 50 * (1 + frame), 50 * (1 + frame));
        evas_object_move(data, 100 * frame, 100 * frame);
        evas_object_color_set(data, 255 * frame, 0, 255 * (1 - frame), 255);
    
        return ECORE_CALLBACK_RENEW;
    }
    
    static Eina_Bool
    _advance_frame2(void *data, double pos)
    {
        double frame = ecore_animator_pos_map(pos, ECORE_POS_MAP_BOUNCE, 1.2, 50);
        evas_object_resize(data, 100 - (50 * frame), 100 - (50 * frame));
        evas_object_move(data, 100 * (1 - frame), 100 * (1 - frame));
        evas_object_color_set(data, 255 * (1 - frame), 0, 255 * frame, 255);
    
        return ECORE_CALLBACK_RENEW;
    }
    
    static Eina_Bool
    _advance_frame3(void * data)
    {
        static int x = 0;
        if (x >= 250)
            x = 0;
        evas_object_move(data, x += 2, 350);
    
        return ECORE_CALLBACK_RENEW;
    }
    
    static Eina_Bool
    _start_second_anim(void *data)
    {
        ecore_animator_frametime_set(1./10);
        ecore_animator_timeline_add(20, _advance_frame2, data);
    
        return ECORE_CALLBACK_CANCEL;
    }
    
    static Eina_Bool
    _freeze_third_anim(void *data)
    {
        dlog_print(DLOG_ERROR, LOG_TAG, "ANIMATOR = %p", data);
        ecore_animator_freeze(data);
    
        return ECORE_CALLBACK_CANCEL;
    }
    
    static Eina_Bool
    _thaw_third_anim(void *data)
    {
        ecore_animator_thaw(data);
    
        return ECORE_CALLBACK_CANCEL;
    }
    
  4. Build and run the application.

    2 squares are shown on the screen:

    • The green square moves from left to right. When the green square
      has moved a certain distance, it restarts its movement from the
      left end of the screen.

    • The blue square turns red and becomes larger as it moves to the
      bottom right for 5 seconds. From 5 to 10 seconds, 2 squares
      are paused. After 10 seconds, they are resumed, and the red
      square turns blue and becomes smaller as it moves to the top
      left for 20 seconds.

      Create the project