def canvas(self): canvas = Canvas() for i, state in sorted(self.states): colors = state.colors coords = self.coords o = orientation.reverse_orientation( self.orientations.get(i, O.RightSideUp)) colors = orientation.reorient(colors, o) if not coords: continue if i >= len(coords): continue (user_x, user_y), (width, height) = coords[i] rows = [] pos = 0 for j in range(height): nxt = [] for i in range(width): nxt.append(colors[pos]) pos += 1 rows.append(nxt) def get_color(x, y): color = rows[y][x] return Color(color.hue, color.saturation, color.brightness, color.kelvin) canvas.set_all_points_for_tile(user_x, user_y, width, height, get_color) return canvas
async def tile_dice(target, serials, afr, **kwargs): canvas = Canvas() def default_color_func(i, j): if j == -3: return Color(0, 1, 0.4, 3500) return Color(0, 0, 0, 3500) canvas.set_default_color_func(default_color_func) numbers = ["1", "2", "3", "4", "5"] characters = [dice[n] for n in numbers] color = Color(100, 1, 1, 3500) put_characters_on_canvas(canvas, characters, coords_for_horizontal_line, color) orientations = {} async for pkt, _, _ in target.script(TileMessages.GetDeviceChain()).run_with( serials, afr, **kwargs ): if pkt | TileMessages.StateDeviceChain: orientations[pkt.serial] = orientations_from(pkt) made, _ = make_rgb_and_color_pixels(canvas, 5) msgs = [] for serial in serials: os = orientations.get(serial) for msg in canvas_to_msgs( canvas, coords_for_horizontal_line, duration=1, acks=True, orientations=os ): msg.target = serial msgs.append(msg) await target.script(msgs).run_with_all(None, afr, **kwargs) return made
def canvas(self): canvas = Canvas() for i, colors in sorted(self.colors): coords = self.coords if not coords: continue if i >= len(coords): continue (user_x, user_y), (width, height) = coords[i] rows = [] pos = 0 for j in range(height): nxt = [] for i in range(width): nxt.append(colors[pos]) pos += 1 rows.append(nxt) def get_color(x, y): color = rows[y][x] return Color(color.hue, color.saturation, color.brightness, color.kelvin) canvas.set_all_points_for_tile(user_x, user_y, width, height, get_color) return canvas
async def start(self, serial, info, target, afr): errors = [] plans = ["chain"] if info.get("initial") is None: info["initial"] = {"colors": [], "power": 65535} plans.append("colors") plans.append("power") plans = make_plans(*plans) gatherer = Gatherer(target) got = await gatherer.gather_all(plans, serial, afr, error_catcher=errors) if errors: return errors, info chain = got[serial][1]["chain"] power = got[serial][1].get("power") colors = got[serial][1].get("colors") if power is not None: info["initial"]["power"] = power["level"] if colors is not None: info["initial"]["colors"] = colors pixel_coords = user_coords_to_pixel_coords(chain["coords_and_sizes"]) info["coords"] = [top_left for top_left, _ in pixel_coords] info["reorient"] = chain["reorient"] if info.get("pixels") is None: canvas = Canvas() def dcf(i, j): return Color(0, 0, 0, 3500) canvas.default_color_func = dcf length = len(info["coords"]) self.style_maker.set_canvas(canvas, length) info["pixels"], info["color_pixels"] = make_rgb_and_color_pixels( canvas, length) msgs = [DeviceMessages.SetPower(level=65535)] msgs.extend( canvas_to_msgs( canvas, coords_for_horizontal_line, duration=1, acks=True, reorient=info["reorient"], )) await target.script(msgs).run_with_all(serial, afr, error_catcher=errors) return errors, info
def make_canvas(self, state, coords): canvas = Canvas() characters = self.characters(state) put_characters_on_canvas(canvas, characters, state.coords_for(coords, characters), self.options.text_color.color) return canvas
def canvas(self): # fmt: off points = [ (0, 12, 0), None, None, None, None, (5, 12, 300), # noqa None, None, None, None, (0, 7, 200), None, None, None, None, (5, 7, 10), # noqa None, None, None, None, (2, 4, 90), None, None, None, (6, 4, 30), None, None, None, None, (11, 4, 45), # noqa None, None, (0, 1, 30), None, None, None, None, None, None, None, None, None, None, (11, 1, 89) # noqa ] # fmt: on canvas = Canvas() for point in points: if point is not None: i, j, h = point canvas[(i, j)] = ThemeColor(h, 1, 1, 3500) return canvas
def __init__(self, coords, options): self.options = options self.coords = coords self.left = coords[0][0][0] self.right = coords[0][0][0] self.top = coords[0][0][1] self.bottom = coords[0][0][1] for (left, top), (width, height) in coords: self.left = min(left, self.left) self.right = max(left + width, self.right) self.bottom = min(top - height, self.bottom) self.top = max(top, self.top) self.lines = {} for (left, top), (width, height) in self.coords: for i in range(width): column = left + i if column not in self.lines: self.lines[column] = Line(column, self) self.canvas = Canvas()
def make_canvas(self, state, coords): canvas = Canvas() characters = self.characters(state) coords = state.coords_for(coords, characters, getattr(self.options, "large_font", False)) put_characters_on_canvas(canvas, characters, coords, self.options.text_color.color) return canvas
def make_canvas(self, state, coords): canvas = Canvas() line_length = (8 * 5) * (state.second / 60) (user_x, user_y), (width, height) = coords[0] if not self.options.full_height_progress: user_y = user_y - height + 1 height = 1 def get_color(x, y): if x < line_length: return self.options.progress_bar_color.color canvas.set_all_points_for_tile(user_x, user_y, width * 5, height, get_color) time_characters = [alphabet_8[ch] for ch in list(state.time_string)] put_characters_on_canvas(canvas, time_characters, coords, self.options.number_color.color) return canvas
def make_canvas(self, state, coords): canvas = Canvas() filled, _, wait = state color = self.color if wait > 1: color = Color(0, 0, 0, 3500) for point in filled: canvas[point] = color return canvas
def __init__(self, coords, make_new_color): self.coords = coords self.canvas = Canvas() self.last_random = time.time() self.last_iteration = None self.make_new_color = make_new_color self.left = coords[0][0][0] self.right = coords[0][0][0] self.top = coords[0][0][1] self.bottom = coords[0][0][1] for (left, top), (width, height) in coords: self.left = min(left, self.left) self.right = max(left + width, self.right) self.bottom = min(top - height, self.bottom) self.top = max(top, self.top) self.width = self.right - self.left self.height = self.top - self.bottom self.place_random(4)
def make_canvas(self, state, coords): chars = state["chars"] if state["chars"] == -1: self.every = 0.5 chars = [full_character] * 5 if state["chars"] == -2: self.duration = 0.5 self.every = 1.5 chars = [random.choice(list(dice.values()))] * 5 canvas = Canvas() put_characters_on_canvas(canvas, chars, coords, self.options.dice_color.color) return canvas
def make_canvas(self, state, coords): """ This is called for each tile set every time we want to refresh the state photons handles turning the points on the canvas into light on the tiles """ canvas = Canvas() color = state.color if state.wait > 1: color = Color(0, 0, 0, 3500) for point in state.filled: canvas[point] = color return canvas
def make_canvas(self): canvas = Canvas() for (left, top), (width, height) in self.coords: for i in range(left, left + width): line = self.lines[i] for j in range(top - height, top): got = line[j] if self.options.blinking_pixels: if not getattr(got, "tip", False) and random.randrange(0, 100) < 5: got = Color(got.hue, got.saturation, got.brightness, got.kelvin) got.brightness = 0 canvas[(i, j)] = got return canvas
def apply_theme(self, theme, canvas=None, return_canvas=False): """ If a canvas is not supplied then we create a new canvas with a color func that generates a vertical stripe """ if canvas is None: canvas = Canvas() # We add points for our tiles so that canvas.width and canvas.height still work # They won't have any effect on the tiles themselves because the color_func overrides points grey = ThemeColor(0, 0, 0.3, 3500) for (left_x, top_y), (tile_width, tile_height) in self.coords_and_sizes: canvas[(left_x, top_y)] = grey canvas[(left_x + tile_width, top_y - tile_height)] = grey canvas.set_color_func(self.color_func_generator(theme, canvas)) colors = TileColors() self.add_tiles_from_canvas(colors, canvas) if return_canvas: return colors.tiles, canvas return colors.tiles
def make_canvas(self, state, coords): canvas = Canvas() put_characters_on_canvas(canvas, state.characters, state.coords_for(coords)) return canvas
def make_canvas(self, state, coords): canvas = Canvas() for point, color in state.twinkles.items(): canvas[point] = color return canvas
def apply_theme(self, theme, return_canvas=False, canvas=None): """ If a canvas is not supplied then we create a new canvas with random points around where each tile is. We then shuffle those points and blur them a little. We then fill in the gaps between the points. Then we blur the filled in points and create the 64 hsbk values for each tile. We return the list of ``[<64 hsbks>, <64 hsbks>, ...]``. If ``return_canvas`` is True then we return a tuple of ``(tiles, canvas)`` """ if canvas is None: canvas = Canvas() theme = theme.shuffled() theme.ensure_color() for (left_x, top_y), (w, h) in self.coords_and_sizes: canvas.add_points_for_tile(left_x, top_y, w, h, theme) canvas.shuffle_points() canvas.blur_by_distance() colors = TileColors() tile_canvas = Canvas() for (left_x, top_y), (tile_width, tile_height) in self.coords_and_sizes: if self.just_points: colors.add_tile( canvas.points_for_tile(left_x, top_y, tile_width, tile_height)) else: tile_canvas.fill_in_points(canvas, left_x, top_y, tile_width, tile_height) if not self.just_points: if self.post_blur: tile_canvas.blur() self.add_tiles_from_canvas(colors, tile_canvas) if return_canvas: return colors.tiles, canvas return colors.tiles
for _ in range(5000): i, j = (random.randrange(-100, 100), random.randrange(-100, 100)) ni, nj = shuffle_point(i, j) assert abs(ni - i) < 4 assert abs(nj - j) < 4 if (i, j) == (ni, nj): equald += 1 assert equald < 1000 describe "Canvas": it "has points": canvas = Canvas() assert canvas.points == {} it "can iterate the points": canvas = Canvas() canvas[(1, 1)] = ThemeColor(0, 1, 1, 2400) canvas[(2, 1)] = ThemeColor(100, 1, 1, 2400) canvas[(3, 4)] = ThemeColor(120, 1, 1, 2400) got = list(canvas) expected = list(canvas.points.items()) assert sorted(got) == sorted(expected) assert len(got) == 3 it "can get a point": canvas = Canvas()
class State: def __init__(self, coords, make_new_color): self.coords = coords self.canvas = Canvas() self.last_random = time.time() self.last_iteration = None self.make_new_color = make_new_color self.left = coords[0][0][0] self.right = coords[0][0][0] self.top = coords[0][0][1] self.bottom = coords[0][0][1] for (left, top), (width, height) in coords: self.left = min(left, self.left) self.right = max(left + width, self.right) self.bottom = min(top - height, self.bottom) self.top = max(top, self.top) self.width = self.right - self.left self.height = self.top - self.bottom self.place_random(4) def place_random(self, amount): for _ in range(amount): ch = random.choice(characters) left, top = self.random_coord() color = Color(random.randrange(0, 360), 1, 1, 3500) self.canvas.set_all_points_for_tile(left, top, ch.width, ch.height, ch.get_color_func(color)) def iterate(self, delay): if self.last_iteration is not None and time.time( ) - self.last_iteration < delay: return self now = time.time() self.last_iteration = now if now - self.last_random > 1: self.place_random(random.randrange(0, 3)) self.last_random = now removal = [] addition = [] points = [c for c, _ in self.canvas] dead_points = [] for i, j in points: dead_points.extend( [p for p in self.canvas.surrounding_points(i, j)]) points.extend(dead_points) for point in set(points): alive = point in self.canvas alive_neighbours = len(self.canvas.surrounding_colors(*point)) if alive: if alive_neighbours < 2 or alive_neighbours > 3: removal.append(point) else: if alive_neighbours == 3: addition.append(point) for point in removal: del self.canvas[point] for point in addition: color = self.make_new_color(self.canvas.surrounding_colors(*point)) self.canvas[point] = color for (left, top), _ in list(self.canvas): too_far_left = left < self.left - 20 too_far_right = left > self.right + 20 too_far_up = top > self.top + 20 too_far_down = top < self.bottom - 20 if too_far_left or too_far_right or too_far_up or too_far_down: del self.canvas[(left, top)] return self def random_coord(self): left = random.randrange(self.left, self.right) top = random.randrange(self.bottom, self.top) return left, top