refactor SparklePulse to inherit Sparkle and use the pulse generator

This commit is contained in:
Roy Hooper 2020-05-19 14:03:18 -04:00
parent be18d57233
commit 5f5d51899a
4 changed files with 51 additions and 57 deletions

View file

@ -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
)

View file

@ -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

View file

@ -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()

View file

@ -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)