33"""
44
55# built-in
6- from typing import NamedTuple , Union
6+ from typing import NamedTuple , TypeVar , Union
77
88# internal
99from svgen .color .conversion import hsl_to_rgb , rgb_to_hsl
166166CSS_COLORS ["slategrey" ] = CSS_COLORS ["slategray" ]
167167
168168Colorlike = Union [str , Hsl , Rgb , "Color" ]
169+ T = TypeVar ("T" , bound = "Color" )
169170
170171
171172class Color (NamedTuple ):
@@ -180,17 +181,17 @@ def __eq__(self, other) -> bool:
180181 return bool (self .rgb == other .rgb or self .hsl == other .hsl )
181182
182183 @classmethod
183- def from_rgb (cls , color : Rgb ) -> "Color" :
184+ def from_rgb (cls : type [ T ] , color : Rgb ) -> T :
184185 """Create a color from an rgb object."""
185186 return cls (color , rgb_to_hsl (color ))
186187
187188 @classmethod
188- def from_hex (cls , value : str ) -> "Color" :
189+ def from_hex (cls : type [ T ] , value : str ) -> T :
189190 """Create a color from a hex value."""
190191 return cls .from_rgb (Rgb .from_hex (value ))
191192
192193 @classmethod
193- def from_hsl (cls , color : Hsl ) -> "Color" :
194+ def from_hsl (cls : type [ T ] , color : Hsl ) -> T :
194195 """Create a color from an hsl object."""
195196 return cls (hsl_to_rgb (color ), color )
196197
@@ -199,7 +200,7 @@ def hsl_arc(self, **kwargs) -> "Color":
199200 return self .from_hsl (self .hsl .arc (** kwargs ))
200201
201202 @classmethod
202- def from_ctor (cls , value : str ) -> "Color" :
203+ def from_ctor (cls : type [ T ] , value : str ) -> T :
203204 """Create a color from an hsl or rgb constructor string."""
204205
205206 # Check if this is a canonical color.
@@ -216,16 +217,47 @@ def from_ctor(cls, value: str) -> "Color":
216217 return cls .from_hex (value )
217218
218219 @classmethod
219- def create (cls , value : Colorlike ) -> "Color" :
220+ def create (cls : type [ T ] , value : Colorlike ) -> T :
220221 """Create a color from a variety of possible sources."""
221- if isinstance (value , Color ):
222- return value
222+
223+ if isinstance (value , (cls , Color )):
224+ return value # type: ignore
223225 if isinstance (value , Hsl ):
224226 return cls .from_hsl (value )
225227 if isinstance (value , Rgb ):
226228 return cls .from_rgb (value )
227229 return cls .from_ctor (value )
228230
231+ def animate (
232+ self : T ,
233+ hue : int = None ,
234+ saturation : float = None ,
235+ lightness : float = None ,
236+ red : int = None ,
237+ green : int = None ,
238+ blue : int = None ,
239+ alpha : float = None ,
240+ delta : bool = False ,
241+ ) -> T :
242+ """Animate this color based on HSL properties."""
243+
244+ if red is not None or blue is not None or green is not None :
245+ return self .from_rgb (
246+ self .rgb .animate (
247+ red = red , green = green , blue = blue , alpha = alpha , delta = delta
248+ )
249+ )
250+
251+ return self .from_hsl (
252+ self .hsl .animate (
253+ hue = hue ,
254+ saturation = saturation ,
255+ lightness = lightness ,
256+ alpha = alpha ,
257+ delta = delta ,
258+ )
259+ )
260+
229261 def __str__ (self ) -> str :
230262 """Convert this color to a hex string."""
231263 return str (self .rgb )
0 commit comments