def apply_to_range(self, color, next_color, length): """ Recursively apply two colours to our strip such that we blend between the two colours. """ if length == 1: self.add_hsbk(color) elif length == 2: second_color = ThemeColor.average( [next_color.limit_distance_to(color), color]) self.add_hsbk(color) self.add_hsbk(second_color) else: average = ThemeColor.average([next_color, color]) self.apply_to_range(color, average, length // 2) self.apply_to_range(average, next_color, length - length // 2)
def blur_by_distance(self): """ Similar to blur but will find the 8 closest points as opposed to the 8 surrounding points. """ new_points = {} for (i, j), original in self: distances = self.closest_points(i, j, 8) weighted = list(color_weighting(distances)) new_points[(i, j)] = ThemeColor.average(weighted) self.points = new_points
def blur(self): """ For each point, find the average colour of that point plus all surrounding points. """ new_points = {} for (i, j), original in self: colors = [original for _ in range(2)] for color in self.surrounding_colors(i, j): colors.append(color) new_points[(i, j)] = ThemeColor.average(colors) self.points = new_points
def fill_in_points(self, canvas, left_x, top_y, tile_width, tile_height): """ Fill in the gaps on this canvas by blurring the points on the provided canvas around where our tile is. We blur by finding the 4 closest points for each point on our tile and averaging them. """ for j in range(top_y, top_y - tile_height, -1): for i in range(left_x, left_x + tile_width): distances = canvas.closest_points(i, j, 4) weighted = list(color_weighting(distances)) self[(i, j)] = ThemeColor.average(weighted)
, ((6, 6), ThemeColor(100, 1, 1, 3500)) ] ) describe "applying a range": it "adds one color if length is 1": color = ThemeColor(0, 1, 1, 3500) color2 = ThemeColor(100, 1, 1, 3500) colors = ZoneColors() colors.apply_to_range(color, color2, 1) self.assertEqual(colors._colors, [color]) it "adds two colors if length is 2 where second color is averaged": color = ThemeColor(0, 1, 1, 3500) color2 = ThemeColor(100, 1, 1, 3500) second_color = ThemeColor.average([color2.limit_distance_to(color), color]) colors = ZoneColors() colors.apply_to_range(color, color2, 2) self.assertEqual(colors._colors, [color, second_color]) it "applies a gradient for length greater than two": color = ThemeColor(0, 1, 1, 3500) color2 = ThemeColor(100, 1, 1, 3500) colors = ZoneColors() colors.apply_to_range(color, color2, 8) hues = [float("{:.3f}".format(c.hue)) for c in colors._colors] self.assertEqual(hues, [0.0, 12.5, 25.0, 37.5, 50.0, 62.5, 75.0, 87.5]) describe "applying a theme":
def make_new_color(self, surrounding): if self.new_color_style == "random": return Color(random.randrange(0, 360), 1, 1, 3500) else: return Color.average(surrounding)
describe "__repr__": it "returns the hsbk in a nice fashion": color = ThemeColor(320, 0.5, 0.6, 5600) self.assertEqual(repr(color), "<Color (320, 0.5, 0.6, 5600)>") describe "averaging colors": def assertColorAlmostEqual(self, color, want): msg = "Expect {} to almost equal {}".format(color, want) self.assertAlmostEqual(color.hue, want.hue, 3, msg=msg) self.assertAlmostEqual(color.saturation, want.saturation, 3, msg=msg) self.assertAlmostEqual(color.brightness, want.brightness, 3, msg=msg) self.assertAlmostEqual(color.kelvin, want.kelvin, 3, msg=msg) it "returns white if there are no colors": color = ThemeColor.average([]) self.assertEqual(color, ThemeColor(0, 0, 1, 3500)) it "averages saturation, brightness and kelvin": colors = [ ThemeColor(0, 0.1, 0.2, 3500) , ThemeColor(0, 0.2, 0.3, 4500) , ThemeColor(0, 0.3, 0.4, 5500) ] color = ThemeColor.average(colors) self.assertColorAlmostEqual(color, ThemeColor(0, 0.2, 0.3, 4500)) it "it sets kelvin to 3500 if 0": colors = [ ThemeColor(0, 0.1, 0.2, 3500)