mirror of
https://github.com/catppuccin/python.git
synced 2026-02-04 20:07:47 +08:00
feat: add opacity to colours
This commit is contained in:
parent
3520cd1ceb
commit
4f9dae019c
@ -15,29 +15,48 @@ class Colour:
|
||||
red: int
|
||||
green: int
|
||||
blue: int
|
||||
alpha: int = 255
|
||||
|
||||
@property
|
||||
def rgb(self) -> Tuple[int, int, int]:
|
||||
"""Get the colour as a 3-tuple of red, green, and blue."""
|
||||
return self.red, self.green, self.blue
|
||||
|
||||
@property
|
||||
def rgba(self) -> Tuple[int, int, int, int]:
|
||||
"""Get the colour as a 4-tuple of red, green, blue, and alpha."""
|
||||
return self.red, self.green, self.blue, self.alpha
|
||||
|
||||
@property
|
||||
def hex(self) -> str:
|
||||
"""Get the colour as a lowercase hex string."""
|
||||
if self.alpha < 255:
|
||||
return f"{self.red:02x}{self.green:02x}{self.blue:02x}{self.alpha:02x}"
|
||||
return f"{self.red:02x}{self.green:02x}{self.blue:02x}"
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
if not isinstance(other, Colour):
|
||||
raise ValueError("Cannot check equality with non-colour types.")
|
||||
|
||||
return self.hex == other.hex
|
||||
|
||||
@classmethod
|
||||
def from_hex(cls, hex_string: str) -> Colour:
|
||||
"""Create a color from hex string."""
|
||||
if len(hex_string) != 6:
|
||||
raise ValueError("Hex string must be 6 characters long.")
|
||||
match = re.match(r"([\da-fA-F]{2})" * 3, hex_string)
|
||||
"""Create a colour from hex string."""
|
||||
if len(hex_string) not in (6, 8):
|
||||
raise ValueError("Hex string must be 6 or 8 characters long.")
|
||||
|
||||
num_groups = 3 if len(hex_string) == 6 else 4
|
||||
match = re.match(r"([\da-fA-F]{2})" * num_groups, hex_string)
|
||||
if match is None:
|
||||
raise ValueError("Hex string have an invalid format.")
|
||||
hex_r, hex_g, hex_b = match.groups()
|
||||
return Colour(*(int(col, 16) for col in (hex_r, hex_g, hex_b)))
|
||||
raise ValueError("Hex string has an invalid format.")
|
||||
|
||||
components = (int(col, 16) for col in match.groups())
|
||||
return Colour(*components)
|
||||
|
||||
def opacity(self, opacity: float) -> Colour:
|
||||
"""Return a new colour with the given opacity."""
|
||||
if not 0 <= opacity <= 1:
|
||||
raise ValueError("Opacity must be between 0 and 1.")
|
||||
|
||||
return Colour(self.red, self.green, self.blue, int(opacity * 255))
|
||||
|
||||
@ -7,14 +7,30 @@ def test_colour_to_rgb():
|
||||
assert Colour(12, 123, 234).rgb == (12, 123, 234)
|
||||
|
||||
|
||||
def test_colour_to_hex():
|
||||
def test_colour_to_rgba():
|
||||
assert Colour(12, 123, 234, 35).rgba == (12, 123, 234, 35)
|
||||
|
||||
|
||||
def test_colour_to_rgba_default():
|
||||
assert Colour(12, 123, 234).rgba == (12, 123, 234, 255)
|
||||
|
||||
|
||||
def test_rgb_colour_to_hex():
|
||||
assert Colour(0x12, 0xEB, 0x77).hex == "12eb77"
|
||||
|
||||
|
||||
def test_hex_to_color():
|
||||
def test_rgba_colour_to_hex():
|
||||
assert Colour(0x12, 0xEB, 0x77, 0x35).hex == "12eb7735"
|
||||
|
||||
|
||||
def test_hex_to_colour():
|
||||
assert Colour.from_hex("12eb77") == Colour(0x12, 0xEB, 0x77)
|
||||
|
||||
|
||||
def test_hex_to_colour_with_alpha():
|
||||
assert Colour.from_hex("12eb7735") == Colour(0x12, 0xEB, 0x77, 0x35)
|
||||
|
||||
|
||||
def test_invalid_hex():
|
||||
for invalid_value in ("1234567", "12345", "Z00000", "ABCDEG", "0F7CBJ"):
|
||||
with pytest.raises(ValueError):
|
||||
@ -27,3 +43,13 @@ def test_equality():
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
assert Colour(0x12, 0xEB, 0x77) == 42
|
||||
|
||||
|
||||
def test_opacity():
|
||||
colour = Colour(0x12, 0xEB, 0x77).opacity(0.5)
|
||||
assert colour == Colour(0x12, 0xEB, 0x77, 0x7F)
|
||||
|
||||
|
||||
def test_opacity_invalid():
|
||||
with pytest.raises(ValueError):
|
||||
Colour(0x12, 0xEB, 0x77).opacity(1.5)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user