def _color_wheel_generator(self): period = int(self._period * NANOS_PER_SECOND) num_pixels = len(self.pixel_object) last_update = monotonic_ns() cycle_position = 0 last_pos = 0 while True: cycle_completed = False now = monotonic_ns() time_since_last_draw = now - last_update last_update = now pos = cycle_position = (cycle_position + time_since_last_draw) % period if pos < last_pos: cycle_completed = True last_pos = pos wheel_index = int((pos / period) * len(self.colors)) if self.colors: self._draw_precomputed(num_pixels, wheel_index) else: wheel_index = int((pos / period) * 256) self.pixel_object[:] = [ colorwheel((i + wheel_index) % 255) for i in range(num_pixels) ] self._wheel_index = wheel_index if cycle_completed: self.cycle_complete = True yield
def animate(self, show=True): """ Call animate() from your code's main loop. It will draw the animation draw() at intervals configured by the speed property (set from init). :param bool show: Whether to automatically call show on the pixel object when an animation fires. Default True. :return: True if the animation draw cycle was triggered, otherwise False. """ if self._paused: return False now = monotonic_ns() if now < self._next_update: return False # Draw related animations together for anim in self._peers: anim.draw_count += 1 anim.draw() anim.after_draw() anim.draw_count += 1 if show: for anim in self._peers: anim.show() # Note that the main animation cycle_complete flag is used, not the peer flag. for anim in self._peers: if anim.cycle_complete: anim.cycle_complete = False anim.on_cycle_complete() self._next_update = now + self._speed_ns return True
def resume(self): """ Resumes the animation. """ self._next_update = monotonic_ns() + self._time_left_at_pause self._time_left_at_pause = 0 self._paused = False
def __init__(self, pixel_object, speed, color, peers=None, paused=False, name=None): self.pixel_object = pixel_object self.pixel_object.auto_write = False self._peers = [self] + peers if peers is not None else [self] self._speed_ns = 0 self._color = None self._paused = paused self._next_update = monotonic_ns() self._time_left_at_pause = 0 self._also_notify = [] self.speed = speed # sets _speed_ns self.color = color # Triggers _set_color self.name = name self.cycle_complete = False self.notify_cycles = 1 """Number of cycles to trigger additional cycle_done notifications after""" self.draw_count = 0 """Number of animation frames drawn.""" self.cycle_count = 0 """Number of animation cycles completed."""
def freeze(self): """ Stops the animation until resumed. """ self._paused = True self._time_left_at_pause = max(0, monotonic_ns() - self._next_update)