[lvgl] Add pause option to round_trip animation timing (#17574)

This commit is contained in:
Clyde Stubbs
2026-08-05 14:16:22 +12:00
committed by GitHub
parent 97d33a5679
commit 27dcf64b45
5 changed files with 49 additions and 11 deletions
+14 -4
View File
@@ -21,12 +21,22 @@ class LvAnimationTiming {
class LvAnimationTimingRoundTrip : public LvAnimationTiming {
public:
// moving_length_ is the fraction of progress spent moving in each direction, in (0, 0.5].
// Callers must pass pause in [0, 1) -- pause == 1.0 would make moving_length_ zero and divide by zero below.
LvAnimationTimingRoundTrip(float pause) : moving_length_((1.0f - pause) / 2.0f) {}
float map_progress(float value) override {
value *= 2.0f;
if (value > 1.0f)
return 2.0f - value;
return value;
if (value < this->moving_length_) {
return value / this->moving_length_;
}
if (value > 1.0f - this->moving_length_) {
return (1.0f - value) / this->moving_length_;
}
// pause in the middle
return 1.0f;
}
protected:
float moving_length_{};
};
class LvAnimationTimingGravity : public LvAnimationTiming {
+13 -2
View File
@@ -42,6 +42,7 @@ LvAnimationTimingRoundTrip = lvgl_ns.class_("LvAnimationTimingRoundTrip")
LvAnimationTimingEaseInOut = lvgl_ns.class_("LvAnimationTimingEaseInOut")
CONF_BOUNCE = "bounce"
CONF_PAUSE = "pause"
def timing_class(name, extras=None):
@@ -60,10 +61,20 @@ TIMING_SCHEMA = cv.maybe_simple_value(
cv.typed_schema(
dict(
[
timing_class("round_trip"),
timing_class(
"round_trip",
{
cv.Optional(CONF_PAUSE, default=0.0): cv.All(
cv.percentage,
cv.float_range(
min=0.0, max=1.0, min_included=True, max_included=False
),
)
},
),
timing_class(
"ease_in_out",
{cv.Optional(CONF_WEIGHT, default=2.0): lv_positive_float},
{cv.Optional(CONF_WEIGHT, default=1.0): cv.zero_to_one_float},
),
timing_class(
"gravity",
+16 -3
View File
@@ -169,14 +169,27 @@ class TestTimingSchema:
def test_round_trip_string(self) -> None:
assert TIMING_SCHEMA("round_trip")["type"] == "round_trip"
def test_round_trip_default_pause(self) -> None:
# Back-compat default: no pause, matching the pre-existing round_trip behavior.
assert TIMING_SCHEMA("round_trip")["pause"] == pytest.approx(0.0)
def test_round_trip_pause_percentage_string(self) -> None:
result = TIMING_SCHEMA({"type": "round_trip", "pause": "50%"})
assert result["pause"] == pytest.approx(0.5)
def test_round_trip_pause_rejects_one(self) -> None:
# pause == 1.0 would make moving_length_ zero and divide by zero in map_progress.
with pytest.raises((Invalid, MultipleInvalid)):
TIMING_SCHEMA({"type": "round_trip", "pause": 1.0})
def test_ease_in_out_default_weight(self) -> None:
result = TIMING_SCHEMA("ease_in_out")
assert result["type"] == "ease_in_out"
assert result["weight"] == pytest.approx(2.0)
assert result["weight"] == pytest.approx(1.0)
def test_ease_in_out_custom_weight(self) -> None:
result = TIMING_SCHEMA({"type": "ease_in_out", "weight": 3})
assert result["weight"] == pytest.approx(3.0)
result = TIMING_SCHEMA({"type": "ease_in_out", "weight": 0.5})
assert result["weight"] == pytest.approx(0.5)
def test_gravity_defaults(self) -> None:
result = TIMING_SCHEMA("gravity")
+5 -1
View File
@@ -174,7 +174,8 @@ lvgl:
- id: anim_color
duration: 2s
timing:
- round_trip
- type: round_trip
pause: 0.5
- type: gravity
bounce: 0.3
acceleration: 0.8
@@ -1557,17 +1558,20 @@ font:
image:
- id: cat_image
platform: file
resize: 256x48
file: $component_dir/logo-text.svg
type: RGB565
transparency: alpha_channel
- id: dog_image
platform: file
file: $component_dir/logo-text.svg
resize: 256x48
type: BINARY
transparency: chroma_key
- id: alert
platform: file
file: $component_dir/logo-text.svg
type: grayscale
resize: 100x100
+1 -1
View File
@@ -39,7 +39,7 @@ lvgl:
timing:
- round_trip
- type: ease_in_out
weight: 3
weight: 0.5
on_start:
- logger.log: anim started
on_stop: