Разработка нативных приложений Tizen

Использование анимации

Показывать лекцию целиком

Создание анимации

Использование объекта Animator позволяет осуществлять изменения объектов на экране через определенные промежутки времени. Объект Animator похож на объект Timer, но, в отличие от таймера он позволяет реализовывать различные эффекты. Давайте поговорим об использовании элемента управления GenList в следующем примере.

Создайт новый проект 'AnimatorSample'. Внесите следующие изменения в начале файла исходного кода.

typedef struct appdata {
Evas_Object *win;
Evas_Object *conform;
Evas_Object *label;
Evas_Object *rect1;
Evas_Object *rect2;
} appdata_s;
Eina_Bool anim_continue = ECORE_CALLBACK_RENEW;
Ecore_Pos_Map pos_map = ECORE_POS_MAP_LINEAR;

Добавьте код в функцию create_base_gui().

/* Conformant */
/*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*/
/*ad->label = elm_label_add(ad->conform);
elm_object_text_set(ad->label, "Hello EFL");
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);*/
/* Evas */
Evas *evas = evas_object_evas_get(ad->win);
/* Rect-1 */
ad->rect1 = evas_object_rectangle_add(evas);
evas_object_pass_events_set(ad->rect1, EINA_TRUE);
evas_object_color_set(ad->rect1, 0, 0, 160, 160);
evas_object_resize(ad->rect1, 50, 50);
evas_object_show(ad->rect1);
/* Animation-1 */
Ecore_Animator *anim = ecore_animator_add(on_next_frame1, ad->rect1);
ecore_animator_frametime_set(1. / 60);
/* Show window after base gui is set up */
evas_object_show(ad->win);

Добавьте объект Evas для создания объекта Rectangle.

ecore_animator_add(Ecore_Task_Cb, void *) - это API, который создает объект Animator. Временные интервалы задаются в секундах. Добавьте функцию выше create_base_gui() .

static Eina_Bool on_next_frame1(void *data)
{
static int x = 0;
if (x >= 350)
x = 0;
evas_object_move(data, x += 2, 50);
return anim_continue;
}

evas_object_move() - это API, который изменяет положение объета на экране.

Запустите пример.

Остановка анимации

Для остановки анимации функция-обработчик события кадра должна возвращать значение ECORE_CALLBACK_CANCEL. Добавьте функцию выше create_base_gui().

