- AnimationBase ABC with render(t, led_count) and from_params() contract - SolidColorAnimation: time-independent uniform fill - ChaseAnimation: moving lit segment with forward/reverse support - PulseAnimation: sine-wave breathing effect (speed maps to period) - RainbowAnimation: HSV hue cycle across strip via colorsys.hsv_to_rgb - StrobeAnimation: on/off flashing at 1-20 Hz with configurable duty cycle - ColorWipeAnimation: progressive fill from start or end - FireAnimation: Fire2012 algorithm with cooling/sparking/heat-to-color mapping - ANIMATION_REGISTRY + create_animation() factory function - All 24 tests passing
49 lines
1.5 KiB
Python
49 lines
1.5 KiB
Python
"""Animation library — 7 built-in animation types with a factory registry."""
|
|
from lightsync.animations.base import AnimationBase
|
|
from lightsync.animations.solid_color import SolidColorAnimation
|
|
from lightsync.animations.chase import ChaseAnimation
|
|
from lightsync.animations.pulse import PulseAnimation
|
|
from lightsync.animations.rainbow import RainbowAnimation
|
|
from lightsync.animations.strobe import StrobeAnimation
|
|
from lightsync.animations.color_wipe import ColorWipeAnimation
|
|
from lightsync.animations.fire import FireAnimation
|
|
|
|
__all__ = [
|
|
"AnimationBase",
|
|
"SolidColorAnimation",
|
|
"ChaseAnimation",
|
|
"PulseAnimation",
|
|
"RainbowAnimation",
|
|
"StrobeAnimation",
|
|
"ColorWipeAnimation",
|
|
"FireAnimation",
|
|
"ANIMATION_REGISTRY",
|
|
"create_animation",
|
|
]
|
|
|
|
ANIMATION_REGISTRY: dict[str, type[AnimationBase]] = {
|
|
"solid_color": SolidColorAnimation,
|
|
"chase": ChaseAnimation,
|
|
"pulse": PulseAnimation,
|
|
"rainbow": RainbowAnimation,
|
|
"strobe": StrobeAnimation,
|
|
"color_wipe": ColorWipeAnimation,
|
|
"fire": FireAnimation,
|
|
}
|
|
|
|
|
|
def create_animation(name: str, params: dict) -> AnimationBase:
|
|
"""Create an animation by registry name.
|
|
|
|
Args:
|
|
name: Animation type name (e.g. "chase", "fire").
|
|
params: CueModel.params dict passed to from_params().
|
|
|
|
Raises:
|
|
ValueError: If name is not in ANIMATION_REGISTRY.
|
|
"""
|
|
cls = ANIMATION_REGISTRY.get(name)
|
|
if cls is None:
|
|
raise ValueError(f"Unknown animation: {name!r}. Available: {sorted(ANIMATION_REGISTRY)}")
|
|
return cls.from_params(params)
|