diff --git a/src/misc/lv_anim.c b/src/misc/lv_anim.c index e216438db..ab75610a5 100644 --- a/src/misc/lv_anim.c +++ b/src/misc/lv_anim.c @@ -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 **********************/ diff --git a/src/misc/lv_anim.h b/src/misc/lv_anim.h index c55339189..f017a9ee8 100644 --- a/src/misc/lv_anim.h +++ b/src/misc/lv_anim.h @@ -14,6 +14,7 @@ extern "C" { * INCLUDES *********************/ #include "../lv_conf_internal.h" +#include "lv_math.h" #include #include @@ -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 **********************/ diff --git a/src/widgets/spinner/lv_spinner.c b/src/widgets/spinner/lv_spinner.c index 659dac4f9..257c898c0 100644 --- a/src/widgets/spinner/lv_spinner.c +++ b/src/widgets/spinner/lv_spinner.c @@ -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*/