Skip to content

Commit 5f5d518

Browse files
committed
refactor SparklePulse to inherit Sparkle and use the pulse generator
1 parent be18d57 commit 5f5d518

File tree

4 files changed

+52
-58
lines changed

4 files changed

+52
-58
lines changed

adafruit_led_animation/animation/pulse.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def __init__(self, pixel_object, speed, color, period=5, name=None):
6868

6969
def draw(self):
7070
color = next(self._generator)
71-
self.fill(color)
71+
self.pixel_object.fill(color)
7272

7373
def reset(self):
7474
"""
@@ -77,8 +77,13 @@ def reset(self):
7777
white = len(self.pixel_object[0]) > 3 and isinstance(
7878
self.pixel_object[0][-1], int
7979
)
80+
dotstar = len(self.pixel_object[0]) == 4 and isinstance(
81+
self.pixel_object[0][-1], float
82+
)
8083
from adafruit_led_animation.helper import ( # pylint: disable=import-outside-toplevel
8184
pulse_generator,
8285
)
8386

84-
self._generator = pulse_generator(self._period, self, white)
87+
self._generator = pulse_generator(
88+
self._period, self, white, dotstar_pwm=dotstar
89+
)

adafruit_led_animation/animation/sparkle.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ class Sparkle(Animation):
6464
def __init__(self, pixel_object, speed, color, num_sparkles=1, name=None):
6565
if len(pixel_object) < 2:
6666
raise ValueError("Sparkle needs at least 2 pixels")
67-
self._half_color = None
68-
self._dim_color = None
67+
self._half_color = color
68+
self._dim_color = color
69+
self._sparkle_color = color
6970
self._num_sparkles = num_sparkles
71+
self._pixels = []
7072
super().__init__(pixel_object, speed, color, name=name)
7173

7274
def _recompute_color(self, color):
@@ -79,15 +81,18 @@ def _recompute_color(self, color):
7981
self.pixel_object[pixel] = dim_color
8082
self._half_color = half_color
8183
self._dim_color = dim_color
84+
self._sparkle_color = color
8285

8386
def draw(self):
84-
pixels = [
87+
self._pixels = [
8588
random.randint(0, (len(self.pixel_object) - 2))
86-
for n in range(self._num_sparkles)
89+
for _ in range(self._num_sparkles)
8790
]
88-
for pixel in pixels:
89-
self.pixel_object[pixel] = self._color
91+
for pixel in self._pixels:
92+
self.pixel_object[pixel] = self._sparkle_color
93+
94+
def after_draw(self):
9095
self.show()
91-
for pixel in pixels:
96+
for pixel in self._pixels:
9297
self.pixel_object[pixel] = self._half_color
9398
self.pixel_object[pixel + 1] = self._dim_color

adafruit_led_animation/animation/sparklepulse.py

Lines changed: 27 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,13 @@
4444
4545
"""
4646

47-
import random
48-
from adafruit_led_animation import NANOS_PER_SECOND, monotonic_ns
49-
from adafruit_led_animation.animation import Animation
47+
from adafruit_led_animation.animation.sparkle import Sparkle
48+
from adafruit_led_animation.helper import pulse_generator
5049

5150

