Skip to content

Commit 4c44276

Browse files
committed
split up into more files to make it possible to use some animations on M0
1 parent 98da8ab commit 4c44276

File tree

9 files changed

+628
-605
lines changed

9 files changed

+628
-605
lines changed

adafruit_led_animation/animation.py

Lines changed: 3 additions & 252 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,9 @@
4444
4545
"""
4646

47-
import random
4847
from math import ceil
49-
import adafruit_led_animation.helper
5048
from . import NANOS_PER_SECOND, monotonic_ns
51-
from .color import BLACK, RAINBOW, colorwheel
49+
from .color import BLACK, RAINBOW
5250

5351
__version__ = "0.0.0-auto.0"
5452
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation.git"
@@ -372,103 +370,6 @@ def reset(self):
372370
self.reverse = self._initial_reverse
373371

374372

375-
class RainbowComet(Comet):
376-
"""
377-
A rainbow comet animation.
378-
379-
:param pixel_object: The initialised LED object.
380-
:param float speed: Animation speed in seconds, e.g. ``0.1``.
381-
:param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format.
382-
:param int tail_length: The length of the comet. Defaults to 10. Cannot exceed the number of
383-
pixels present in the pixel object, e.g. if the strip is 30 pixels
384-
long, the ``tail_length`` cannot exceed 30 pixels.
385-
:param bool reverse: Animates the comet in the reverse order. Defaults to ``False``.
386-
:param bool bounce: Comet will bounce back and forth. Defaults to ``True``.
387-
:param int colorwheel_offset: Offset from start of colorwheel (0-255).
388-
"""
389-
390-
# pylint: disable=too-many-arguments
391-
def __init__(
392-
self,
393-
pixel_object,
394-
speed,
395-
tail_length=10,
396-
reverse=False,
397-
bounce=False,
398-
colorwheel_offset=0,
399-
name=None,
400-
):
401-
self._colorwheel_is_tuple = isinstance(colorwheel(0), tuple)
402-
self._colorwheel_offset = colorwheel_offset
403-
404-
super().__init__(pixel_object, speed, 0, tail_length, reverse, bounce, name)
405-
406-
def _calc_brightness(self, n, color):
407-
brightness = (n * self._color_step) + self._color_offset
408-
if not self._colorwheel_is_tuple:
409-
color = (color & 0xFF, ((color & 0xFF00) >> 8), (color >> 16))
410-
return [int(i * brightness) for i in color]
411-
412-
def __recompute_color(self, color):
413-
factor = int(256 / self._tail_length)
414-
self._comet_colors = [BLACK] + [
415-
self._calc_brightness(
416-
n,
417-
colorwheel(
418-
int((n * factor) + self._color_offset + self._colorwheel_offset)
419-
% 256
420-
),
421-
)
422-
for n in range(self._tail_length - 1)
423-
]
424-
self._reverse_comet_colors = list(reversed(self._comet_colors))
425-
self._computed_color = color
426-
427-
428-
class Sparkle(Animation):
429-
"""
430-
Sparkle animation of a single color.
431-
432-
:param pixel_object: The initialised LED object.
433-
:param float speed: Animation speed in seconds, e.g. ``0.1``.
434-
:param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format.
435-
:param num_sparkles: Number of sparkles to generate per animation cycle.
436-
"""
437-
438-
# pylint: disable=too-many-arguments
439-
def __init__(self, pixel_object, speed, color, num_sparkles=1, name=None):
440-
if len(pixel_object) < 2:
441-
raise ValueError("Sparkle needs at least 2 pixels")
442-
self._half_color = None
443-
self._dim_color = None
444-
self._num_sparkles = num_sparkles
445-
super().__init__(pixel_object, speed, color, name=name)
446-
447-
def _recompute_color(self, color):
448-
half_color = tuple(color[rgb] // 4 for rgb in range(len(color)))
449-
dim_color = tuple(color[rgb] // 10 for rgb in range(len(color)))
450-
for pixel in range(len(self.pixel_object)):
451-
if self.pixel_object[pixel] == self._half_color:
452-
self.pixel_object[pixel] = half_color
453-
elif self.pixel_object[pixel] == self._dim_color:
454-
self.pixel_object[pixel] = dim_color
455-
self._half_color = half_color
456-
self._dim_color = dim_color
457-
458-
def draw(self):
459-
pixels = [
460-
random.randint(0, (len(self.pixel_object) - 2))
461-
for n in range(self._num_sparkles)
462-
]
463-
for pixel in pixels:
464-
self.pixel_object[pixel] = self._color
465-
self.show()
466-
for pixel in pixels:
467-
self.pixel_object[pixel] = self._half_color
468-
self.pixel_object[pixel + 1] = self._dim_color
469-
self.show()
470-
471-
472373
class Pulse(Animation):
473374
"""
474375
Pulse all pixels a single color.
@@ -500,122 +401,9 @@ def reset(self):
500401
white = len(self.pixel_object[0]) > 3 and isinstance(
501402
self.pixel_object[0][-1], int
502403
)
503-
self._generator = adafruit_led_animation.helper.pulse_generator(
504-
self._period, self, white
505-
)
404+
from adafruit_led_animation.helper import pulse_generator # pylint: disable=import-outside-toplevel
506405

