bevy_color/
color.rs

1use crate::{
2    color_difference::EuclideanDistance, Alpha, Hsla, Hsva, Hue, Hwba, Laba, Lcha, LinearRgba,
3    Luminance, Mix, Oklaba, Oklcha, Srgba, StandardColor, Xyza,
4};
5#[cfg(feature = "bevy_reflect")]
6use bevy_reflect::prelude::*;
7use derive_more::derive::From;
8
9/// An enumerated type that can represent any of the color types in this crate.
10///
11/// This is useful when you need to store a color in a data structure that can't be generic over
12/// the color type.
13#[doc = include_str!("../docs/conversion.md")]
14/// <div>
15#[doc = include_str!("../docs/diagrams/model_graph.svg")]
16/// </div>
17///
18/// # Operations
19///
20/// [`Color`] supports all the standard color operations, such as [mixing](Mix),
21/// [luminance](Luminance) and [hue](Hue) adjustment,
22/// and [diffing](EuclideanDistance). These operations delegate to the concrete color space contained
23/// by [`Color`], but will convert to [`Oklch`](Oklcha) for operations which aren't supported in the
24/// current space. After performing the operation, if a conversion was required, the result will be
25/// converted back into the original color space.
26///
27/// ```rust
28/// # use bevy_color::{Hue, Color};
29/// let red_hsv = Color::hsv(0., 1., 1.);
30/// let red_srgb = Color::srgb(1., 0., 0.);
31///
32/// // HSV has a definition of hue, so it will be returned.
33/// red_hsv.hue();
34///
35/// // SRGB doesn't have a native definition for hue.
36/// // Converts to Oklch and returns that result.
37/// red_srgb.hue();
38/// ```
39///
40/// [`Oklch`](Oklcha) has been chosen as the intermediary space in cases where conversion is required
41/// due to its perceptual uniformity and broad support for Bevy's color operations.
42/// To avoid the cost of repeated conversion, and ensure consistent results where that is desired,
43/// first convert this [`Color`] into your desired color space.
44#[derive(Debug, Clone, Copy, PartialEq, From)]
45#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(PartialEq, Default))]
46#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
47#[cfg_attr(
48    all(feature = "serialize", feature = "bevy_reflect"),
49    reflect(Serialize, Deserialize)
50)]
51pub enum Color {
52    /// A color in the sRGB color space with alpha.
53    Srgba(Srgba),
54    /// A color in the linear sRGB color space with alpha.
55    LinearRgba(LinearRgba),
56    /// A color in the HSL color space with alpha.
57    Hsla(Hsla),
58    /// A color in the HSV color space with alpha.
59    Hsva(Hsva),
60    /// A color in the HWB color space with alpha.
61    Hwba(Hwba),
62    /// A color in the LAB color space with alpha.
63    Laba(Laba),
64    /// A color in the LCH color space with alpha.
65    Lcha(Lcha),
66    /// A color in the Oklab color space with alpha.
67    Oklaba(Oklaba),
68    /// A color in the Oklch color space with alpha.
69    Oklcha(Oklcha),
70    /// A color in the XYZ color space with alpha.
71    Xyza(Xyza),
72}
73
74impl StandardColor for Color {}
75
76impl Color {
77    /// Return the color as a linear RGBA color.
78    pub fn to_linear(&self) -> LinearRgba {
79        (*self).into()
80    }
81
82    /// Return the color as an SRGBA color.
83    pub fn to_srgba(&self) -> Srgba {
84        (*self).into()
85    }
86
87    #[deprecated = "Use `Color::srgba` instead"]
88    /// Creates a new [`Color`] object storing a [`Srgba`] color.
89    pub const fn rgba(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
90        Self::srgba(red, green, blue, alpha)
91    }
92
93    /// Creates a new [`Color`] object storing a [`Srgba`] color.
94    pub const fn srgba(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
95        Self::Srgba(Srgba {
96            red,
97            green,
98            blue,
99            alpha,
100        })
101    }
102
103    #[deprecated = "Use `Color::srgb` instead"]
104    /// Creates a new [`Color`] object storing a [`Srgba`] color with an alpha of 1.0.
105    pub const fn rgb(red: f32, green: f32, blue: f32) -> Self {
106        Self::srgb(red, green, blue)
107    }
108
109    /// Creates a new [`Color`] object storing a [`Srgba`] color with an alpha of 1.0.
110    pub const fn srgb(red: f32, green: f32, blue: f32) -> Self {
111        Self::Srgba(Srgba {
112            red,
113            green,
114            blue,
115            alpha: 1.0,
116        })
117    }
118
119    #[deprecated = "Use `Color::srgb_from_array` instead"]
120    /// Reads an array of floats to creates a new [`Color`] object storing a [`Srgba`] color with an alpha of 1.0.
121    pub fn rgb_from_array([r, g, b]: [f32; 3]) -> Self {
122        Self::Srgba(Srgba::rgb(r, g, b))
123    }
124
125    /// Reads an array of floats to creates a new [`Color`] object storing a [`Srgba`] color with an alpha of 1.0.
126    pub fn srgb_from_array(array: [f32; 3]) -> Self {
127        Self::Srgba(Srgba {
128            red: array[0],
129            green: array[1],
130            blue: array[2],
131            alpha: 1.0,
132        })
133    }
134
135    #[deprecated = "Use `Color::srgba_u8` instead"]
136    /// Creates a new [`Color`] object storing a [`Srgba`] color from [`u8`] values.
137    ///
138    /// A value of 0 is interpreted as 0.0, and a value of 255 is interpreted as 1.0.
139    pub fn rgba_u8(red: u8, green: u8, blue: u8, alpha: u8) -> Self {
140        Self::srgba_u8(red, green, blue, alpha)
141    }
142
143    /// Creates a new [`Color`] object storing a [`Srgba`] color from [`u8`] values.
144    ///
145    /// A value of 0 is interpreted as 0.0, and a value of 255 is interpreted as 1.0.
146    pub fn srgba_u8(red: u8, green: u8, blue: u8, alpha: u8) -> Self {
147        Self::Srgba(Srgba {
148            red: red as f32 / 255.0,
149            green: green as f32 / 255.0,
150            blue: blue as f32 / 255.0,
151            alpha: alpha as f32 / 255.0,
152        })
153    }
154
155    #[deprecated = "Use `Color::srgb_u8` instead"]
156    /// Creates a new [`Color`] object storing a [`Srgba`] color from [`u8`] values with an alpha of 1.0.
157    ///
158    /// A value of 0 is interpreted as 0.0, and a value of 255 is interpreted as 1.0.
159    pub fn rgb_u8(red: u8, green: u8, blue: u8) -> Self {
160        Self::srgb_u8(red, green, blue)
161    }
162
163    /// Creates a new [`Color`] object storing a [`Srgba`] color from [`u8`] values with an alpha of 1.0.
164    ///
165    /// A value of 0 is interpreted as 0.0, and a value of 255 is interpreted as 1.0.
166    pub fn srgb_u8(red: u8, green: u8, blue: u8) -> Self {
167        Self::Srgba(Srgba {
168            red: red as f32 / 255.0,
169            green: green as f32 / 255.0,
170            blue: blue as f32 / 255.0,
171            alpha: 1.0,
172        })
173    }
174
175    #[deprecated = "Use Color::linear_rgba instead."]
176    /// Creates a new [`Color`] object storing a [`LinearRgba`] color.
177    pub const fn rbga_linear(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
178        Self::linear_rgba(red, green, blue, alpha)
179    }
180
181    /// Creates a new [`Color`] object storing a [`LinearRgba`] color.
182    pub const fn linear_rgba(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
183        Self::LinearRgba(LinearRgba {
184            red,
185            green,
186            blue,
187            alpha,
188        })
189    }
190
191    #[deprecated = "Use Color::linear_rgb instead."]
192    /// Creates a new [`Color`] object storing a [`LinearRgba`] color with an alpha of 1.0.
193    pub const fn rgb_linear(red: f32, green: f32, blue: f32) -> Self {
194        Self::linear_rgb(red, green, blue)
195    }
196
197    /// Creates a new [`Color`] object storing a [`LinearRgba`] color with an alpha of 1.0.
198    pub const fn linear_rgb(red: f32, green: f32, blue: f32) -> Self {
199        Self::LinearRgba(LinearRgba {
200            red,
201            green,
202            blue,
203            alpha: 1.0,
204        })
205    }
206
207    /// Creates a new [`Color`] object storing a [`Hsla`] color.
208    pub const fn hsla(hue: f32, saturation: f32, lightness: f32, alpha: f32) -> Self {
209        Self::Hsla(Hsla {
210            hue,
211            saturation,
212            lightness,
213            alpha,
214        })
215    }
216
217    /// Creates a new [`Color`] object storing a [`Hsla`] color with an alpha of 1.0.
218    pub const fn hsl(hue: f32, saturation: f32, lightness: f32) -> Self {
219        Self::Hsla(Hsla {
220            hue,
221            saturation,
222            lightness,
223            alpha: 1.0,
224        })
225    }
226
227    /// Creates a new [`Color`] object storing a [`Hsva`] color.
228    pub const fn hsva(hue: f32, saturation: f32, value: f32, alpha: f32) -> Self {
229        Self::Hsva(Hsva {
230            hue,
231            saturation,
232            value,
233            alpha,
234        })
235    }
236
237    /// Creates a new [`Color`] object storing a [`Hsva`] color with an alpha of 1.0.
238    pub const fn hsv(hue: f32, saturation: f32, value: f32) -> Self {
239        Self::Hsva(Hsva {
240            hue,
241            saturation,
242            value,
243            alpha: 1.0,
244        })
245    }
246
247    /// Creates a new [`Color`] object storing a [`Hwba`] color.
248    pub const fn hwba(hue: f32, whiteness: f32, blackness: f32, alpha: f32) -> Self {
249        Self::Hwba(Hwba {
250            hue,
251            whiteness,
252            blackness,
253            alpha,
254        })
255    }
256
257    /// Creates a new [`Color`] object storing a [`Hwba`] color with an alpha of 1.0.
258    pub const fn hwb(hue: f32, whiteness: f32, blackness: f32) -> Self {
259        Self::Hwba(Hwba {
260            hue,
261            whiteness,
262            blackness,
263            alpha: 1.0,
264        })
265    }
266
267    /// Creates a new [`Color`] object storing a [`Laba`] color.
268    pub const fn laba(lightness: f32, a: f32, b: f32, alpha: f32) -> Self {
269        Self::Laba(Laba {
270            lightness,
271            a,
272            b,
273            alpha,
274        })
275    }
276
277    /// Creates a new [`Color`] object storing a [`Laba`] color with an alpha of 1.0.
278    pub const fn lab(lightness: f32, a: f32, b: f32) -> Self {
279        Self::Laba(Laba {
280            lightness,
281            a,
282            b,
283            alpha: 1.0,
284        })
285    }
286
287    /// Creates a new [`Color`] object storing a [`Lcha`] color.
288    pub const fn lcha(lightness: f32, chroma: f32, hue: f32, alpha: f32) -> Self {
289        Self::Lcha(Lcha {
290            lightness,
291            chroma,
292            hue,
293            alpha,
294        })
295    }
296
297    /// Creates a new [`Color`] object storing a [`Lcha`] color with an alpha of 1.0.
298    pub const fn lch(lightness: f32, chroma: f32, hue: f32) -> Self {
299        Self::Lcha(Lcha {
300            lightness,
301            chroma,
302            hue,
303            alpha: 1.0,
304        })
305    }
306
307    /// Creates a new [`Color`] object storing a [`Oklaba`] color.
308    pub const fn oklaba(lightness: f32, a: f32, b: f32, alpha: f32) -> Self {
309        Self::Oklaba(Oklaba {
310            lightness,
311            a,
312            b,
313            alpha,
314        })
315    }
316
317    /// Creates a new [`Color`] object storing a [`Oklaba`] color with an alpha of 1.0.
318    pub const fn oklab(lightness: f32, a: f32, b: f32) -> Self {
319        Self::Oklaba(Oklaba {
320            lightness,
321            a,
322            b,
323            alpha: 1.0,
324        })
325    }
326
327    /// Creates a new [`Color`] object storing a [`Oklcha`] color.
328    pub const fn oklcha(lightness: f32, chroma: f32, hue: f32, alpha: f32) -> Self {
329        Self::Oklcha(Oklcha {
330            lightness,
331            chroma,
332            hue,
333            alpha,
334        })
335    }
336
337    /// Creates a new [`Color`] object storing a [`Oklcha`] color with an alpha of 1.0.
338    pub const fn oklch(lightness: f32, chroma: f32, hue: f32) -> Self {
339        Self::Oklcha(Oklcha {
340            lightness,
341            chroma,
342            hue,
343            alpha: 1.0,
344        })
345    }
346
347    /// Creates a new [`Color`] object storing a [`Xyza`] color.
348    pub const fn xyza(x: f32, y: f32, z: f32, alpha: f32) -> Self {
349        Self::Xyza(Xyza { x, y, z, alpha })
350    }
351
352    /// Creates a new [`Color`] object storing a [`Xyza`] color with an alpha of 1.0.
353    pub const fn xyz(x: f32, y: f32, z: f32) -> Self {
354        Self::Xyza(Xyza {
355            x,
356            y,
357            z,
358            alpha: 1.0,
359        })
360    }
361
362    /// A fully white [`Color::LinearRgba`] color with an alpha of 1.0.
363    pub const WHITE: Self = Self::linear_rgb(1.0, 1.0, 1.0);
364
365    /// A fully black [`Color::LinearRgba`] color with an alpha of 1.0.
366    pub const BLACK: Self = Self::linear_rgb(0., 0., 0.);
367
368    /// A fully transparent [`Color::LinearRgba`] color with 0 red, green and blue.
369    pub const NONE: Self = Self::linear_rgba(0., 0., 0., 0.);
370}
371
372impl Default for Color {
373    /// A fully white [`Color::LinearRgba`] color with an alpha of 1.0.
374    fn default() -> Self {
375        Color::WHITE
376    }
377}
378
379impl Alpha for Color {
380    fn with_alpha(&self, alpha: f32) -> Self {
381        let mut new = *self;
382
383        match &mut new {
384            Color::Srgba(x) => *x = x.with_alpha(alpha),
385            Color::LinearRgba(x) => *x = x.with_alpha(alpha),
386            Color::Hsla(x) => *x = x.with_alpha(alpha),
387            Color::Hsva(x) => *x = x.with_alpha(alpha),
388            Color::Hwba(x) => *x = x.with_alpha(alpha),
389            Color::Laba(x) => *x = x.with_alpha(alpha),
390            Color::Lcha(x) => *x = x.with_alpha(alpha),
391            Color::Oklaba(x) => *x = x.with_alpha(alpha),
392            Color::Oklcha(x) => *x = x.with_alpha(alpha),
393            Color::Xyza(x) => *x = x.with_alpha(alpha),
394        }
395
396        new
397    }
398
399    fn alpha(&self) -> f32 {
400        match self {
401            Color::Srgba(x) => x.alpha(),
402            Color::LinearRgba(x) => x.alpha(),
403            Color::Hsla(x) => x.alpha(),
404            Color::Hsva(x) => x.alpha(),
405            Color::Hwba(x) => x.alpha(),
406            Color::Laba(x) => x.alpha(),
407            Color::Lcha(x) => x.alpha(),
408            Color::Oklaba(x) => x.alpha(),
409            Color::Oklcha(x) => x.alpha(),
410            Color::Xyza(x) => x.alpha(),
411        }
412    }
413
414    fn set_alpha(&mut self, alpha: f32) {
415        match self {
416            Color::Srgba(x) => x.set_alpha(alpha),
417            Color::LinearRgba(x) => x.set_alpha(alpha),
418            Color::Hsla(x) => x.set_alpha(alpha),
419            Color::Hsva(x) => x.set_alpha(alpha),
420            Color::Hwba(x) => x.set_alpha(alpha),
421            Color::Laba(x) => x.set_alpha(alpha),
422            Color::Lcha(x) => x.set_alpha(alpha),
423            Color::Oklaba(x) => x.set_alpha(alpha),
424            Color::Oklcha(x) => x.set_alpha(alpha),
425            Color::Xyza(x) => x.set_alpha(alpha),
426        }
427    }
428}
429
430impl From<Color> for Srgba {
431    fn from(value: Color) -> Self {
432        match value {
433            Color::Srgba(srgba) => srgba,
434            Color::LinearRgba(linear) => linear.into(),
435            Color::Hsla(hsla) => hsla.into(),
436            Color::Hsva(hsva) => hsva.into(),
437            Color::Hwba(hwba) => hwba.into(),
438            Color::Laba(laba) => laba.into(),
439            Color::Lcha(lcha) => lcha.into(),
440            Color::Oklaba(oklab) => oklab.into(),
441            Color::Oklcha(oklch) => oklch.into(),
442            Color::Xyza(xyza) => xyza.into(),
443        }
444    }
445}
446
447impl From<Color> for LinearRgba {
448    fn from(value: Color) -> Self {
449        match value {
450            Color::Srgba(srgba) => srgba.into(),
451            Color::LinearRgba(linear) => linear,
452            Color::Hsla(hsla) => hsla.into(),
453            Color::Hsva(hsva) => hsva.into(),
454            Color::Hwba(hwba) => hwba.into(),
455            Color::Laba(laba) => laba.into(),
456            Color::Lcha(lcha) => lcha.into(),
457            Color::Oklaba(oklab) => oklab.into(),
458            Color::Oklcha(oklch) => oklch.into(),
459            Color::Xyza(xyza) => xyza.into(),
460        }
461    }
462}
463
464impl From<Color> for Hsla {
465    fn from(value: Color) -> Self {
466        match value {
467            Color::Srgba(srgba) => srgba.into(),
468            Color::LinearRgba(linear) => linear.into(),
469            Color::Hsla(hsla) => hsla,
470            Color::Hsva(hsva) => hsva.into(),
471            Color::Hwba(hwba) => hwba.into(),
472            Color::Laba(laba) => laba.into(),
473            Color::Lcha(lcha) => lcha.into(),
474            Color::Oklaba(oklab) => oklab.into(),
475            Color::Oklcha(oklch) => oklch.into(),
476            Color::Xyza(xyza) => xyza.into(),
477        }
478    }
479}
480
481impl From<Color> for Hsva {
482    fn from(value: Color) -> Self {
483        match value {
484            Color::Srgba(srgba) => srgba.into(),
485            Color::LinearRgba(linear) => linear.into(),
486            Color::Hsla(hsla) => hsla.into(),
487            Color::Hsva(hsva) => hsva,
488            Color::Hwba(hwba) => hwba.into(),
489            Color::Laba(laba) => laba.into(),
490            Color::Lcha(lcha) => lcha.into(),
491            Color::Oklaba(oklab) => oklab.into(),
492            Color::Oklcha(oklch) => oklch.into(),
493            Color::Xyza(xyza) => xyza.into(),
494        }
495    }
496}
497
498impl From<Color> for Hwba {
499    fn from(value: Color) -> Self {
500        match value {
501            Color::Srgba(srgba) => srgba.into(),
502            Color::LinearRgba(linear) => linear.into(),
503            Color::Hsla(hsla) => hsla.into(),
504            Color::Hsva(hsva) => hsva.into(),
505            Color::Hwba(hwba) => hwba,
506            Color::Laba(laba) => laba.into(),
507            Color::Lcha(lcha) => lcha.into(),
508            Color::Oklaba(oklab) => oklab.into(),
509            Color::Oklcha(oklch) => oklch.into(),
510            Color::Xyza(xyza) => xyza.into(),
511        }
512    }
513}
514
515impl From<Color> for Laba {
516    fn from(value: Color) -> Self {
517        match value {
518            Color::Srgba(srgba) => srgba.into(),
519            Color::LinearRgba(linear) => linear.into(),
520            Color::Hsla(hsla) => hsla.into(),
521            Color::Hsva(hsva) => hsva.into(),
522            Color::Hwba(hwba) => hwba.into(),
523            Color::Laba(laba) => laba,
524            Color::Lcha(lcha) => lcha.into(),
525            Color::Oklaba(oklab) => oklab.into(),
526            Color::Oklcha(oklch) => oklch.into(),
527            Color::Xyza(xyza) => xyza.into(),
528        }
529    }
530}
531
532impl From<Color> for Lcha {
533    fn from(value: Color) -> Self {
534        match value {
535            Color::Srgba(srgba) => srgba.into(),
536            Color::LinearRgba(linear) => linear.into(),
537            Color::Hsla(hsla) => hsla.into(),
538            Color::Hsva(hsva) => hsva.into(),
539            Color::Hwba(hwba) => hwba.into(),
540            Color::Laba(laba) => laba.into(),
541            Color::Lcha(lcha) => lcha,
542            Color::Oklaba(oklab) => oklab.into(),
543            Color::Oklcha(oklch) => oklch.into(),
544            Color::Xyza(xyza) => xyza.into(),
545        }
546    }
547}
548
549impl From<Color> for Oklaba {
550    fn from(value: Color) -> Self {
551        match value {
552            Color::Srgba(srgba) => srgba.into(),
553            Color::LinearRgba(linear) => linear.into(),
554            Color::Hsla(hsla) => hsla.into(),
555            Color::Hsva(hsva) => hsva.into(),
556            Color::Hwba(hwba) => hwba.into(),
557            Color::Laba(laba) => laba.into(),
558            Color::Lcha(lcha) => lcha.into(),
559            Color::Oklaba(oklab) => oklab,
560            Color::Oklcha(oklch) => oklch.into(),
561            Color::Xyza(xyza) => xyza.into(),
562        }
563    }
564}
565
566impl From<Color> for Oklcha {
567    fn from(value: Color) -> Self {
568        match value {
569            Color::Srgba(srgba) => srgba.into(),
570            Color::LinearRgba(linear) => linear.into(),
571            Color::Hsla(hsla) => hsla.into(),
572            Color::Hsva(hsva) => hsva.into(),
573            Color::Hwba(hwba) => hwba.into(),
574            Color::Laba(laba) => laba.into(),
575            Color::Lcha(lcha) => lcha.into(),
576            Color::Oklaba(oklab) => oklab.into(),
577            Color::Oklcha(oklch) => oklch,
578            Color::Xyza(xyza) => xyza.into(),
579        }
580    }
581}
582
583impl From<Color> for Xyza {
584    fn from(value: Color) -> Self {
585        match value {
586            Color::Srgba(x) => x.into(),
587            Color::LinearRgba(x) => x.into(),
588            Color::Hsla(x) => x.into(),
589            Color::Hsva(hsva) => hsva.into(),
590            Color::Hwba(hwba) => hwba.into(),
591            Color::Laba(laba) => laba.into(),
592            Color::Lcha(x) => x.into(),
593            Color::Oklaba(x) => x.into(),
594            Color::Oklcha(oklch) => oklch.into(),
595            Color::Xyza(xyza) => xyza,
596        }
597    }
598}
599
600/// Color space chosen for operations on `Color`.
601type ChosenColorSpace = Oklcha;
602
603impl Luminance for Color {
604    fn luminance(&self) -> f32 {
605        match self {
606            Color::Srgba(x) => x.luminance(),
607            Color::LinearRgba(x) => x.luminance(),
608            Color::Hsla(x) => x.luminance(),
609            Color::Hsva(x) => ChosenColorSpace::from(*x).luminance(),
610            Color::Hwba(x) => ChosenColorSpace::from(*x).luminance(),
611            Color::Laba(x) => x.luminance(),
612            Color::Lcha(x) => x.luminance(),
613            Color::Oklaba(x) => x.luminance(),
614            Color::Oklcha(x) => x.luminance(),
615            Color::Xyza(x) => x.luminance(),
616        }
617    }
618
619    fn with_luminance(&self, value: f32) -> Self {
620        let mut new = *self;
621
622        match &mut new {
623            Color::Srgba(x) => *x = x.with_luminance(value),
624            Color::LinearRgba(x) => *x = x.with_luminance(value),
625            Color::Hsla(x) => *x = x.with_luminance(value),
626            Color::Hsva(x) => *x = ChosenColorSpace::from(*x).with_luminance(value).into(),
627            Color::Hwba(x) => *x = ChosenColorSpace::from(*x).with_luminance(value).into(),
628            Color::Laba(x) => *x = x.with_luminance(value),
629            Color::Lcha(x) => *x = x.with_luminance(value),
630            Color::Oklaba(x) => *x = x.with_luminance(value),
631            Color::Oklcha(x) => *x = x.with_luminance(value),
632            Color::Xyza(x) => *x = x.with_luminance(value),
633        }
634
635        new
636    }
637
638    fn darker(&self, amount: f32) -> Self {
639        let mut new = *self;
640
641        match &mut new {
642            Color::Srgba(x) => *x = x.darker(amount),
643            Color::LinearRgba(x) => *x = x.darker(amount),
644            Color::Hsla(x) => *x = x.darker(amount),
645            Color::Hsva(x) => *x = ChosenColorSpace::from(*x).darker(amount).into(),
646            Color::Hwba(x) => *x = ChosenColorSpace::from(*x).darker(amount).into(),
647            Color::Laba(x) => *x = x.darker(amount),
648            Color::Lcha(x) => *x = x.darker(amount),
649            Color::Oklaba(x) => *x = x.darker(amount),
650            Color::Oklcha(x) => *x = x.darker(amount),
651            Color::Xyza(x) => *x = x.darker(amount),
652        }
653
654        new
655    }
656
657    fn lighter(&self, amount: f32) -> Self {
658        let mut new = *self;
659
660        match &mut new {
661            Color::Srgba(x) => *x = x.lighter(amount),
662            Color::LinearRgba(x) => *x = x.lighter(amount),
663            Color::Hsla(x) => *x = x.lighter(amount),
664            Color::Hsva(x) => *x = ChosenColorSpace::from(*x).lighter(amount).into(),
665            Color::Hwba(x) => *x = ChosenColorSpace::from(*x).lighter(amount).into(),
666            Color::Laba(x) => *x = x.lighter(amount),
667            Color::Lcha(x) => *x = x.lighter(amount),
668            Color::Oklaba(x) => *x = x.lighter(amount),
669            Color::Oklcha(x) => *x = x.lighter(amount),
670            Color::Xyza(x) => *x = x.lighter(amount),
671        }
672
673        new
674    }
675}
676
677impl Hue for Color {
678    fn with_hue(&self, hue: f32) -> Self {
679        let mut new = *self;
680
681        match &mut new {
682            Color::Srgba(x) => *x = ChosenColorSpace::from(*x).with_hue(hue).into(),
683            Color::LinearRgba(x) => *x = ChosenColorSpace::from(*x).with_hue(hue).into(),
684            Color::Hsla(x) => *x = x.with_hue(hue),
685            Color::Hsva(x) => *x = x.with_hue(hue),
686            Color::Hwba(x) => *x = x.with_hue(hue),
687            Color::Laba(x) => *x = ChosenColorSpace::from(*x).with_hue(hue).into(),
688            Color::Lcha(x) => *x = x.with_hue(hue),
689            Color::Oklaba(x) => *x = ChosenColorSpace::from(*x).with_hue(hue).into(),
690            Color::Oklcha(x) => *x = x.with_hue(hue),
691            Color::Xyza(x) => *x = ChosenColorSpace::from(*x).with_hue(hue).into(),
692        }
693
694        new
695    }
696
697    fn hue(&self) -> f32 {
698        match self {
699            Color::Srgba(x) => ChosenColorSpace::from(*x).hue(),
700            Color::LinearRgba(x) => ChosenColorSpace::from(*x).hue(),
701            Color::Hsla(x) => x.hue(),
702            Color::Hsva(x) => x.hue(),
703            Color::Hwba(x) => x.hue(),
704            Color::Laba(x) => ChosenColorSpace::from(*x).hue(),
705            Color::Lcha(x) => x.hue(),
706            Color::Oklaba(x) => ChosenColorSpace::from(*x).hue(),
707            Color::Oklcha(x) => x.hue(),
708            Color::Xyza(x) => ChosenColorSpace::from(*x).hue(),
709        }
710    }
711
712    fn set_hue(&mut self, hue: f32) {
713        *self = self.with_hue(hue);
714    }
715}
716
717impl Mix for Color {
718    fn mix(&self, other: &Self, factor: f32) -> Self {
719        let mut new = *self;
720
721        match &mut new {
722            Color::Srgba(x) => *x = x.mix(&(*other).into(), factor),
723            Color::LinearRgba(x) => *x = x.mix(&(*other).into(), factor),
724            Color::Hsla(x) => *x = x.mix(&(*other).into(), factor),
725            Color::Hsva(x) => *x = x.mix(&(*other).into(), factor),
726            Color::Hwba(x) => *x = x.mix(&(*other).into(), factor),
727            Color::Laba(x) => *x = x.mix(&(*other).into(), factor),
728            Color::Lcha(x) => *x = x.mix(&(*other).into(), factor),
729            Color::Oklaba(x) => *x = x.mix(&(*other).into(), factor),
730            Color::Oklcha(x) => *x = x.mix(&(*other).into(), factor),
731            Color::Xyza(x) => *x = x.mix(&(*other).into(), factor),
732        }
733
734        new
735    }
736}
737
738impl EuclideanDistance for Color {
739    fn distance_squared(&self, other: &Self) -> f32 {
740        match self {
741            Color::Srgba(x) => x.distance_squared(&(*other).into()),
742            Color::LinearRgba(x) => x.distance_squared(&(*other).into()),
743            Color::Hsla(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
744            Color::Hsva(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
745            Color::Hwba(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
746            Color::Laba(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
747            Color::Lcha(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
748            Color::Oklaba(x) => x.distance_squared(&(*other).into()),
749            Color::Oklcha(x) => x.distance_squared(&(*other).into()),
750            Color::Xyza(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
751        }
752    }
753}