1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

feat(anim): add custom cubic-bezier anim path parameter support (#4343)

Signed-off-by: Xu Xingliang <xuxingliang@xiaomi.com>
This commit is contained in:
Neo Xu 2023-07-10 06:38:26 +08:00 committed by GitHub
parent 95b9fe327f
commit 7151395e34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 16 deletions

View File

@ -304,6 +304,12 @@ int32_t lv_anim_path_step(const lv_anim_t * a)
return a->start_value;
}
int32_t lv_anim_path_custom_bezier3(const lv_anim_t * a)
{
const struct _lv_anim_bezier3_para_t * para = &a->parameter.bezier3;
return lv_anim_path_cubic_bezier(a, para->x1, para->y1, para->x2, para->y2);
}
/**********************
* STATIC FUNCTIONS
**********************/

View File

@ -14,6 +14,7 @@ extern "C" {
* INCLUDES
*********************/
#include "../lv_conf_internal.h"
#include "lv_math.h"
#include <stdint.h>
#include <stdbool.h>
@ -26,6 +27,52 @@ extern "C" {
#define LV_ANIM_REPEAT_INFINITE 0xFFFF
#define LV_ANIM_PLAYTIME_INFINITE 0xFFFFFFFF
/*
* Macros used to set cubic-bezier anim parameter.
* Parameters come from https://easings.net/
*
* Usage:
*
* lv_anim_t a;
* lv_anim_init(&a);
* ...
* lv_anim_set_path_cb(&a, lv_anim_path_custom_bezier3);
* LV_ANIM_SET_EASE_IN_SINE(&a); //Set cubic-bezier anim parameter to easeInSine
* ...
* lv_anim_start(&a);
*/
#define _PARA(a, x1, y1, x2, y2) ((a)->parameter.bezier3 = \
(struct _lv_anim_bezier3_para_t) { \
LV_BEZIER_VAL_FLOAT(x1), LV_BEZIER_VAL_FLOAT(y1), \
LV_BEZIER_VAL_FLOAT(x2), LV_BEZIER_VAL_FLOAT(y2) } \
)
#define LV_ANIM_SET_EASE_IN_SINE(a) _PARA(a, 0.12, 0, 0.39, 0)
#define LV_ANIM_SET_EASE_OUT_SINE(a) _PARA(a, 0.61, 1, 0.88, 1)
#define LV_ANIM_SET_EASE_IN_OUT_SINE(a) _PARA(a, 0.37, 0, 0.63, 1)
#define LV_ANIM_SET_EASE_IN_QUAD(a) _PARA(a, 0.11, 0, 0.5, 0)
#define LV_ANIM_SET_EASE_OUT_QUAD(a) _PARA(a, 0.5, 1, 0.89, 1)
#define LV_ANIM_SET_EASE_IN_OUT_QUAD(a) _PARA(a, 0.45, 0, 0.55, 1)
#define LV_ANIM_SET_EASE_IN_CUBIC(a) _PARA(a, 0.32, 0, 0.67, 0)
#define LV_ANIM_SET_EASE_OUT_CUBIC(a) _PARA(a, 0.33, 1, 0.68, 1)
#define LV_ANIM_SET_EASE_IN_OUT_CUBIC(a) _PARA(a, 0.65, 0, 0.35, 1)
#define LV_ANIM_SET_EASE_IN_QUART(a) _PARA(a, 0.5, 0, 0.75, 0)
#define LV_ANIM_SET_EASE_OUT_QUART(a) _PARA(a, 0.25, 1, 0.5, 1)
#define LV_ANIM_SET_EASE_IN_OUT_QUART(a) _PARA(a, 0.76, 0, 0.24, 1)
#define LV_ANIM_SET_EASE_IN_QUINT(a) _PARA(a, 0.64, 0, 0.78, 0)
#define LV_ANIM_SET_EASE_OUT_QUINT(a) _PARA(a, 0.22, 1, 0.36, 1)
#define LV_ANIM_SET_EASE_IN_OUT_QUINT(a) _PARA(a, 0.83, 0, 0.17, 1)
#define LV_ANIM_SET_EASE_IN_EXPO(a) _PARA(a, 0.7, 0, 0.84, 0)
#define LV_ANIM_SET_EASE_OUT_EXPO(a) _PARA(a, 0.16, 1, 0.3, 1)
#define LV_ANIM_SET_EASE_IN_OUT_EXPO(a) _PARA(a, 0.87, 0, 0.13, 1)
#define LV_ANIM_SET_EASE_IN_CIRC(a) _PARA(a, 0.55, 0, 1, 0.45)
#define LV_ANIM_SET_EASE_OUT_CIRC(a) _PARA(a, 0, 0.55, 0.45, 1)
#define LV_ANIM_SET_EASE_IN_OUT_CIRC(a) _PARA(a, 0.85, 0, 0.15, 1)
#define LV_ANIM_SET_EASE_IN_BACK(a) _PARA(a, 0.36, 0, 0.66, -0.56)
#define LV_ANIM_SET_EASE_OUT_BACK(a) _PARA(a, 0.34, 1.56, 0.64, 1)
#define LV_ANIM_SET_EASE_IN_OUT_BACK(a) _PARA(a, 0.68, -0.6, 0.32, 1.6)
LV_EXPORT_CONST_INT(LV_ANIM_REPEAT_INFINITE);
LV_EXPORT_CONST_INT(LV_ANIM_PLAYTIME_INFINITE);
@ -88,6 +135,15 @@ typedef struct _lv_anim_t {
uint32_t playback_time; /**< Duration of playback animation*/
uint32_t repeat_delay; /**< Wait before repeat*/
uint16_t repeat_cnt; /**< Repeat count for the animation*/
union _lv_anim_path_para_t {
struct _lv_anim_bezier3_para_t {
int16_t x1;
int16_t y1;
int16_t x2;
int16_t y2;
} bezier3; /**< Parameter used when path is custom_bezier*/
} parameter;
uint8_t early_apply : 1; /**< 1: Apply start value immediately even is there is `delay`*/
/*Animation system use these - user shouldn't set*/
@ -299,6 +355,24 @@ static inline void lv_anim_set_user_data(lv_anim_t * a, void * user_data)
a->user_data = user_data;
}
/**
* Set parameter for cubic bezier path
* @param a pointer to an initialized `lv_anim_t` variable
* @param x1 first control point
* @param y1
* @param y1 second control point
*/
static inline void lv_anim_set_bezier3_param(lv_anim_t * a, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
{
struct _lv_anim_bezier3_para_t * para = &a->parameter.bezier3;
para->x1 = x1;
para->x2 = x2;
para->y1 = y1;
para->y2 = y2;
}
/**
* Create an animation
* @param a an initialized 'anim_t' variable. Not required after call.
@ -484,6 +558,13 @@ int32_t lv_anim_path_bounce(const lv_anim_t * a);
*/
int32_t lv_anim_path_step(const lv_anim_t * a);
/**
* A custom cubic bezier animation path, need to specify cubic-parameters in a->parameter.bezier3
* @param a pointer to an animation
* @return the current value to set
*/
int32_t lv_anim_path_custom_bezier3(const lv_anim_t * a);
/**********************
* GLOBAL VARIABLES
**********************/

View File

@ -23,7 +23,6 @@
static void lv_spinner_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj);
static void arc_anim_start_angle(void * obj, int32_t v);
static void arc_anim_end_angle(void * obj, int32_t v);
static int32_t anim_path(const lv_anim_t * a);
/**********************
* STATIC VARIABLES
@ -81,7 +80,9 @@ static void lv_spinner_constructor(const lv_obj_class_t * class_p, lv_obj_t * ob
lv_anim_set_values(&a, arc_length_param, 360 + arc_length_param);
lv_anim_start(&a);
lv_anim_set_path_cb(&a, anim_path);
lv_anim_set_path_cb(&a, lv_anim_path_custom_bezier3);
lv_anim_set_bezier3_param(&a, LV_BEZIER_VAL_FLOAT(0.42), LV_BEZIER_VAL_FLOAT(0.58),
LV_BEZIER_VAL_FLOAT(0), LV_BEZIER_VAL_FLOAT(1));
lv_anim_set_values(&a, 0, 360);
lv_anim_set_exec_cb(&a, arc_anim_start_angle);
lv_anim_start(&a);
@ -102,18 +103,4 @@ static void arc_anim_end_angle(void * obj, int32_t v)
lv_arc_set_end_angle(obj, (uint16_t) v);
}
static int32_t anim_path(const lv_anim_t * a)
{
uint32_t t = lv_map(a->act_time, 0, a->time, 0, LV_BEZIER_VAL_MAX);
int32_t step = lv_cubic_bezier(t, LV_BEZIER_VAL_FLOAT(0.42), LV_BEZIER_VAL_FLOAT(0.58),
LV_BEZIER_VAL_FLOAT(0), LV_BEZIER_VAL_FLOAT(1));
int32_t new_value;
new_value = step * (a->end_value - a->start_value);
new_value = new_value >> LV_BEZIER_VAL_SHIFT;
new_value += a->start_value;
return new_value;
}
#endif /*LV_USE_SPINNER*/