mirror of
https://github.com/lvgl/lvgl.git
synced 2026-06-02 09:37:42 +08:00
feat(anim_timeline): add repeat and more (#6127)
Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com>
This commit is contained in:
@@ -33,6 +33,8 @@ struct lv_anim_timeline_t {
|
|||||||
uint32_t anim_dsc_cnt; /**< The length of anim dsc array*/
|
uint32_t anim_dsc_cnt; /**< The length of anim dsc array*/
|
||||||
uint32_t act_time; /**< Current time of the animation*/
|
uint32_t act_time; /**< Current time of the animation*/
|
||||||
bool reverse; /**< Reverse playback*/
|
bool reverse; /**< Reverse playback*/
|
||||||
|
uint32_t repeat_count; /**< Repeat count*/
|
||||||
|
uint32_t repeat_delay; /**< Wait before repeat*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
@@ -89,6 +91,8 @@ uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at)
|
|||||||
LV_ASSERT_NULL(at);
|
LV_ASSERT_NULL(at);
|
||||||
|
|
||||||
uint32_t playtime = lv_anim_timeline_get_playtime(at);
|
uint32_t playtime = lv_anim_timeline_get_playtime(at);
|
||||||
|
uint32_t repeat = at->repeat_count;
|
||||||
|
uint32_t delay = at->repeat_delay;
|
||||||
uint32_t start = at->act_time;
|
uint32_t start = at->act_time;
|
||||||
uint32_t end = at->reverse ? 0 : playtime;
|
uint32_t end = at->reverse ? 0 : playtime;
|
||||||
uint32_t duration = end > start ? end - start : start - end;
|
uint32_t duration = end > start ? end - start : start - end;
|
||||||
@@ -107,6 +111,8 @@ uint32_t lv_anim_timeline_start(lv_anim_timeline_t * at)
|
|||||||
lv_anim_set_values(&a, start, end);
|
lv_anim_set_values(&a, start, end);
|
||||||
lv_anim_set_time(&a, duration);
|
lv_anim_set_time(&a, duration);
|
||||||
lv_anim_set_path_cb(&a, anim_timeline_path_cb);
|
lv_anim_set_path_cb(&a, anim_timeline_path_cb);
|
||||||
|
lv_anim_set_repeat_count(&a, repeat);
|
||||||
|
lv_anim_set_repeat_delay(&a, delay);
|
||||||
lv_anim_start(&a);
|
lv_anim_start(&a);
|
||||||
return playtime;
|
return playtime;
|
||||||
}
|
}
|
||||||
@@ -124,6 +130,18 @@ void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse)
|
|||||||
at->reverse = reverse;
|
at->reverse = reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lv_anim_timeline_set_repeat_count(lv_anim_timeline_t * at, uint32_t cnt)
|
||||||
|
{
|
||||||
|
LV_ASSERT_NULL(at);
|
||||||
|
at->repeat_count = cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lv_anim_timeline_set_repeat_delay(lv_anim_timeline_t * at, uint32_t delay)
|
||||||
|
{
|
||||||
|
LV_ASSERT_NULL(at);
|
||||||
|
at->repeat_delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
void lv_anim_timeline_set_progress(lv_anim_timeline_t * at, uint16_t progress)
|
void lv_anim_timeline_set_progress(lv_anim_timeline_t * at, uint16_t progress)
|
||||||
{
|
{
|
||||||
LV_ASSERT_NULL(at);
|
LV_ASSERT_NULL(at);
|
||||||
@@ -164,6 +182,18 @@ uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at)
|
|||||||
return lv_map(at->act_time, 0, playtime, 0, LV_ANIM_TIMELINE_PROGRESS_MAX);
|
return lv_map(at->act_time, 0, playtime, 0, LV_ANIM_TIMELINE_PROGRESS_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t lv_anim_timeline_get_repeat_count(lv_anim_timeline_t * at)
|
||||||
|
{
|
||||||
|
LV_ASSERT_NULL(at);
|
||||||
|
return at->repeat_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t lv_anim_timeline_get_repeat_delay(lv_anim_timeline_t * at)
|
||||||
|
{
|
||||||
|
LV_ASSERT_NULL(at);
|
||||||
|
return at->repeat_delay;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC FUNCTIONS
|
* STATIC FUNCTIONS
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -71,6 +71,20 @@ void lv_anim_timeline_pause(lv_anim_timeline_t * at);
|
|||||||
*/
|
*/
|
||||||
void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse);
|
void lv_anim_timeline_set_reverse(lv_anim_timeline_t * at, bool reverse);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the animation timeline repeat itself.
|
||||||
|
* @param at pointer to the animation timeline.
|
||||||
|
* @param cnt repeat count or `LV_ANIM_REPEAT_INFINITE` for infinite repetition. 0: to disable repetition.
|
||||||
|
*/
|
||||||
|
void lv_anim_timeline_set_repeat_count(lv_anim_timeline_t * at, uint32_t cnt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a delay before repeating the animation timeline.
|
||||||
|
* @param at pointer to the animation timeline.
|
||||||
|
* @param delay delay in milliseconds before repeating the animation timeline.
|
||||||
|
*/
|
||||||
|
void lv_anim_timeline_set_repeat_delay(lv_anim_timeline_t * at, uint32_t delay);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the progress of the animation timeline.
|
* Set the progress of the animation timeline.
|
||||||
* @param at pointer to the animation timeline.
|
* @param at pointer to the animation timeline.
|
||||||
@@ -99,6 +113,18 @@ bool lv_anim_timeline_get_reverse(lv_anim_timeline_t * at);
|
|||||||
*/
|
*/
|
||||||
uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at);
|
uint16_t lv_anim_timeline_get_progress(lv_anim_timeline_t * at);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get repeat count of the animation timeline.
|
||||||
|
* @param at pointer to the animation timeline.
|
||||||
|
*/
|
||||||
|
uint32_t lv_anim_timeline_get_repeat_count(lv_anim_timeline_t * at);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get repeat delay of the animation timeline.
|
||||||
|
* @param at pointer to the animation timeline.
|
||||||
|
*/
|
||||||
|
uint32_t lv_anim_timeline_get_repeat_delay(lv_anim_timeline_t * at);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* MACROS
|
* MACROS
|
||||||
**********************/
|
**********************/
|
||||||
|
|||||||
@@ -327,39 +327,147 @@ void test_anim_timeline_reverse(void)
|
|||||||
TEST_ASSERT_EQUAL(20, lv_obj_get_x(obj));
|
TEST_ASSERT_EQUAL(20, lv_obj_get_x(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_anim_timeline_repeat(void)
|
||||||
|
{
|
||||||
|
lv_obj_t * obj = lv_obj_create(lv_screen_active());
|
||||||
|
lv_obj_set_size(obj, 100, 100);
|
||||||
|
lv_obj_set_pos(obj, 30, 40);
|
||||||
|
|
||||||
|
lv_anim_t a1;
|
||||||
|
lv_anim_init(&a1);
|
||||||
|
lv_anim_set_exec_cb(&a1, (lv_anim_exec_xcb_t)lv_obj_set_x);
|
||||||
|
lv_anim_set_var(&a1, obj);
|
||||||
|
lv_anim_set_values(&a1, 0, 1000);
|
||||||
|
lv_anim_set_duration(&a1, 1000);
|
||||||
|
|
||||||
|
anim_timeline = lv_anim_timeline_create();
|
||||||
|
TEST_ASSERT_NOT_NULL(anim_timeline);
|
||||||
|
|
||||||
|
lv_anim_timeline_add(anim_timeline, 0, &a1);
|
||||||
|
lv_anim_timeline_set_repeat_count(anim_timeline, 3);
|
||||||
|
lv_anim_timeline_set_repeat_delay(anim_timeline, 1);
|
||||||
|
lv_anim_timeline_start(anim_timeline);
|
||||||
|
|
||||||
|
lv_refr_now(NULL);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(1, lv_anim_timeline_get_repeat_delay(anim_timeline));
|
||||||
|
TEST_ASSERT_EQUAL(1000, lv_anim_timeline_get_playtime(anim_timeline));
|
||||||
|
|
||||||
|
lv_test_wait(100);
|
||||||
|
TEST_ASSERT_EQUAL(99, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(500);
|
||||||
|
TEST_ASSERT_EQUAL(599, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(400);
|
||||||
|
TEST_ASSERT_EQUAL(1000, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(1);
|
||||||
|
TEST_ASSERT_EQUAL(0, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(500);
|
||||||
|
TEST_ASSERT_EQUAL(500, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(500);
|
||||||
|
TEST_ASSERT_EQUAL(1000, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(701);
|
||||||
|
TEST_ASSERT_EQUAL(699, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(1000);
|
||||||
|
TEST_ASSERT_EQUAL(1000, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(1000);
|
||||||
|
TEST_ASSERT_EQUAL(1000, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_anim_timeline_delay(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
lv_obj_t * obj = lv_obj_create(lv_screen_active());
|
||||||
|
lv_obj_set_size(obj, 100, 100);
|
||||||
|
lv_obj_set_pos(obj, 30, 40);
|
||||||
|
|
||||||
|
lv_anim_t a1;
|
||||||
|
lv_anim_init(&a1);
|
||||||
|
lv_anim_set_exec_cb(&a1, (lv_anim_exec_xcb_t)lv_obj_set_x);
|
||||||
|
lv_anim_set_var(&a1, obj);
|
||||||
|
lv_anim_set_values(&a1, 0, 1000);
|
||||||
|
lv_anim_set_duration(&a1, 1000);
|
||||||
|
|
||||||
|
anim_timeline = lv_anim_timeline_create();
|
||||||
|
TEST_ASSERT_NOT_NULL(anim_timeline);
|
||||||
|
|
||||||
|
lv_anim_timeline_add(anim_timeline, 0, &a1);
|
||||||
|
lv_anim_timeline_set_repeat_count(anim_timeline, 3);
|
||||||
|
lv_anim_timeline_set_repeat_delay(anim_timeline, 1000);
|
||||||
|
lv_anim_timeline_start(anim_timeline);
|
||||||
|
|
||||||
|
lv_refr_now(NULL);
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL(1000, lv_anim_timeline_get_repeat_delay(anim_timeline));
|
||||||
|
TEST_ASSERT_EQUAL(1000, lv_anim_timeline_get_playtime(anim_timeline));
|
||||||
|
|
||||||
|
lv_test_wait(100);
|
||||||
|
TEST_ASSERT_EQUAL(99, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(500);
|
||||||
|
TEST_ASSERT_EQUAL(599, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(400);
|
||||||
|
TEST_ASSERT_EQUAL(1000, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(1000);
|
||||||
|
TEST_ASSERT_EQUAL(0, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(500);
|
||||||
|
TEST_ASSERT_EQUAL(500, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(500);
|
||||||
|
TEST_ASSERT_EQUAL(1000, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(1700);
|
||||||
|
TEST_ASSERT_EQUAL(699, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(1000);
|
||||||
|
TEST_ASSERT_EQUAL(1000, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
lv_test_wait(1000);
|
||||||
|
TEST_ASSERT_EQUAL(1000, lv_obj_get_x(obj));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void anim1_exec_cb(void * var, int32_t v)
|
void anim1_exec_cb(void * var, int32_t v)
|
||||||
{
|
{
|
||||||
LV_UNUSED(var);
|
LV_UNUSED(var);
|
||||||
printf("[anim1] %d\n", v);
|
LV_UNUSED(v);
|
||||||
}
|
}
|
||||||
void anim1_start(lv_anim_t * a)
|
void anim1_start(lv_anim_t * a)
|
||||||
{
|
{
|
||||||
LV_UNUSED(a);
|
LV_UNUSED(a);
|
||||||
printf("[anim1] start\n");
|
|
||||||
anim1_start_called++;
|
anim1_start_called++;
|
||||||
}
|
}
|
||||||
void anim1_completed(lv_anim_t * a)
|
void anim1_completed(lv_anim_t * a)
|
||||||
{
|
{
|
||||||
LV_UNUSED(a);
|
LV_UNUSED(a);
|
||||||
printf("[anim1] completed\n");
|
|
||||||
anim1_completed_called++;
|
anim1_completed_called++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void anim2_exec_cb(void * var, int32_t v)
|
void anim2_exec_cb(void * var, int32_t v)
|
||||||
{
|
{
|
||||||
LV_UNUSED(var);
|
LV_UNUSED(var);
|
||||||
printf(" [anim2] %d\n", v);
|
LV_UNUSED(v);
|
||||||
}
|
}
|
||||||
void anim2_start(lv_anim_t * a)
|
void anim2_start(lv_anim_t * a)
|
||||||
{
|
{
|
||||||
LV_UNUSED(a);
|
LV_UNUSED(a);
|
||||||
printf(" [anim2] start\n");
|
|
||||||
anim2_start_called++;
|
anim2_start_called++;
|
||||||
}
|
}
|
||||||
void anim2_completed(lv_anim_t * a)
|
void anim2_completed(lv_anim_t * a)
|
||||||
{
|
{
|
||||||
LV_UNUSED(a);
|
LV_UNUSED(a);
|
||||||
printf(" [anim2] completed\n");
|
|
||||||
anim2_completed_called++;
|
anim2_completed_called++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user