mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
[lvgl] Add pause option to round_trip animation timing (#17574)
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user