mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-14 06:42:58 +08:00
refact(anim_timeline): refact anim timeline design (#5061)
Signed-off-by: FASTSHIFT <vifextech@foxmail.com> Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
parent
d7237d4923
commit
4b995448bc
@ -147,6 +147,9 @@ timeline.
|
||||
|
||||
It supports forward and backward playback of the entire animation group,
|
||||
using :cpp:expr:`lv_anim_timeline_set_reverse(at, reverse)`.
|
||||
Note that if you want to play in reverse from the end of the timeline,
|
||||
you need to call :cpp:expr:`lv_anim_timeline_set_progress(at, LV_ANIM_TIMELINE_PROGRESS_MAX)`
|
||||
after adding all animations and before starting to play.
|
||||
|
||||
Call :cpp:expr:`lv_anim_timeline_stop(at)` to stop the animation timeline.
|
||||
|
||||
@ -159,8 +162,9 @@ duration of the entire animation timeline.
|
||||
Call :cpp:expr:`lv_anim_timeline_get_reverse(at)` function to get whether to
|
||||
reverse the animation timeline.
|
||||
|
||||
Call :cpp:expr:`lv_anim_timeline_delete(at)` function to delete the animation
|
||||
timeline.
|
||||
Call :cpp:expr:`lv_anim_timeline_delete(at)` function to delete the animation timeline.
|
||||
**Note**: If you need to delete an object during animation, be sure to delete the
|
||||
anim timeline before deleting the object. Otherwise, the program may crash or behave abnormally.
|
||||
|
||||
.. image:: /misc/anim-timeline.png
|
||||
|
||||
|
@ -1,12 +1,6 @@
|
||||
#include "../lv_examples.h"
|
||||
#if LV_USE_FLEX && LV_BUILD_EXAMPLES
|
||||
|
||||
static lv_anim_timeline_t * anim_timeline = NULL;
|
||||
|
||||
static lv_obj_t * obj1 = NULL;
|
||||
static lv_obj_t * obj2 = NULL;
|
||||
static lv_obj_t * obj3 = NULL;
|
||||
|
||||
static const int32_t obj_width = 90;
|
||||
static const int32_t obj_height = 70;
|
||||
|
||||
@ -20,9 +14,98 @@ static void set_height(lv_anim_t * var, int32_t v)
|
||||
lv_obj_set_height(var->var, v);
|
||||
}
|
||||
|
||||
static void anim_timeline_create(void)
|
||||
static void set_slider_value(lv_anim_t * var, int32_t v)
|
||||
{
|
||||
/* obj1 */
|
||||
lv_slider_set_value(var->var, v, LV_ANIM_OFF);
|
||||
}
|
||||
|
||||
static void btn_start_event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * btn = lv_event_get_current_target_obj(e);
|
||||
lv_anim_timeline_t * anim_timeline = lv_event_get_user_data(e);
|
||||
|
||||
bool reverse = lv_obj_has_state(btn, LV_STATE_CHECKED);
|
||||
lv_anim_timeline_set_reverse(anim_timeline, reverse);
|
||||
lv_anim_timeline_start(anim_timeline);
|
||||
}
|
||||
|
||||
static void btn_pause_event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_anim_timeline_t * anim_timeline = lv_event_get_user_data(e);
|
||||
lv_anim_timeline_pause(anim_timeline);
|
||||
}
|
||||
|
||||
static void slider_prg_event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * slider = lv_event_get_current_target_obj(e);
|
||||
lv_anim_timeline_t * anim_timeline = lv_event_get_user_data(e);
|
||||
int32_t progress = lv_slider_get_value(slider);
|
||||
lv_anim_timeline_set_progress(anim_timeline, progress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an animation timeline
|
||||
*/
|
||||
void lv_example_anim_timeline_1(void)
|
||||
{
|
||||
/* Create anim timeline */
|
||||
lv_anim_timeline_t * anim_timeline = lv_anim_timeline_create();
|
||||
|
||||
lv_obj_t * par = lv_screen_active();
|
||||
lv_obj_set_flex_flow(par, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(par, LV_FLEX_ALIGN_SPACE_AROUND, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
/* create btn_start */
|
||||
lv_obj_t * btn_start = lv_button_create(par);
|
||||
lv_obj_add_event_cb(btn_start, btn_start_event_handler, LV_EVENT_VALUE_CHANGED, anim_timeline);
|
||||
lv_obj_add_flag(btn_start, LV_OBJ_FLAG_IGNORE_LAYOUT);
|
||||
lv_obj_add_flag(btn_start, LV_OBJ_FLAG_CHECKABLE);
|
||||
lv_obj_align(btn_start, LV_ALIGN_TOP_MID, -100, 20);
|
||||
|
||||
lv_obj_t * label_start = lv_label_create(btn_start);
|
||||
lv_label_set_text(label_start, "Start");
|
||||
lv_obj_center(label_start);
|
||||
|
||||
/* create btn_pause */
|
||||
lv_obj_t * btn_pause = lv_button_create(par);
|
||||
lv_obj_add_event_cb(btn_pause, btn_pause_event_handler, LV_EVENT_CLICKED, anim_timeline);
|
||||
lv_obj_add_flag(btn_pause, LV_OBJ_FLAG_IGNORE_LAYOUT);
|
||||
lv_obj_align(btn_pause, LV_ALIGN_TOP_MID, 100, 20);
|
||||
|
||||
lv_obj_t * label_pause = lv_label_create(btn_pause);
|
||||
lv_label_set_text(label_pause, "Pause");
|
||||
lv_obj_center(label_pause);
|
||||
|
||||
/* create slider_prg */
|
||||
lv_obj_t * slider_prg = lv_slider_create(par);
|
||||
lv_obj_add_event_cb(slider_prg, slider_prg_event_handler, LV_EVENT_VALUE_CHANGED, anim_timeline);
|
||||
lv_obj_add_flag(slider_prg, LV_OBJ_FLAG_IGNORE_LAYOUT);
|
||||
lv_obj_align(slider_prg, LV_ALIGN_BOTTOM_MID, 0, -20);
|
||||
lv_slider_set_range(slider_prg, 0, LV_ANIM_TIMELINE_PROGRESS_MAX);
|
||||
|
||||
/* create 3 objects */
|
||||
lv_obj_t * obj1 = lv_obj_create(par);
|
||||
lv_obj_set_size(obj1, obj_width, obj_height);
|
||||
lv_obj_set_scrollbar_mode(obj1, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
lv_obj_t * obj2 = lv_obj_create(par);
|
||||
lv_obj_set_size(obj2, obj_width, obj_height);
|
||||
lv_obj_set_scrollbar_mode(obj2, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
lv_obj_t * obj3 = lv_obj_create(par);
|
||||
lv_obj_set_size(obj3, obj_width, obj_height);
|
||||
lv_obj_set_scrollbar_mode(obj3, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
/* anim-slider */
|
||||
lv_anim_t a_slider;
|
||||
lv_anim_init(&a_slider);
|
||||
lv_anim_set_var(&a_slider, slider_prg);
|
||||
lv_anim_set_values(&a_slider, 0, LV_ANIM_TIMELINE_PROGRESS_MAX);
|
||||
lv_anim_set_custom_exec_cb(&a_slider, set_slider_value);
|
||||
lv_anim_set_path_cb(&a_slider, lv_anim_path_linear);
|
||||
lv_anim_set_duration(&a_slider, 700);
|
||||
|
||||
/* anim-obj1 */
|
||||
lv_anim_t a1;
|
||||
lv_anim_init(&a1);
|
||||
lv_anim_set_var(&a1, obj1);
|
||||
@ -39,7 +122,7 @@ static void anim_timeline_create(void)
|
||||
lv_anim_set_path_cb(&a2, lv_anim_path_ease_out);
|
||||
lv_anim_set_duration(&a2, 300);
|
||||
|
||||
/* obj2 */
|
||||
/* anim-obj2 */
|
||||
lv_anim_t a3;
|
||||
lv_anim_init(&a3);
|
||||
lv_anim_set_var(&a3, obj2);
|
||||
@ -56,7 +139,7 @@ static void anim_timeline_create(void)
|
||||
lv_anim_set_path_cb(&a4, lv_anim_path_ease_out);
|
||||
lv_anim_set_duration(&a4, 300);
|
||||
|
||||
/* obj3 */
|
||||
/* anim-obj3 */
|
||||
lv_anim_t a5;
|
||||
lv_anim_init(&a5);
|
||||
lv_anim_set_var(&a5, obj3);
|
||||
@ -73,119 +156,16 @@ static void anim_timeline_create(void)
|
||||
lv_anim_set_path_cb(&a6, lv_anim_path_ease_out);
|
||||
lv_anim_set_duration(&a6, 300);
|
||||
|
||||
/* Create anim timeline */
|
||||
anim_timeline = lv_anim_timeline_create();
|
||||
/* add animations to timeline */
|
||||
lv_anim_timeline_add(anim_timeline, 0, &a_slider);
|
||||
lv_anim_timeline_add(anim_timeline, 0, &a1);
|
||||
lv_anim_timeline_add(anim_timeline, 0, &a2);
|
||||
lv_anim_timeline_add(anim_timeline, 200, &a3);
|
||||
lv_anim_timeline_add(anim_timeline, 200, &a4);
|
||||
lv_anim_timeline_add(anim_timeline, 400, &a5);
|
||||
lv_anim_timeline_add(anim_timeline, 400, &a6);
|
||||
}
|
||||
|
||||
static void btn_start_event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * btn = lv_event_get_target(e);
|
||||
|
||||
if(!anim_timeline) {
|
||||
anim_timeline_create();
|
||||
}
|
||||
|
||||
bool reverse = lv_obj_has_state(btn, LV_STATE_CHECKED);
|
||||
lv_anim_timeline_set_reverse(anim_timeline, reverse);
|
||||
lv_anim_timeline_start(anim_timeline);
|
||||
}
|
||||
|
||||
static void btn_delete_event_handler(lv_event_t * e)
|
||||
{
|
||||
LV_UNUSED(e);
|
||||
if(anim_timeline) {
|
||||
lv_anim_timeline_delete(anim_timeline);
|
||||
anim_timeline = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void btn_stop_event_handler(lv_event_t * e)
|
||||
{
|
||||
LV_UNUSED(e);
|
||||
if(anim_timeline) {
|
||||
lv_anim_timeline_stop(anim_timeline);
|
||||
}
|
||||
}
|
||||
|
||||
static void slider_prg_event_handler(lv_event_t * e)
|
||||
{
|
||||
lv_obj_t * slider = lv_event_get_target(e);
|
||||
|
||||
if(!anim_timeline) {
|
||||
anim_timeline_create();
|
||||
}
|
||||
|
||||
int32_t progress = lv_slider_get_value(slider);
|
||||
lv_anim_timeline_set_progress(anim_timeline, progress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an animation timeline
|
||||
*/
|
||||
void lv_example_anim_timeline_1(void)
|
||||
{
|
||||
lv_obj_t * par = lv_screen_active();
|
||||
lv_obj_set_flex_flow(par, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(par, LV_FLEX_ALIGN_SPACE_AROUND, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
/* create btn_start */
|
||||
lv_obj_t * btn_start = lv_button_create(par);
|
||||
lv_obj_add_event_cb(btn_start, btn_start_event_handler, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_obj_add_flag(btn_start, LV_OBJ_FLAG_IGNORE_LAYOUT);
|
||||
lv_obj_add_flag(btn_start, LV_OBJ_FLAG_CHECKABLE);
|
||||
lv_obj_align(btn_start, LV_ALIGN_TOP_MID, -100, 20);
|
||||
|
||||
lv_obj_t * label_start = lv_label_create(btn_start);
|
||||
lv_label_set_text(label_start, "Start");
|
||||
lv_obj_center(label_start);
|
||||
|
||||
/* create btn_del */
|
||||
lv_obj_t * btn_del = lv_button_create(par);
|
||||
lv_obj_add_event_cb(btn_del, btn_delete_event_handler, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_add_flag(btn_del, LV_OBJ_FLAG_IGNORE_LAYOUT);
|
||||
lv_obj_align(btn_del, LV_ALIGN_TOP_MID, 0, 20);
|
||||
|
||||
lv_obj_t * label_del = lv_label_create(btn_del);
|
||||
lv_label_set_text(label_del, "Delete");
|
||||
lv_obj_center(label_del);
|
||||
|
||||
/* create btn_stop */
|
||||
lv_obj_t * btn_stop = lv_button_create(par);
|
||||
lv_obj_add_event_cb(btn_stop, btn_stop_event_handler, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_add_flag(btn_stop, LV_OBJ_FLAG_IGNORE_LAYOUT);
|
||||
lv_obj_align(btn_stop, LV_ALIGN_TOP_MID, 100, 20);
|
||||
|
||||
lv_obj_t * label_stop = lv_label_create(btn_stop);
|
||||
lv_label_set_text(label_stop, "Stop");
|
||||
lv_obj_center(label_stop);
|
||||
|
||||
/* create slider_prg */
|
||||
lv_obj_t * slider_prg = lv_slider_create(par);
|
||||
lv_obj_add_event_cb(slider_prg, slider_prg_event_handler, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_obj_add_flag(slider_prg, LV_OBJ_FLAG_IGNORE_LAYOUT);
|
||||
lv_obj_align(slider_prg, LV_ALIGN_BOTTOM_MID, 0, -20);
|
||||
lv_slider_set_range(slider_prg, 0, 65535);
|
||||
|
||||
/* create 3 objects */
|
||||
obj1 = lv_obj_create(par);
|
||||
lv_obj_set_size(obj1, obj_width, obj_height);
|
||||
lv_obj_set_scrollbar_mode(obj1, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
obj2 = lv_obj_create(par);
|
||||
lv_obj_set_size(obj2, obj_width, obj_height);
|
||||
lv_obj_set_scrollbar_mode(obj2, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
obj3 = lv_obj_create(par);
|
||||
lv_obj_set_size(obj3, obj_width, obj_height);
|
||||
lv_obj_set_scrollbar_mode(obj3, LV_SCROLLBAR_MODE_OFF);
|
||||
|
||||
anim_timeline_create();
|
||||
lv_anim_timeline_set_progress(anim_timeline, LV_ANIM_TIMELINE_PROGRESS_MAX);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -18,11 +18,26 @@
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
/*Data of anim_timeline_dsc*/
|
||||
typedef struct {
|
||||
lv_anim_t anim;
|
||||
uint32_t start_time;
|
||||
} lv_anim_timeline_dsc_t;
|
||||
|
||||
/*Data of anim_timeline*/
|
||||
struct _lv_anim_timeline_t {
|
||||
lv_anim_timeline_dsc_t * anim_dsc; /**< Dynamically allocated anim dsc array*/
|
||||
uint32_t anim_dsc_cnt; /**< The length of anim dsc array*/
|
||||
uint32_t act_time; /**< Current time of the animation*/
|
||||
bool reverse; /**< Reverse playback*/
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_anim_timeline_virtual_exec_cb(void * var, int32_t v);
|
||||
static void anim_timeline_exec_cb(void * var, int32_t v);
|
||||
static void anim_timeline_set_act_time(lv_anim_timeline_t * at, uint32_t act_time);
|
||||
static int32_t anim_timeline_path_cb(const lv_anim_t * a);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@ -47,13 +62,13 @@ void lv_anim_timeline_delete(lv_anim_timeline_t * at)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
lv_anim_timeline_stop(at);
|
||||
lv_anim_timeline_pause(at);
|
||||
|
||||
lv_free(at->anim_dsc);
|
||||
lv_free(at);
|
||||
}
|
||||
|
||||
void lv_anim_timeline_add(lv_anim_timeline_t * at, uint32_t start_time, lv_anim_t * a)
|
||||
void lv_anim_timeline_add(lv_anim_timeline_t * at, uint32_t start_time, const lv_anim_t * a)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
@ -64,50 +79,33 @@ void lv_anim_timeline_add(lv_anim_timeline_t * at, uint32_t start_time, lv_anim_
|
||||
|
||||
at->anim_dsc[at->anim_dsc_cnt - 1].anim = *a;
|
||||
at->anim_dsc[at->anim_dsc_cnt - 1].start_time = start_time;
|
||||
|
||||
/*Add default var and virtual exec_cb, used to delete animation.*/
|
||||
if(a->var == NULL && a->exec_cb == NULL && a->custom_exec_cb == NULL) {
|
||||
at->anim_dsc[at->anim_dsc_cnt - 1].anim.var = at;
|
||||
at->anim_dsc[at->anim_dsc_cnt - 1].anim.exec_cb = lv_anim_timeline_virtual_exec_cb;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
const uint32_t playtime = lv_anim_timeline_get_playtime(at);
|
||||
bool reverse = at->reverse;
|
||||
|
||||
for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
|
||||
lv_anim_t a = at->anim_dsc[i].anim;
|
||||
uint32_t start_time = at->anim_dsc[i].start_time;
|
||||
|
||||
if(reverse) {
|
||||
int32_t temp = a.start_value;
|
||||
a.start_value = a.end_value;
|
||||
a.end_value = temp;
|
||||
lv_anim_set_delay(&a, playtime - (start_time + a.duration));
|
||||
}
|
||||
else {
|
||||
lv_anim_set_delay(&a, start_time);
|
||||
}
|
||||
|
||||
lv_anim_start(&a);
|
||||
}
|
||||
uint32_t playtime = lv_anim_timeline_get_playtime(at);
|
||||
uint32_t start = at->act_time;
|
||||
uint32_t end = at->reverse ? 0 : playtime;
|
||||
uint32_t duration = end > start ? end - start : start - end;
|
||||
|
||||
lv_anim_t a;
|
||||
lv_anim_init(&a);
|
||||
lv_anim_set_var(&a, at);
|
||||
lv_anim_set_exec_cb(&a, anim_timeline_exec_cb);
|
||||
lv_anim_set_values(&a, start, end);
|
||||
lv_anim_set_time(&a, duration);
|
||||
lv_anim_set_path_cb(&a, anim_timeline_path_cb);
|
||||
lv_anim_start(&a);
|
||||
return playtime;
|
||||
}
|
||||
|
||||
void lv_anim_timeline_stop(lv_anim_timeline_t * at)
|
||||
void lv_anim_timeline_pause(lv_anim_timeline_t * at)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
|
||||
lv_anim_t * a = &(at->anim_dsc[i].anim);
|
||||
if(a->exec_cb) lv_anim_delete(a->var, a->exec_cb);
|
||||
else lv_anim_delete(a->var, NULL);
|
||||
}
|
||||
lv_anim_delete(at, anim_timeline_exec_cb);
|
||||
}
|
||||
|
||||
void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse)
|
||||
@ -120,9 +118,49 @@ void lv_anim_timeline_set_progress(lv_anim_timeline_t * at, uint16_t progress)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
const uint32_t playtime = lv_anim_timeline_get_playtime(at);
|
||||
const uint32_t act_time = progress * playtime / 0xFFFF;
|
||||
uint32_t playtime = lv_anim_timeline_get_playtime(at);
|
||||
uint32_t act_time = lv_map(progress, 0, LV_ANIM_TIMELINE_PROGRESS_MAX, 0, playtime);
|
||||
anim_timeline_set_act_time(at, act_time);
|
||||
}
|
||||
|
||||
uint32_t lv_anim_timeline_get_playtime(lv_anim_timeline_t * at)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
uint32_t playtime = 0;
|
||||
for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
|
||||
uint32_t end = lv_anim_get_playtime(&at->anim_dsc[i].anim);
|
||||
if(end == LV_ANIM_PLAYTIME_INFINITE)
|
||||
return end;
|
||||
end += at->anim_dsc[i].start_time;
|
||||
if(end > playtime) {
|
||||
playtime = end;
|
||||
}
|
||||
}
|
||||
|
||||
return playtime;
|
||||
}
|
||||
|
||||
bool lv_anim_timeline_get_reverse(lv_anim_timeline_t * at)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
return at->reverse;
|
||||
}
|
||||
|
||||
uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
uint32_t playtime = lv_anim_timeline_get_playtime(at);
|
||||
return lv_map(at->act_time, 0, playtime, 0, LV_ANIM_TIMELINE_PROGRESS_MAX);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void anim_timeline_set_act_time(lv_anim_timeline_t * at, uint32_t act_time)
|
||||
{
|
||||
at->act_time = act_time;
|
||||
for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
|
||||
lv_anim_t * a = &(at->anim_dsc[i].anim);
|
||||
|
||||
@ -151,36 +189,14 @@ void lv_anim_timeline_set_progress(lv_anim_timeline_t * at, uint16_t progress)
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lv_anim_timeline_get_playtime(lv_anim_timeline_t * at)
|
||||
static int32_t anim_timeline_path_cb(const lv_anim_t * a)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
|
||||
uint32_t playtime = 0;
|
||||
for(uint32_t i = 0; i < at->anim_dsc_cnt; i++) {
|
||||
uint32_t end = lv_anim_get_playtime(&at->anim_dsc[i].anim);
|
||||
if(end == LV_ANIM_PLAYTIME_INFINITE)
|
||||
return end;
|
||||
end += at->anim_dsc[i].start_time;
|
||||
if(end > playtime) {
|
||||
playtime = end;
|
||||
}
|
||||
}
|
||||
|
||||
return playtime;
|
||||
/* Directly map original timestamps to avoid loss of accuracy */
|
||||
return lv_map(a->act_time, 0, a->duration, a->start_value, a->end_value);
|
||||
}
|
||||
|
||||
bool lv_anim_timeline_get_reverse(lv_anim_timeline_t * at)
|
||||
static void anim_timeline_exec_cb(void * var, int32_t v)
|
||||
{
|
||||
LV_ASSERT_NULL(at);
|
||||
return at->reverse;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_anim_timeline_virtual_exec_cb(void * var, int32_t v)
|
||||
{
|
||||
LV_UNUSED(var);
|
||||
LV_UNUSED(v);
|
||||
lv_anim_timeline_t * at = var;
|
||||
anim_timeline_set_act_time(at, v);
|
||||
}
|
||||
|
@ -19,22 +19,13 @@ extern "C" {
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define LV_ANIM_TIMELINE_PROGRESS_MAX 0xFFFF
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/*Data of anim_timeline_dsc*/
|
||||
typedef struct {
|
||||
lv_anim_t anim;
|
||||
uint32_t start_time;
|
||||
} lv_anim_timeline_dsc_t;
|
||||
|
||||
/*Data of anim_timeline*/
|
||||
typedef struct {
|
||||
lv_anim_timeline_dsc_t * anim_dsc; /**< Dynamically allocated anim dsc array*/
|
||||
uint32_t anim_dsc_cnt; /**< The length of anim dsc array*/
|
||||
bool reverse; /**< Reverse playback*/
|
||||
} lv_anim_timeline_t;
|
||||
typedef struct _lv_anim_timeline_t lv_anim_timeline_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
@ -58,7 +49,7 @@ void lv_anim_timeline_delete(lv_anim_timeline_t * at);
|
||||
* @param start_time the time the animation started on the timeline, note that start_time will override the value of delay.
|
||||
* @param a pointer to an animation.
|
||||
*/
|
||||
void lv_anim_timeline_add(lv_anim_timeline_t * at, uint32_t start_time, lv_anim_t * a);
|
||||
void lv_anim_timeline_add(lv_anim_timeline_t * at, uint32_t start_time, const lv_anim_t * a);
|
||||
|
||||
/**
|
||||
* Start the animation timeline.
|
||||
@ -68,10 +59,10 @@ void lv_anim_timeline_add(lv_anim_timeline_t * at, uint32_t start_time, lv_anim_
|
||||
uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at);
|
||||
|
||||
/**
|
||||
* Stop the animation timeline.
|
||||
* Pause the animation timeline.
|
||||
* @param at pointer to the animation timeline.
|
||||
*/
|
||||
void lv_anim_timeline_stop(lv_anim_timeline_t * at);
|
||||
void lv_anim_timeline_pause(lv_anim_timeline_t * at);
|
||||
|
||||
/**
|
||||
* Set the playback direction of the animation timeline.
|
||||
@ -101,6 +92,13 @@ uint32_t lv_anim_timeline_get_playtime(lv_anim_timeline_t * at);
|
||||
*/
|
||||
bool lv_anim_timeline_get_reverse(lv_anim_timeline_t * at);
|
||||
|
||||
/**
|
||||
* Get the progress of the animation timeline.
|
||||
* @param at pointer to the animation timeline.
|
||||
* @return return value 0~65535 to map 0~100% animation progress.
|
||||
*/
|
||||
uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -202,11 +202,11 @@ void test_anim_timeline_start(void)
|
||||
lv_test_wait(100); /*1100*/
|
||||
TEST_ASSERT_EQUAL(100, lv_obj_get_x(obj));
|
||||
|
||||
/*Nothing should change it*/
|
||||
/*Should change it*/
|
||||
lv_obj_set_x(obj, 10);
|
||||
|
||||
lv_test_wait(100); /*1200*/
|
||||
TEST_ASSERT_EQUAL(10, lv_obj_get_x(obj));
|
||||
TEST_ASSERT_EQUAL(100, lv_obj_get_x(obj));
|
||||
|
||||
lv_test_wait(300); /*1500*/
|
||||
TEST_ASSERT_EQUAL(200, lv_obj_get_x(obj));
|
||||
@ -272,7 +272,7 @@ void test_anim_timeline_reverse(void)
|
||||
lv_anim_set_duration(&a1, 1500);
|
||||
lv_anim_timeline_add(anim_timeline, 2000, &a1);
|
||||
|
||||
lv_anim_timeline_set_reverse(anim_timeline, true);
|
||||
lv_anim_timeline_set_progress(anim_timeline, LV_ANIM_TIMELINE_PROGRESS_MAX);
|
||||
lv_anim_timeline_start(anim_timeline); /*0 (3500)*/
|
||||
|
||||
lv_refr_now(NULL);
|
||||
@ -282,23 +282,23 @@ void test_anim_timeline_reverse(void)
|
||||
TEST_ASSERT_EQUAL(500, lv_obj_get_x(obj));
|
||||
|
||||
lv_test_wait(201); /*1200 (2300)*/
|
||||
TEST_ASSERT_EQUAL(280, lv_obj_get_x(obj));
|
||||
TEST_ASSERT_EQUAL(459, lv_obj_get_x(obj));
|
||||
|
||||
lv_test_wait(300); /*1500 (2000)*/
|
||||
TEST_ASSERT_EQUAL(250, lv_obj_get_x(obj));
|
||||
TEST_ASSERT_EQUAL(400, lv_obj_get_x(obj));
|
||||
|
||||
lv_test_wait(500); /*2000 (1500)*/
|
||||
TEST_ASSERT_EQUAL(200, lv_obj_get_x(obj));
|
||||
|
||||
/*There is a gap*/
|
||||
lv_test_wait(100); /*2100 (1400)*/
|
||||
TEST_ASSERT_EQUAL(200, lv_obj_get_x(obj));
|
||||
TEST_ASSERT_EQUAL(100, lv_obj_get_x(obj));
|
||||
|
||||
/*Nothing should change it*/
|
||||
/*Should change it*/
|
||||
lv_obj_set_x(obj, 10);
|
||||
|
||||
lv_test_wait(100); /*2200 (1300)*/
|
||||
TEST_ASSERT_EQUAL(10, lv_obj_get_x(obj));
|
||||
TEST_ASSERT_EQUAL(100, lv_obj_get_x(obj));
|
||||
|
||||
lv_test_wait(300); /*2500 (1000)*/
|
||||
TEST_ASSERT_EQUAL(100, lv_obj_get_x(obj));
|
||||
|
Loading…
x
Reference in New Issue
Block a user