static void
my_table_pack(Evas_Object *table, Evas_Object *child, int x, int y, int w, int h)
{
evas_object_size_hint_align_set(child, EVAS_HINT_FILL, 0.5);
evas_object_size_hint_weight_set(child, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_table_pack(table, child, x, y, w, h);
evas_object_show(child);
}

Добавьте код в функцию create_base_gui().

/* Rect-1 */
ad->rect1 = evas_object_rectangle_add(evas);
evas_object_pass_events_set(ad->rect1, EINA_TRUE);
evas_object_color_set(ad->rect1, 0, 0, 160, 160);
evas_object_resize(ad->rect1, 50, 50);
evas_object_show(ad->rect1);

{
/* Box to put the table in so we can bottom-align the table
* window will stretch all resize object content to win size */
Evas_Object *box = elm_box_add(ad->win);
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(ad->win, box);
evas_object_show(box);
/* Table */
Evas_Object *table = elm_table_add(ad->win);
/* Make table homogenous - every cell will be the same size */
elm_table_homogeneous_set(table, EINA_TRUE);
/* Set padding of 10 pixels multiplied by scale factor of UI */
elm_table_padding_set(table, 20 * elm_config_scale_get(), 10 * elm_config_scale_get());
/* Let the table child allocation area expand within in the box */
evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
/* Set table to fiill width but align to bottom of box */
evas_object_size_hint_align_set(table, EVAS_HINT_FILL, 1.0);
elm_box_pack_end(box, table);
evas_object_show(table);
{
/* Button-1 */
Evas_Object *btn = elm_button_add(ad->win);
elm_object_text_set(btn, "■");
evas_object_smart_callback_add(btn, "clicked", btn_stop_cb, NULL);
my_table_pack(table, btn, 0, 0, 2, 1);
}
}
evas_object_raise(ad->rect1);
/* Animation-1 */
Ecore_Animator *anim = ecore_animator_add(on_next_frame1, ad->rect1);

evas_object_raise() - это API, который перемещает объекты в самый верх экрана. Добавьте обработчик нажатия кнопки выше функции create_base_gui().

static void
btn_stop_cb(void *data, Evas_Object *obj, void *event_info)
{
anim_continue = ECORE_CALLBACK_CANCEL;
}

Запустите пример.

Приостановка/возобновление анимации с помощью таймера

Для приостановки анимации, вам нужно использоваться функцией ecore_animator_freeze(). Для возобновления анимации, вам нужно использовать функцию ecore_animator_thaw(). Добавьте новый код в функции create_base_gui (). Этот код создает два таймера.

/* Animation-1 */
Ecore_Animator *anim = ecore_animator_add(on_next_frame1, ad->rect1);
/* add 2 timers to go off every 6 seconds */
ecore_timer_add(6, freeze_anim, anim);
Ecore_Timer *timer = ecore_timer_add(6, thaw_anim, anim);
/* delay the last timer by 3 seconds so the 2 timers are offset */
ecore_timer_delay(timer, 3);

Добавьте две функции выше create_base_gui().

static Eina_Bool freeze_anim(void *data)
{
ecore_animator_freeze(data);
// Animation stop Timer delete
return ECORE_CALLBACK_CANCEL;
}
static Eina_Bool thaw_anim(void *data)
{
ecore_animator_thaw(data);
// Animation restart Timer delete
return ECORE_CALLBACK_CANCEL;
}

ecore_animator_freeze(Ecore_Animator *) - это API, который приостанавливает анимацию

ecore_animator_thaw(Ecore_Animator *) - это API, который возобновляет.

Запустите пример

Временная шкала анимации

В этом разделе мы поговорим о реализации анимации, воспроизводящейся заданные промежуток времени. Добавьте код в функцию create_base_gui().

/* Rect-1 */
ad->rect1 = evas_object_rectangle_add(evas);
evas_object_pass_events_set(ad->rect1, EINA_TRUE);
evas_object_color_set(ad->rect1, 0, 0, 160, 160);
evas_object_resize(ad->rect1, 50, 50);
evas_object_show(ad->rect1);

/* Rect-2 */
ad->rect2 = evas_object_rectangle_add(evas);
evas_object_pass_events_set(ad->rect2, EINA_TRUE);
evas_object_color_set(ad->rect2, 0, 55, 0, 160);
evas_object_resize(ad->rect2, 50, 50);
evas_object_show(ad->rect2);

{
~
}
evas_object_raise(ad->rect1);
evas_object_raise(ad->rect2);
/* Animation-1 */
Ecore_Animator *anim = ecore_animator_add(on_next_frame1, ad->rect1);
/* add 2 timers to go off every 6 seconds */
ecore_timer_add(6, freeze_anim, anim);
Ecore_Timer *timer = ecore_timer_add(6, thaw_anim, anim);
/* delay the last timer by 3 seconds so the 2 timers are offset */
ecore_timer_delay(timer, 3);
/* Animation-2 */
ecore_animator_timeline_add(4, on_next_frame2, ad->rect2);
/* Show window after base gui is set up */
evas_object_show(ad->win);

ecore_animator_timeline_add(double, Ecore_Timeline_Cb, void *) - это API, который создает объект TimeLine анимации. Добавьте код выше функции create_base_gui().

static Eina_Bool on_next_frame2(void *data, double pos)
{
double frame = ecore_animator_pos_map(pos, pos_map, 1.2, 15);
evas_object_resize(data, 50 * (1 + frame * 2), 50 * (1 + frame * 2));
evas_object_move(data, 200 * frame, 200 * frame + 100);
evas_object_color_set(data, 255 * frame, 0, 255 * (1 - frame), 255);
return ECORE_CALLBACK_RENEW;
}

ecore_animator_pos_map() - это API, который возвращает результирующее значение, которое характеризует текущее состояние анимации. Изменяется от 0 до 1.

Запустите пример.

Добавление ускорения к временной шкале анимации

Добавьте код в функцию create_base_gui().

/* Button-1 */
Evas_Object *btn = elm_button_add(ad->win);
elm_object_text_set(btn, "■");
evas_object_smart_callback_add(btn, "clicked", btn_stop_cb, NULL);
my_table_pack(table, btn, 0, 0, 2, 1);

/* Button-2 */
btn = elm_button_add(ad->win);
elm_object_text_set(btn, "Accelerate");
evas_object_smart_callback_add(btn, "clicked", btn_accelerate_cb, ad->rect2);
my_table_pack(table, btn, 0, 1, 1, 1);
}
}

