@@ -15,29 +15,48 @@ class Colour:
1515 red : int
1616 green : int
1717 blue : int
18+ alpha : int = 255
1819
1920 @property
2021 def rgb (self ) -> Tuple [int , int , int ]:
2122 """Get the colour as a 3-tuple of red, green, and blue."""
2223 return self .red , self .green , self .blue
2324
25+ @property
26+ def rgba (self ) -> Tuple [int , int , int , int ]:
27+ """Get the colour as a 4-tuple of red, green, blue, and alpha."""
28+ return self .red , self .green , self .blue , self .alpha
29+
2430 @property
2531 def hex (self ) -> str :
2632 """Get the colour as a lowercase hex string."""
33+ if self .alpha < 255 :
34+ return f"{ self .red :02x} { self .green :02x} { self .blue :02x} { self .alpha :02x} "
2735 return f"{ self .red :02x} { self .green :02x} { self .blue :02x} "
2836
2937 def __eq__ (self , other : Any ) -> bool :
3038 if not isinstance (other , Colour ):
3139 raise ValueError ("Cannot check equality with non-colour types." )
40+
3241 return self .hex == other .hex
3342
3443 @classmethod
3544 def from_hex (cls , hex_string : str ) -> Colour :
36- """Create a color from hex string."""
37- if len (hex_string ) != 6 :
38- raise ValueError ("Hex string must be 6 characters long." )
39- match = re .match (r"([\da-fA-F]{2})" * 3 , hex_string )
45+ """Create a colour from hex string."""
46+ if len (hex_string ) not in (6 , 8 ):
47+ raise ValueError ("Hex string must be 6 or 8 characters long." )
48+
49+ num_groups = 3 if len (hex_string ) == 6 else 4
50+ match = re .match (r"([\da-fA-F]{2})" * num_groups , hex_string )
4051 if match is None :
41- raise ValueError ("Hex string have an invalid format." )
42- hex_r , hex_g , hex_b = match .groups ()
43- return Colour (* (int (col , 16 ) for col in (hex_r , hex_g , hex_b )))
52+ raise ValueError ("Hex string has an invalid format." )
53+
54+ components = (int (col , 16 ) for col in match .groups ())
55+ return Colour (* components )
56+
57+ def opacity (self , opacity : float ) -> Colour :
58+ """Return a new colour with the given opacity."""
59+ if not 0 <= opacity <= 1 :
60+ raise ValueError ("Opacity must be between 0 and 1." )
61+
62+ return Colour (self .red , self .green , self .blue , int (opacity * 255 ))
0 commit comments