507-
508-
class Rainbow(Animation):
509-
"""
510-
The classic rainbow color wheel.
511-
512-
:param pixel_object: The initialised LED object.
513-
:param float speed: Animation refresh rate in seconds, e.g. ``0.1``.
514-
:param period: Period to cycle the rainbow over. Default 5.
515-
"""
516-
517-
# pylint: disable=too-many-arguments
518-
def __init__(self, pixel_object, speed, period=5, name=None):
519-
super().__init__(pixel_object, speed, BLACK, name=name)
520-
self._period = period
521-
self._generator = self._color_wheel_generator()
522-
523-
cycle_complete_supported = True
524-
525-
def _color_wheel_generator(self):
526-
period = int(self._period * NANOS_PER_SECOND)
527-
528-
last_update = monotonic_ns()
529-
cycle_position = 0
530-
last_pos = 0
531-
while True:
532-
cycle_completed = False
533-
now = monotonic_ns()
534-
time_since_last_draw = now - last_update
535-
last_update = now
536-
pos = cycle_position = (cycle_position + time_since_last_draw) % period
537-
if pos < last_pos:
538-
cycle_completed = True
539-
last_pos = pos
540-
wheel_index = int((pos / period) * 256)
541-
self.pixel_object[:] = [
542-
colorwheel((i + wheel_index) % 255)
543-
for i, _ in enumerate(self.pixel_object)
544-
]
545-
self.show()
546-
if cycle_completed:
547-
self.cycle_complete()
548-
yield
549-
550-
def draw(self):
551-
next(self._generator)
552-
553-
def reset(self):
554-
"""
555-
Resets the animation.
556-
"""
557-
self._generator = self._color_wheel_generator()
558-
559-
560-
class SparklePulse(Animation):
561-
"""
562-
Combination of the Spark and Pulse animations.
563-
564-
:param pixel_object: The initialised LED object.
565-
:param int speed: Animation refresh rate in seconds, e.g. ``0.1``.
566-
:param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format.
567-
:param period: Period to pulse the LEDs over. Default 5.
568-
:param max_intensity: The maximum intensity to pulse, between 0 and 1.0. Default 1.
569-
:param min_intensity: The minimum intensity to pulse, between 0 and 1.0. Default 0.
570-
"""
571-
572-
# pylint: disable=too-many-arguments
573-
def __init__(
574-
self, pixel_object, speed, color, period=5, max_intensity=1, min_intensity=0
575-
):
576-
if len(pixel_object) < 2:
577-
raise ValueError("Sparkle needs at least 2 pixels")
578-
self.max_intensity = max_intensity
579-
self.min_intensity = min_intensity
580-
self._period = period
581-
self._intensity_delta = max_intensity - min_intensity
582-
self._half_period = period / 2
583-
self._position_factor = 1 / self._half_period
584-
self._bpp = len(pixel_object[0])
585-
self._last_update = monotonic_ns()
586-
self._cycle_position = 0
587-
self._half_color = None
588-
self._dim_color = None
589-
super().__init__(pixel_object, speed, color)
590-
591-
def _recompute_color(self, color):
592-
half_color = tuple(color[rgb] // 4 for rgb in range(len(color)))
593-
dim_color = tuple(color[rgb] // 10 for rgb in range(len(color)))
594-
for pixel in range(len(self.pixel_object)):
595-
if self.pixel_object[pixel] == self._half_color:
596-
self.pixel_object[pixel] = half_color
597-
elif self.pixel_object[pixel] == self._dim_color:
598-
self.pixel_object[pixel] = dim_color
599-
self._half_color = half_color
600-
self._dim_color = dim_color
601-
602-
def draw(self):
603-
pixel = random.randint(0, (len(self.pixel_object) - 2))
604-
605-
now = monotonic_ns()
606-
time_since_last_draw = (now - self._last_update) / NANOS_PER_SECOND
607-
self._last_update = now
608-
pos = self._cycle_position = (
609-
self._cycle_position + time_since_last_draw
610-
) % self._period
611-
if pos > self._half_period:
612-
pos = self._period - pos
613-
intensity = self.min_intensity + (
614-
pos * self._intensity_delta * self._position_factor
615-
)
616-
color = [int(self.color[n] * intensity) for n in range(self._bpp)]
617-
self.pixel_object[pixel] = color
618-
self.show()
406+
self._generator = pulse_generator(self._period, self, white)
619407

620408

621409
class Chase(Animation):
@@ -713,40 +501,3 @@ def reset(self):
713501
Reset the animation.
714502
"""
715503
self._reset()
716-
717-
718-
class RainbowChase(Chase):
719-
"""
720-
Chase pixels in one direction, like a theater marquee but with rainbows!
721-
722-
:param pixel_object: The initialised LED object.
723-
:param float speed: Animation speed rate in seconds, e.g. ``0.1``.
724-
:param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format.
725-
:param size: Number of pixels to turn on in a row.
726-
:param spacing: Number of pixels to turn off in a row.
727-
:param reverse: Reverse direction of movement.
728-
:param wheel_step: How many colors to skip in `colorwheel` per bar (default 8)
729-
"""
730-
731-
# pylint: disable=too-many-arguments
732-
def __init__(
733-
self,
734-
pixel_object,
735-
speed,
736-
size=2,
737-
spacing=3,
738-
reverse=False,
739-
name=None,
740-
wheel_step=8,
741-
):
742-
self._num_colors = 256 // wheel_step
743-
self._colors = [colorwheel(n % 256) for n in range(0, 512, wheel_step)]
744-
self._color_idx = 0
745-
super().__init__(pixel_object, speed, 0, size, spacing, reverse, name)
746-
747-
def bar_color(self, n, pixel_no=0):
748-
return self._colors[self._color_idx - n]
749-
750-
def cycle_complete(self):
751-
self._color_idx = (self._color_idx + self._direction) % len(self._colors)
752-
super().cycle_complete()

0 commit comments

Comments
 (0)