52-
class SparklePulse(Animation):
51+
class SparklePulse(Sparkle):
5352
"""
54-
Combination of the Spark and Pulse animations.
53+
Combination of the Sparkle and Pulse animations.
5554
5655
:param pixel_object: The initialised LED object.
5756
:param int speed: Animation refresh rate in seconds, e.g. ``0.1``.
@@ -63,50 +62,30 @@ class SparklePulse(Animation):
6362

6463
# pylint: disable=too-many-arguments
6564
def __init__(
66-
self, pixel_object, speed, color, period=5, max_intensity=1, min_intensity=0
65+
self,
66+
pixel_object,
67+
speed,
68+
color,
69+
period=5,
70+
max_intensity=1,
71+
min_intensity=0,
72+
name=None,
6773
):
68-
if len(pixel_object) < 2:
69-
raise ValueError("Sparkle needs at least 2 pixels")
70-
self.max_intensity = max_intensity
71-
self.min_intensity = min_intensity
74+
self._max_intensity = max_intensity
75+
self._min_intensity = min_intensity
7276
self._period = period
73-
self._intensity_delta = max_intensity - min_intensity
74-
self._half_period = period / 2
75-
self._position_factor = 1 / self._half_period
76-
self._bpp = len(pixel_object[0])
77-
# Handle dotstars
78-
if self._bpp == 4 and isinstance(pixel_object[0][3], float):
79-
self._bpp = 3
80-
self._last_update = monotonic_ns()
81-
self._cycle_position = 0
82-
self._half_color = None
83-
self._dim_color = None
84-
super().__init__(pixel_object, speed, color)
85-
86-
def _recompute_color(self, color):
87-
half_color = tuple(color[rgb] // 4 for rgb in range(len(color)))
88-
dim_color = tuple(color[rgb] // 10 for rgb in range(len(color)))
89-
for pixel in range(len(self.pixel_object)):
90-
if self.pixel_object[pixel] == self._half_color:
91-
self.pixel_object[pixel] = half_color
92-
elif self.pixel_object[pixel] == self._dim_color:
93-
self.pixel_object[pixel] = dim_color
94-
self._half_color = half_color
95-
self._dim_color = dim_color
77+
white = len(pixel_object) == 4 and isinstance(pixel_object[0][-1], int)
78+
dotstar = len(pixel_object) == 4 and isinstance(pixel_object[0][-1], float)
79+
super().__init__(
80+
pixel_object, speed=speed, color=color, num_sparkles=1, name=name
81+
)
82+
self._generator = pulse_generator(
83+
self._period, self, white, dotstar_pwm=dotstar
84+
)
9685

9786
def draw(self):
98-
pixel = random.randint(0, (len(self.pixel_object) - 2))
99-
100-
now = monotonic_ns()
101-
time_since_last_draw = (now - self._last_update) / NANOS_PER_SECOND
102-
self._last_update = now
103-
pos = self._cycle_position = (
104-
self._cycle_position + time_since_last_draw
105-
) % self._period
106-
if pos > self._half_period:
107-
pos = self._period - pos
108-
intensity = self.min_intensity + (
109-
pos * self._intensity_delta * self._position_factor
110-
)
111-
color = [int(self.color[n] * intensity) for n in range(self._bpp)]
112-
self.pixel_object[pixel] = color
87+
self._sparkle_color = next(self._generator)
88+
super().draw()
89+
90+
def after_draw(self):
91+
self.show()

adafruit_led_animation/helper.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,12 +361,13 @@ def auto_write(self, value):
361361
self._pixels.auto_write = value
362362

363363

364-
def pulse_generator(period: float, animation_object, white=False):
364+
def pulse_generator(period: float, animation_object, white=False, dotstar_pwm=False):
365365
"""
366366
Generates a sequence of colors for a pulse, based on the time period specified.
367367
:param period: Pulse duration in seconds.
368368
:param animation_object: An animation object to interact with.
369369
:param white: Whether the pixel strip has a white pixel.
370+
:param dotstar_pwm: Whether to use the dostar per pixel PWM value for brightness control.
370371
"""
371372
period = int(period * NANOS_PER_SECOND)
372373
half_period = period // 2
@@ -386,6 +387,10 @@ def pulse_generator(period: float, animation_object, white=False):
386387
if pos > half_period:
387388
pos = period - pos
388389
intensity = pos / half_period
390+
if dotstar_pwm:
391+
fill_color = (fill_color[0], fill_color[1], fill_color[2], intensity)
392+
yield fill_color
393+
continue
389394
if white:
390395
fill_color[3] = int(fill_color[3] * intensity)
391396
fill_color[0] = int(fill_color[0] * intensity)

0 commit comments

Comments
 (0)