8
|
1 import logging
|
|
2 from dataclasses import dataclass
|
4
|
3
|
8
|
4 from dataclasses_json import DataClassJsonMixin
|
|
5
|
|
6 log = logging.getLogger('colr')
|
|
7
|
|
8
|
|
9 def lerp(a, b, t):
|
|
10 return (1 - t) * a + (t) * b
|
|
11
|
|
12
|
|
13 @dataclass(frozen=True)
|
|
14 class Color(DataClassJsonMixin):
|
16
|
15 """This is a target color that should look "the same" on all lights you send
|
|
16 it to. We convert it somehow to a DeviceColor which has the color
|
|
17 coordinates (maybe not RGB) that get sent to a light."""
|
8
|
18 r: float
|
|
19 g: float
|
|
20 b: float
|
4
|
21
|
8
|
22 def __post_init__(self):
|
|
23 super().__setattr__('r', max(0, min(1, self.r)))
|
|
24 super().__setattr__('g', max(0, min(1, self.g)))
|
|
25 super().__setattr__('b', max(0, min(1, self.b)))
|
|
26
|
|
27 def __repr__(self):
|
|
28 return f'(Color(r={self.r:.3f}, g={self.g:.3f}, b={self.b:.3f}))'
|
|
29
|
|
30 def avg(self):
|
|
31 return (self.r + self.g + self.b) / 3
|
4
|
32
|
8
|
33 def mix(self, other, x):
|
|
34 return Color(
|
|
35 lerp(self.r, other.r, x),
|
|
36 lerp(self.g, other.g, x),
|
|
37 lerp(self.b, other.b, x),
|
|
38 )
|
|
39
|
|
40 def hex(self):
|
|
41 r, g, b = int(self.r * 255), int(self.g * 255), int(self.b * 255)
|
|
42 return '#%02x%02x%02x' % (r, g, b)
|
9
|
43
|
|
44 @classmethod
|
|
45 def fromHex(cls, h: str):
|
|
46 return cls(
|
|
47 r=int(h[1:3], 16) / 255,
|
|
48 g=int(h[3:5], 16) / 255,
|
|
49 b=int(h[5:7], 16) / 255,
|
|
50 )
|