def step(self, amt=1): self._ledcolors = [(0, 0, 0) for i in range(self._size)] self.layout.all_off() for i in range(0, 3): self._currentpos[i] = self._start + self._steps[i] color = self.palette(i) # average the colors together so they blend self._ledcolors[self._currentpos[i]] = list( map(lambda x, y: (x + y) // 2, color, self._ledcolors[self._currentpos[i]])) for j in range(1, self._tail): if self._currentpos[i] - j >= 0: self._ledcolors[self._currentpos[i] - j] = list( map(lambda x, y: (x + y) // 2, self._ledcolors[self._currentpos[i] - j], color_scale(color, 255 - (self._fadeAmt * j)))) if self._currentpos[i] + j < self._size: self._ledcolors[self._currentpos[i] + j] = list( map(lambda x, y: (x + y) // 2, self._ledcolors[self._currentpos[i] + j], color_scale(color, 255 - (self._fadeAmt * j)))) if self._start + self._steps[i] >= self._end: self._direction[i] = -1 elif self._start + self._steps[i] <= 0: self._direction[i] = 1 # advance each searchlight at a slightly different speed self._steps[i] += self._direction[i] * amt * int( random.random() > (i * 0.05)) for i, thiscolor in enumerate(self._ledcolors): self.layout.set(i, thiscolor)
def render_particles(self): """ Render visible particles at each strip position, by modifying the strip's color list. """ for strip_pos in range(self._start, self._end + 1): blended = COLORS.black # Render visible emitters if self.has_e_colors: for (e_pos, e_dir, e_vel, e_range, e_color, e_pal) in self.emitters: if e_color is not None: vis = self.visibility(strip_pos, e_pos) if vis > 0: blended = color_blend( blended, color_scale(e_color, int(vis * 255))) # Render visible particles for vel, pos, stl, color, bright in self.particles: vis = self.visibility(strip_pos, pos) if vis > 0 and bright > 0: blended = color_blend( blended, color_scale(color, int(vis * bright))) # Add background if showing if (blended == COLORS.black): blended = self.bgcolor self.color_list[strip_pos] = blended
def test_color_scale(self): self.assertEqual(COLORS.Green, (0, 255, 0)) self.assertEqual(arithmetic.color_scale(COLORS.Green, 256), (0, 255, 0)) self.assertEqual(arithmetic.color_scale(COLORS.Green, 255), (0, 254, 0)) self.assertEqual(arithmetic.color_scale(COLORS.Green, 128), (0, 127, 0)) self.assertEqual(arithmetic.color_scale(COLORS.Green, 0), (0, 0, 0))
def pick_led(self, speed): idx = random.randrange(0, self.layout.numLEDs) p_dir, p_color, p_level = self.pixels[idx] if random.randrange(0, 100) < self.density: if p_dir == 0: # 0 is off p_level += speed p_dir = 1 # 1 is growing p_color = random.choice(self.colors) self.layout._set_base(idx, color_scale(p_color, p_level)) self.pixels[idx] = p_dir, p_color, p_level
def step(self, amt=1): self.layout.all_off() t = time.localtime() for h in self.hands: segs = h['segments'] point = (360 / segs) * (getattr(t, h['key']) % segs) self.layout.set(h['ring'], point, h['color']) if h['tail'] > 0: for i in range(h['tail']): scaled = color_scale(h['color'], 255 - ((256 // h['tail']) * i)) self.layout.set(h['ring'], point + i, scaled) self.layout.set(h['ring'], point - i, scaled)
def step(self, amt=1): self.layout.all_off() self.pick_led(self.speed) for i, val in enumerate(self.pixels): p_dir, p_color, p_level = val if p_dir == 1: p_level += self.speed if p_level > 255: p_level = 255 p_dir = 2 # start dimming self.layout._set_base(i, color_scale(p_color, p_level)) elif p_dir == 2: p_level -= self.speed if p_level < 0: p_level = 0 p_dir = 0 # turn off self.layout._set_base(i, color_scale(p_color, p_level)) self.pixels[i] = (p_dir, p_color, p_level) self._step += amt
def step(self, amt=1): self.layout.all_off() if self.pulse_speed == 0 and random.randrange(0, 100) <= self.chance: self.add_pulse() if self.pulse_speed > 0: self.layout.set(self.pulse_position, self.pulse_color) for i in range(self._tail): c = color_scale(self.pulse_color, 255 - (self._fadeAmt * i)) self.layout.set(self.pulse_position - i, c) self.layout.set(self.pulse_position + i, c) if self.pulse_position > self._size + self._tail: self.pulse_speed = 0 else: self.pulse_position += self.pulse_speed
def step(self, amt=1): self.layout.all_off() self._last = self._start + self._step color = self._get_color() self.layout.set(self._last, color) for i in range(self._tail): c2 = color_scale(color, 255 - (self._fadeAmt * i)) self.layout.set(self._last - i, c2) self.layout.set(self._last + i, c2) if self._start + self._step >= self._end: self._direction = -self._direction elif self._step <= 0: self._direction = -self._direction self._step += self._direction * amt
def _drawDrop(self, x, y, z, color): for i in range(self._tail): if y - i >= 0 and y - i < self.y: level = 255 - ((255 // self._tail) * i) self.layout.set(x, y - i, z, color_scale(color, level))
def step(self, amt=1): c_index, l_index = divmod(self._step, self._level_count) color = self.palette(c_index) color = color_scale(color, self._levels[l_index]) self.layout.fill(color, self._start, self._end) self._step += amt
def step(self, amt=1): self._ledcolors = [(0, 0, 0) for i in range(self._size)] self.layout.all_off() for i in range(0, 3): self._currentpos[i] = self._start + self._steps[i] color = self.palette(i) # average the colors together so they blend self._ledcolors[self._currentpos[i]] = list(map(lambda x, y: (x + y) // 2, color, self._ledcolors[self._currentpos[i]])) for j in range(1, self._tail): if self._currentpos[i] - j >= 0: self._ledcolors[self._currentpos[i] - j] = list(map(lambda x, y: (x + y) // 2, self._ledcolors[self._currentpos[i] - j], color_scale(color, 255 - (self._fadeAmt * j)))) if self._currentpos[i] + j < self._size: self._ledcolors[self._currentpos[i] + j] = list(map(lambda x, y: (x + y) // 2, self._ledcolors[self._currentpos[i] + j], color_scale(color, 255 - (self._fadeAmt * j)))) if self._start + self._steps[i] >= self._end: self._direction[i] = -1 elif self._start + self._steps[i] <= 0: self._direction[i] = 1 # advance each searchlight at a slightly different speed self._steps[i] += self._direction[i] * amt * int(random.random() > (i * 0.05)) for i, thiscolor in enumerate(self._ledcolors): self.layout.set(i, thiscolor)
def __init__(self, layout, imagePath=None, offset=(0, 0), bgcolor=COLORS.Off, brightness=255, cycles=1, seconds=None, random=False, use_file_fps=True, use_gamma=True, scale_to=None, **kwds): """ Animation class for displaying image animations for GIF files or a set of bitmaps layout: layout.Matrix instance imagePath: Path to either a single animated GIF image or folder of GIF files offset: X, Y coordinates of the top-left corner of the image bgcolor: RGB tuple color to replace any transparent pixels with. Avoids transparent showing as black brightness: Brightness value (0-255) to scale the image by. Otherwise uses master brightness at the time of creation use_gamma: If true, use the driver's gamma on the raw image data. TODO: why do we do this? scale_to: Which dimensions to scale the image to? None: Don't scale 'x': Scale to use full width 'y': Scale to use full height 'xy': Scale both width and height 'fit: Use best fit from 'x' or 'y' """ super().__init__(layout, **kwds) self.cycles = cycles self.cycle_count = 0 self.seconds = seconds self.last_start = 0 self.random = random self.use_file_fps = use_file_fps self._bright = brightness self._bgcolor = color_scale(bgcolor, self._bright) self._offset = offset self._image_buffers = [None, None] self._cur_img_buf = 1 # start here because loadNext swaps it self.imagePath = imagePath or str(DEFAULT_ANIM) self.folder_mode = os.path.isdir(self.imagePath) self.gif_files = [] self.gif_indices = [] self.folder_index = -1 self.load_thread = None self.use_gamma = use_gamma self.scale_to = scale_to and SCALE_TO[scale_to] if self.folder_mode: self.gif_files = glob.glob(self.imagePath + "/*.gif") self.gif_indices = list(range(len(self.gif_files))) self.loadNextGIF() # first load is manual self.swapbuf() self.load_thread = None else: self.loadGIFFile(self.imagePath) self.swapbuf()
def _drawTail(self, angle, ring, color): for i in range(self._tail): if ring - i >= 0 and ring - i <= self.lastRing: level = 255 - ((255 // self._tail) * i) self.layout.set(ring - i, angle, color_scale(color, level))
def __init__( self, layout, imagePath=None, offset=(0, 0), bgcolor=COLORS.Off, brightness=255, cycles=1, seconds=None, random=False, use_file_fps=True, use_gamma=True, scale_to=None, **kwds): """ Animation class for displaying image animations for GIF files or a set of bitmaps layout: layout.Matrix instance imagePath: Path to either a single animated GIF image or folder of GIF files offset: X, Y coordinates of the top-left corner of the image bgcolor: RGB tuple color to replace any transparent pixels with. Avoids transparent showing as black brightness: Brightness value (0-255) to scale the image by. Otherwise uses master brightness at the time of creation use_gamma: If true, use the driver's gamma on the raw image data. TODO: why do we do this? scale_to: Which dimensions to scale the image to? None: Don't scale 'x': Scale to use full width 'y': Scale to use full height 'xy': Scale both width and height 'fit: Use best fit from 'x' or 'y' """ super().__init__(layout, **kwds) self.cycles = cycles self.cycle_count = 0 self.seconds = seconds self.last_start = 0 self.random = random self.use_file_fps = use_file_fps self._bright = brightness self._bgcolor = color_scale(bgcolor, self._bright) self._offset = offset self._image_buffers = [None, None] self._cur_img_buf = 1 # start here because loadNext swaps it self.imagePath = imagePath or str(DEFAULT_ANIM) self.folder_mode = os.path.isdir(self.imagePath) self.gif_files = [] self.gif_indices = [] self.folder_index = -1 self.load_thread = None self.use_gamma = use_gamma self.scale_to = scale_to and SCALE_TO[scale_to] if self.folder_mode: self.gif_files = glob.glob(self.imagePath + "/*.gif") self.gif_indices = list(range(len(self.gif_files))) self.loadNextGIF() # first load is manual self.swapbuf() self.load_thread = None else: self.loadGIFFile(self.imagePath) self.swapbuf()