grid_rain.py
1 # SPDX-FileCopyrightText: 2020 Kattni Rembor for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 5 """ 6 `adafruit_led_animation.animation.grid_rain` 7 ================================================================================ 8 9 Rain animations for CircuitPython helper library for LED animations. 10 11 * Author(s): Kattni Rembor 12 13 Implementation Notes 14 -------------------- 15 16 **Hardware:** 17 18 * `Adafruit NeoPixels <https://www.adafruit.com/category/168>`_ 19 * `Adafruit DotStars <https://www.adafruit.com/category/885>`_ 20 21 **Software and Dependencies:** 22 23 * Adafruit CircuitPython firmware for the supported boards: 24 https://circuitpython.org/downloads 25 26 """ 27 28 import random 29 from adafruit_led_animation.animation import Animation 30 31 __version__ = "0.0.0-auto.0" 32 __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_LED_Animation.git" 33 34 from adafruit_led_animation.color import BLACK, colorwheel, calculate_intensity, GREEN 35 36 37 class Rain(Animation): 38 """ 39 Droplets of rain. 40 41 :param grid_object: The initialised PixelGrid object. 42 :param float speed: Animation speed in seconds, e.g. ``0.1``. 43 :param color: Animation color in ``(r, g, b)`` tuple, or ``0x000000`` hex format. 44 :param count: Number of sparkles to generate per animation cycle. 45 :param length: Number of pixels per raindrop (Default 3) 46 :param background: Background color (Default BLACK). 47 """ 48 49 # pylint: disable=too-many-arguments 50 def __init__( 51 self, grid_object, speed, color, count=1, length=3, background=BLACK, name=None 52 ): 53 self._count = count 54 self._length = length 55 self._background = background 56 self._raindrops = [] 57 super().__init__(grid_object, speed, color, name=name) 58 59 def draw(self): 60 61 # Move raindrops down 62 keep = [] 63 for raindrop in self._raindrops: 64 pixels = [] 65 if raindrop[1][0][0] >= 0: 66 self.pixel_object[raindrop[0], raindrop[1][0][0]] = self._background 67 for pixel in raindrop[1]: 68 pixel[0] += 1 69 if pixel[0] < self.pixel_object.height: 70 pixels.append(pixel) 71 if pixels: 72 keep.append([raindrop[0], pixels]) 73 self._raindrops = keep 74 75 # Add a raindrop 76 if len(self._raindrops) < self._count: 77 x = random.randint(0, self.pixel_object.width - 1) 78 self._raindrops.append([x, self._generate_droplet(x, self._length)]) 79 80 # Draw raindrops 81 for x, pixels in self._raindrops: 82 for y, color in pixels: 83 if y >= 0: 84 self.pixel_object[x, y] = color 85 86 def _generate_droplet(self, x, length): # pylint: disable=unused-argument 87 return [[n, self.color] for n in range(-length, 0)] 88 89 90 class RainbowRain(Rain): 91 """ 92 Rainbow Rain animation. 93 """ 94 95 def __init__( # pylint: disable=too-many-arguments 96 self, grid_object, speed, count=1, length=3, background=BLACK, name=None 97 ): 98 super().__init__(grid_object, speed, BLACK, count, length, background, name) 99 100 def _generate_droplet(self, x, length): 101 color = colorwheel(random.randint(0, 255)) 102 return [ 103 [n, calculate_intensity(color, 1.0 - -((n + 1) / (length + 1)))] 104 for n in range(-length, 0) 105 ] 106 107 108 class MatrixRain(Rain): 109 """ 110 The Matrix style animation. 111 """ 112 113 def __init__( # pylint: disable=too-many-arguments 114 self, 115 grid_object, 116 speed, 117 color=GREEN, 118 count=1, 119 length=6, 120 background=(0, 32, 0), 121 name=None, 122 ): 123 super().__init__(grid_object, speed, color, count, length, background, name) 124 125 def _generate_droplet(self, x, length): 126 return [ 127 [n, calculate_intensity(self.color, random.randint(10, 100) * 1.0)] 128 for n in range(-length, 0) 129 ]