Skip to content

Commit 5c90cfa

Browse files
committed
rainbowsparkles
1 parent cdd61d6 commit 5c90cfa

File tree

2 files changed

+118
-7
lines changed

2 files changed

+118
-7
lines changed

adafruit_led_animation/animation/rainbow.py

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,26 +52,43 @@
5252
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation.git"
5353

5454

55+
5556
class Rainbow(Animation):
5657
"""
5758
The classic rainbow color wheel.
5859
5960
:param pixel_object: The initialised LED object.
6061
:param float speed: Animation refresh rate in seconds, e.g. ``0.1``.
61-
:param period: Period to cycle the rainbow over. Default 5.
62+
:param float period: Period to cycle the rainbow over in seconds. Default 5.
63+
:param float step: Color wheel step. Default 1.
64+
:param str name: Name of animation (optional, useful for sequences and debugging).
65+
:param bool precompute_rainbow: Whether to precompute the rainbow. Uses more memory. (default True).
6266
"""
6367

6468
# pylint: disable=too-many-arguments
65-
def __init__(self, pixel_object, speed, period=5, name=None):
69+
def __init__(self, pixel_object, speed, period=5, step=1, name=None, precompute_rainbow=True):
6670
super().__init__(pixel_object, speed, BLACK, name=name)
6771
self._period = period
72+
self._step = step
73+
self._wheel_index = 0
74+
self.colors = None
6875
self._generator = self._color_wheel_generator()
76+
if precompute_rainbow:
77+
self.generate_rainbow()
78+
79+
def generate_rainbow(self):
80+
self.colors = []
81+
i = 0
82+
while i < 256:
83+
self.colors.append(colorwheel(int(i)))
84+
i += self._step
6985

7086
cycle_complete_supported = True
7187

7288
def _color_wheel_generator(self):
7389
period = int(self._period * NANOS_PER_SECOND)
7490

91+
num_pixels = len(self.pixel_object)
7592
last_update = monotonic_ns()
7693
cycle_position = 0
7794
last_pos = 0
@@ -84,16 +101,34 @@ def _color_wheel_generator(self):
84101
if pos < last_pos:
85102
cycle_completed = True
86103
last_pos = pos
87-
wheel_index = int((pos / period) * 256)
88-
self.pixel_object[:] = [
89-
colorwheel((i + wheel_index) % 255)
90-
for i, _ in enumerate(self.pixel_object)
91-
]
104+
wheel_index = int((pos / period) * len(self.colors))
105+
106+
if self.colors:
107+
self._draw_precomputed(num_pixels, wheel_index)
108+
else:
109+
wheel_index = int((pos / period) * 256)
110+
self.pixel_object[:] = [
111+
colorwheel((i + wheel_index) % 255)
112+
for i in range(num_pixels)
113+
]
114+
self._wheel_index = wheel_index
92115
self.show()
93116
if cycle_completed:
94117
self.cycle_complete()
95118
yield
96119

120+
def _draw_precomputed(self, num_pixels, wheel_index):
121+
for i in range(0, num_pixels, len(self.colors)):
122+
num = len(self.colors)
123+
if i + len(self.colors) > num_pixels:
124+
num = num_pixels - i
125+
if wheel_index + num > len(self.colors):
126+
colors_left = len(self.colors) - wheel_index
127+
self.pixel_object[i:i + colors_left] = self.colors[wheel_index:]
128+
self.pixel_object[i + colors_left:i + num] = self.colors[:num - colors_left]
129+
else:
130+
self.pixel_object[i:i + num] = self.colors[wheel_index:wheel_index + num]
131+
97132
def draw(self):
98133
next(self._generator)
99134

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# The MIT License (MIT)
2+
#
3+
# Copyright (c) 2019-2020 Roy Hooper
4+
# Copyright (c) 2020 Kattni Rembor for Adafruit Industries
5+
#
6+
# Permission is hereby granted, free of charge, to any person obtaining a copy
7+
# of this software and associated documentation files (the "Software"), to deal
8+
# in the Software without restriction, including without limitation the rights
9+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
# copies of the Software, and to permit persons to whom the Software is
11+
# furnished to do so, subject to the following conditions:
12+
#
13+
# The above copyright notice and this permission notice shall be included in
14+
# all copies or substantial portions of the Software.
15+
#
16+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
# THE SOFTWARE.
23+
"""
24+
`adafruit_led_animation.animation.rainbowcomet`
25+
================================================================================
26+
27+
TODO
28+
29+
* Author(s): Roy Hooper, Kattni Rembor
30+
31+
"""
32+
33+
import random
34+
35+
from adafruit_led_animation.animation.rainbow import Rainbow
36+
37+
38+
class RainbowSparkle(Rainbow):
39+
40+
def __init__(self, pixel_object, speed, period=5, num_sparkles=None, step=1, name=None,
41+
bg_brightness=0.2):
42+
self._num_sparkles = num_sparkles
43+
if num_sparkles is None:
44+
self._num_sparkles = max(1, int(len(pixel_object) / 20))
45+
self._sparkle_duration = 2
46+
self._bg_brightness = bg_brightness
47+
self._bright_colors = None
48+
super().__init__(pixel_object=pixel_object, speed=speed, period=period, step=step, name=name,
49+
precompute_rainbow=True)
50+
51+
def generate_rainbow(self, step=1):
52+
super().generate_rainbow()
53+
self._bright_colors = self.colors[:]
54+
for i, color in enumerate(self.colors):
55+
if isinstance(self.colors[i], int):
56+
self.colors[i] = (
57+
int(self._bg_brightness * ((color & 0xff0000) >> 16)),
58+
int(self._bg_brightness * ((color & 0xff00) >> 8)),
59+
int(self._bg_brightness * (color & 0xff))
60+
)
61+
else:
62+
self.colors[i] = (
63+
int(self._bg_brightness * color[0]),
64+
int(self._bg_brightness * color[1]),
65+
int(self._bg_brightness * color[2])
66+
)
67+
68+
def show(self):
69+
pixels = [
70+
random.randint(0, len(self.pixel_object)-1)
71+
for n in range(self._num_sparkles)
72+
]
73+
for pixel in pixels:
74+
bc = (self._wheel_index + pixel) % len(self._bright_colors)
75+
self.pixel_object[pixel] = self._bright_colors[bc]
76+
super().show()

0 commit comments

Comments
 (0)