Добавьте обработчик нажатия кнопки выше функции create_base_gui().

static void
btn_accelerate_cb(void *data, Evas_Object *obj, void *event_info)
{
pos_map = ECORE_POS_MAP_ACCELERATE;
ecore_animator_timeline_add(4, on_next_frame2, data);
}

Запустите пример

Другие стили анимации

Добавьте коды создания кнопок в функцию create_base_gui().

/* Button-2 */
btn = elm_button_add(ad->win);
elm_object_text_set(btn, "Accelerate");
evas_object_smart_callback_add(btn, "clicked", btn_accelerate_cb, ad->rect2);
my_table_pack(table, btn, 0, 1, 1, 1);

/* Button-3 */
btn = elm_button_add(ad->win);
elm_object_text_set(btn, "Decelerate");
evas_object_smart_callback_add(btn, "clicked", btn_decelerate_cb, ad->rect2);
my_table_pack(table, btn, 1, 1, 1, 1);

/* Button-4 */
btn = elm_button_add(ad->win);
elm_object_text_set(btn, "Sinusoidal");
evas_object_smart_callback_add(btn, "clicked", btn_sinusoidal_cb, ad->rect2);
my_table_pack(table, btn, 0, 2, 1, 1);

/* Button-5 */
btn = elm_button_add(ad->win);
elm_object_text_set(btn, "Bounce");
evas_object_smart_callback_add(btn, "clicked", btn_bounce_cb, ad->rect2);
my_table_pack(table, btn, 1, 2, 1, 1);

/* Button-6 */
btn = elm_button_add(ad->win);
elm_object_text_set(btn, "Spring");
evas_object_smart_callback_add(btn, "clicked", btn_spring_cb, ad->rect2);
my_table_pack(table, btn, 0, 3, 1, 1);

}
}

Добавьте четыре обработчика нажатия кнопок выше функции create_base_gui().

static void
btn_decelerate_cb(void *data, Evas_Object *obj, void *event_info)
{
pos_map = ECORE_POS_MAP_DECELERATE;
ecore_animator_timeline_add(4, on_next_frame2, data);
}
static void
btn_sinusoidal_cb(void *data, Evas_Object *obj, void *event_info)
{
pos_map = ECORE_POS_MAP_SINUSOIDAL;
ecore_animator_timeline_add(4, on_next_frame2, data);
}
static void
btn_bounce_cb(void *data, Evas_Object *obj, void *event_info)
{
pos_map = ECORE_POS_MAP_BOUNCE;
ecore_animator_timeline_add(4, on_next_frame2, data);
}
static void
btn_spring_cb(void *data, Evas_Object *obj, void *event_info)
{
pos_map = ECORE_POS_MAP_SPRING;
ecore_animator_timeline_add(4, on_next_frame2, data);
}

Запустите пример

Непрерывные анимации

Добавьте код в функцию create_base_gui().

/* Button-6 */
btn = elm_button_add(ad->win);
elm_object_text_set(btn, "Spring");
evas_object_smart_callback_add(btn, "clicked", btn_spring_cb, ad->rect2);
my_table_pack(table, btn, 0, 3, 1, 1);

/* Button-7 */
btn = elm_button_add(ad->win);
elm_object_text_set(btn, "Twice");
evas_object_smart_callback_add(btn, "clicked", btn_twice_cb, ad->rect2);
my_table_pack(table, btn, 1, 3, 1, 1);

}
}

Добавьте обработчики событий выше функции create_base_gui().

static Eina_Bool
start_second_anim(void *data)
{
pos_map = ECORE_POS_MAP_SPRING;
ecore_animator_timeline_add(4, on_next_frame2, data);
return ECORE_CALLBACK_CANCEL;
}
static void
btn_twice_cb(void *data, Evas_Object *obj, void *event_info)
{
pos_map = ECORE_POS_MAP_ACCELERATE;
ecore_animator_timeline_add(4, on_next_frame2, data);
ecore_timer_add(4, start_second_anim, data);
}

Запустите пример

Вернуться к учебному плану