"""Chase animation — a lit segment moves along the strip.""" from lightsync.animations.base import AnimationBase class ChaseAnimation(AnimationBase): """Moving lit segment(s) chasing along the strip. At speed=1.0, the segment moves at 60 pixels/second. Pattern repeats every (size + spacing) pixels. """ def __init__( self, color: tuple[int, int, int] = (255, 255, 255), bg_color: tuple[int, int, int] = (0, 0, 0), speed: float = 0.5, size: int = 3, spacing: int = 7, reverse: bool = False, white: int = 0, ) -> None: self.color = tuple(color) # type: ignore[arg-type] self.bg_color = tuple(bg_color) # type: ignore[arg-type] self.speed = speed self.size = size self.spacing = spacing self.reverse = reverse self.white = white def render(self, t: float, led_count: int) -> list[tuple]: period = self.size + self.spacing offset = int(t * self.speed * 60) # pixels/sec at speed=1.0 is 60 pixels = [] for i in range(led_count): if self.reverse: pos = (i + offset) % period else: pos = (i - offset) % period if pos < self.size: pixels.append(self.color) else: pixels.append(self.bg_color) return pixels @classmethod def from_params(cls, params: dict) -> "ChaseAnimation": return cls( color=tuple(params.get("color", [255, 255, 255])), # type: ignore[arg-type] bg_color=tuple(params.get("bg_color", [0, 0, 0])), # type: ignore[arg-type] speed=params.get("speed", 0.5), size=params.get("size", 3), spacing=params.get("spacing", 7), reverse=params.get("reverse", False), white=params.get("white", 0), )