refactor SparklePulse to inherit Sparkle and use the pulse generator
This commit is contained in:
parent
be18d57233
commit
5f5d51899a
4 changed files with 51 additions and 57 deletions
|
|
@ -68,7 +68,7 @@ class Pulse(Animation):
|
|||
|
||||
def draw(self):
|
||||
color = next(self._generator)
|
||||
self.fill(color)
|
||||
self.pixel_object.fill(color)
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
|
|
@ -77,8 +77,13 @@ class Pulse(Animation):
|
|||
white = len(self.pixel_object[0]) > 3 and isinstance(
|
||||
self.pixel_object[0][-1], int
|
||||
)
|
||||
dotstar = len(self.pixel_object[0]) == 4 and isinstance(
|
||||
self.pixel_object[0][-1], float
|
||||
)
|
||||
from adafruit_led_animation.helper import ( # pylint: disable=import-outside-toplevel
|
||||
pulse_generator,
|
||||
)
|
||||
|
||||
self._generator = pulse_generator(self._period, self, white)
|
||||
self._generator = pulse_generator(
|
||||
self._period, self, white, dotstar_pwm=dotstar
|
||||
)
|
||||
|
|
|
|||
|
|
@ -64,9 +64,11 @@ class Sparkle(Animation):
|
|||
def __init__(self, pixel_object, speed, color, num_sparkles=1, name=None):
|
||||
if len(pixel_object) < 2:
|
||||
raise ValueError("Sparkle needs at least 2 pixels")
|
||||
self._half_color = None
|
||||
self._dim_color = None
|
||||
self._half_color = color
|
||||
self._dim_color = color
|
||||
self._sparkle_color = color
|
||||
self._num_sparkles = num_sparkles
|
||||
self._pixels = []
|
||||
super().__init__(pixel_object, speed, color, name=name)
|
||||
|
||||
def _recompute_color(self, color):
|
||||
|
|
@ -79,15 +81,18 @@ class Sparkle(Animation):
|
|||
self.pixel_object[pixel] = dim_color
|
||||
self._half_color = half_color
|
||||
self._dim_color = dim_color
|
||||
self._sparkle_color = color
|
||||
|
||||
def draw(self):
|
||||
pixels = [
|
||||
self._pixels = [
|
||||
random.randint(0, (len(self.pixel_object) - 2))
|
||||
for n in range(self._num_sparkles)
|
||||
for _ in range(self._num_sparkles)
|
||||
]
|
||||
for pixel in pixels:
|
||||
self.pixel_object[pixel] = self._color
|
||||
for pixel in self._pixels:
|
||||
self.pixel_object[pixel] = self._sparkle_color
|
||||
|
||||
def after_draw(self):
|
||||
self.show()
|
||||
for pixel in pixels:
|
||||
for pixel in self._pixels:
|
||||
self.pixel_object[pixel] = self._half_color
|
||||
self.pixel_object[pixel + 1] = self._dim_color
|
||||
|
|
|
|||
|
|
@ -44,14 +44,13 @@ Implementation Notes
|
|||
|
||||
"""
|
||||
|
||||
import random
|
||||
from adafruit_led_animation import NANOS_PER_SECOND, monotonic_ns
|
||||
from adafruit_led_animation.animation import Animation
|
||||
from adafruit_led_animation.animation.sparkle import Sparkle
|
||||
from adafruit_led_animation.helper import pulse_generator
|
||||
|
||||
|
||||
class SparklePulse(Animation):
|
||||
class SparklePulse(Sparkle):
|
||||
"""
|
||||
Combination of the Spark and Pulse animations.
|
||||
Combination of the Sparkle and Pulse animations.
|
||||
|
||||
:param pixel_object: The initialised LED object.
|
||||
:param int speed: Animation refresh rate in seconds, e.g. ``0.1``.
|
||||
|
|
@ -63,50 +62,30 @@ class SparklePulse(Animation):
|
|||
|
||||
# pylint: disable=too-many-arguments
|
||||
def __init__(
|
||||
self, pixel_object, speed, color, period=5, max_intensity=1, min_intensity=0
|
||||
self,
|
||||
pixel_object,
|
||||
speed,
|
||||
color,
|
||||
period=5,
|
||||
max_intensity=1,
|
||||
min_intensity=0,
|
||||
name=None,
|
||||
):
|
||||
if len(pixel_object) < 2:
|
||||
raise ValueError("Sparkle needs at least 2 pixels")
|
||||
self.max_intensity = max_intensity
|
||||
self.min_intensity = min_intensity
|
||||
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])
|
||||
# Handle dotstars
|
||||
if self._bpp == 4 and isinstance(pixel_object[0][3], float):
|
||||
self._bpp = 3
|
||||
self._last_update = monotonic_ns()
|
||||
self._cycle_position = 0
|
||||
self._half_color = None
|
||||
self._dim_color = None
|
||||
super().__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
|
||||
white = len(pixel_object) == 4 and isinstance(pixel_object[0][-1], int)
|
||||
dotstar = len(pixel_object) == 4 and isinstance(pixel_object[0][-1], float)
|
||||
super().__init__(
|
||||
pixel_object, speed=speed, color=color, num_sparkles=1, name=name
|
||||
)
|
||||
self._generator = pulse_generator(
|
||||
self._period, self, white, dotstar_pwm=dotstar
|
||||
)
|
||||
|
||||
def draw(self):
|
||||
pixel = random.randint(0, (len(self.pixel_object) - 2))
|
||||
self._sparkle_color = next(self._generator)
|
||||
super().draw()
|
||||
|
||||
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
|
||||
def after_draw(self):
|
||||
self.show()
|
||||
|
|
|
|||
|
|
@ -361,12 +361,13 @@ class PixelSubset:
|
|||
self._pixels.auto_write = value
|
||||
|
||||
|
||||
def pulse_generator(period: float, animation_object, white=False):
|
||||
def pulse_generator(period: float, animation_object, white=False, dotstar_pwm=False):
|
||||
"""
|
||||
Generates a sequence of colors for a pulse, based on the time period specified.
|
||||
:param period: Pulse duration in seconds.
|
||||
:param animation_object: An animation object to interact with.
|
||||
:param white: Whether the pixel strip has a white pixel.
|
||||
:param dotstar_pwm: Whether to use the dostar per pixel PWM value for brightness control.
|
||||
"""
|
||||
period = int(period * NANOS_PER_SECOND)
|
||||
half_period = period // 2
|
||||
|
|
@ -386,6 +387,10 @@ def pulse_generator(period: float, animation_object, white=False):
|
|||
if pos > half_period:
|
||||
pos = period - pos
|
||||
intensity = pos / half_period
|
||||
if dotstar_pwm:
|
||||
fill_color = (fill_color[0], fill_color[1], fill_color[2], intensity)
|
||||
yield fill_color
|
||||
continue
|
||||
if white:
|
||||
fill_color[3] = int(fill_color[3] * intensity)
|
||||
fill_color[0] = int(fill_color[0] * intensity)
|
||||
|
|
|
|||
Loading…
Reference in a new issue