diff --git a/adafruit_led_animation/animation.py b/adafruit_led_animation/animation.py index 242bd8f..dcfd36a 100644 --- a/adafruit_led_animation/animation.py +++ b/adafruit_led_animation/animation.py @@ -367,6 +367,59 @@ def draw(self): self.fill(color) self.show() +class SparklePulse(Animation): + """ + Combination of the Spark and Pulse animations. + + :param pixel_object: The initialised LED object. + :param int speed: Animation refresh rate in seconds, e.g. ``0.1``. + :param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format. + :param period: Period to pulse the LEDs over. Default 5. + :param max_intensity: The maximum intensity to pulse, between 0 and 1.0. Default 1. + :param min_intensity: The minimum intensity to pulse, between 0 and 1.0. Default 0. + """ + + # pylint: disable=too-many-arguments + def __init__(self, pixel_object, speed, color, period=5, max_intensity=1, min_intensity=0): + if len(pixel_object) < 2: + raise ValueError("Sparkle needs at least 2 pixels") + self.max_intensity = max_intensity + self.min_intensity = min_intensity + self._period = period + self._intensity_delta = max_intensity - min_intensity + self._half_period = period / 2 + self._position_factor = 1 / self._half_period + self._bpp = len(pixel_object[0]) + self._last_update = monotonic_ns() + self._cycle_position = 0 + self._half_color = None + self._dim_color = None + super(SparklePulse, self).__init__(pixel_object, speed, color) + + def _recompute_color(self, color): + half_color = tuple(color[rgb] // 4 for rgb in range(len(color))) + dim_color = tuple(color[rgb] // 10 for rgb in range(len(color))) + for pixel in range(len(self.pixel_object)): + if self.pixel_object[pixel] == self._half_color: + self.pixel_object[pixel] = half_color + elif self.pixel_object[pixel] == self._dim_color: + self.pixel_object[pixel] = dim_color + self._half_color = half_color + self._dim_color = dim_color + + def draw(self): + pixel = random.randint(0, (len(self.pixel_object) - 2)) + + now = monotonic_ns() + time_since_last_draw = (now - self._last_update) / NANOS_PER_SECOND + self._last_update = now + pos = self._cycle_position = (self._cycle_position + time_since_last_draw) % self._period + if pos > self._half_period: + pos = self._period - pos + intensity = self.min_intensity + (pos * self._intensity_delta * self._position_factor) + color = [int(self.color[n] * intensity) for n in range(self._bpp)] + self.pixel_object[pixel] = color + self.show() class Chase(Animation): """