From af0323a55e9cbfe28262fd500fbe21f8cf4c8ee4 Mon Sep 17 00:00:00 2001 From: IDEDARY <49441831+IDEDARY@users.noreply.github.com> Date: Mon, 21 Aug 2023 18:29:28 +0200 Subject: [PATCH] [RAINBOW EFFECT] Added methods to get HSL components from Color (#9201) # Changes Added methods to Color enum to retrieve Hue, Saturation and Lightness values. ## Why? As you probably know, to create a color that iterates over the color spectrum (rainbow effect that can be seen on LED keyboards, PC components, etc..), you need to mix the color from Hue, Saturation and Luminosity. Bevy already supports multiple color formats, but provides only 4 methods of retrieving components for RGBA. Nothing like ".get_hue()", so I implemented them with all their variations that RGBA has. Now we can do true rainbow color blending (Example is a button hover effect): [Discord Showcase](https://discord.com/channels/691052431525675048/866787577687310356/1130960862232969400), [Video download](https://cdn.discordapp.com/attachments/866787577687310356/1130960861708697600/HSL_PR.mp4) ![image](https://github.com/bevyengine/bevy/assets/49441831/e8cf4905-2d09-45b3-8e5b-e6203da7fa9c) --- crates/bevy_render/src/color/mod.rs | 93 ++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 9 deletions(-) diff --git a/crates/bevy_render/src/color/mod.rs b/crates/bevy_render/src/color/mod.rs index 795ba48e3e0fc..c5839b7cd4266 100644 --- a/crates/bevy_render/src/color/mod.rs +++ b/crates/bevy_render/src/color/mod.rs @@ -368,7 +368,7 @@ impl Color { ) } - /// Get red in sRGB colorspace. + /// Converts a Color to variant [`Color::Rgba`] and return red in sRGB colorspace pub fn r(&self) -> f32 { match self.as_rgba() { Color::Rgba { red, .. } => red, @@ -376,7 +376,7 @@ impl Color { } } - /// Get green in sRGB colorspace. + /// Converts a Color to variant [`Color::Rgba`] and return green in sRGB colorspace pub fn g(&self) -> f32 { match self.as_rgba() { Color::Rgba { green, .. } => green, @@ -384,7 +384,7 @@ impl Color { } } - /// Get blue in sRGB colorspace. + /// Converts a Color to variant [`Color::Rgba`] and return blue in sRGB colorspace pub fn b(&self) -> f32 { match self.as_rgba() { Color::Rgba { blue, .. } => blue, @@ -392,7 +392,7 @@ impl Color { } } - /// Set red in sRGB colorspace. + /// Converts a Color to variant [`Color::Rgba`] and set red pub fn set_r(&mut self, r: f32) -> &mut Self { *self = self.as_rgba(); match self { @@ -402,14 +402,14 @@ impl Color { self } - /// Returns this color with red set to a new value in sRGB colorspace. + /// Converts a Color to variant [`Color::Rgba`] and return this color with red set to a new value #[must_use] pub fn with_r(mut self, r: f32) -> Self { self.set_r(r); self } - /// Set green in sRGB colorspace. + /// Converts a Color to variant [`Color::Rgba`] and set green pub fn set_g(&mut self, g: f32) -> &mut Self { *self = self.as_rgba(); match self { @@ -419,14 +419,14 @@ impl Color { self } - /// Returns this color with green set to a new value in sRGB colorspace. + /// Converts a Color to variant [`Color::Rgba`] and return this color with green set to a new value #[must_use] pub fn with_g(mut self, g: f32) -> Self { self.set_g(g); self } - /// Set blue in sRGB colorspace. + /// Converts a Color to variant [`Color::Rgba`] and set blue pub fn set_b(&mut self, b: f32) -> &mut Self { *self = self.as_rgba(); match self { @@ -436,13 +436,88 @@ impl Color { self } - /// Returns this color with blue set to a new value in sRGB colorspace. + /// Converts a Color to variant [`Color::Rgba`] and return this color with blue set to a new value #[must_use] pub fn with_b(mut self, b: f32) -> Self { self.set_b(b); self } + /// Converts a Color to variant [`Color::Hsla`] and return hue + pub fn h(&self) -> f32 { + match self.as_hsla() { + Color::Hsla { hue, .. } => hue, + _ => unreachable!(), + } + } + + /// Converts a Color to variant [`Color::Hsla`] and return saturation + pub fn s(&self) -> f32 { + match self.as_hsla() { + Color::Hsla { saturation, .. } => saturation, + _ => unreachable!(), + } + } + + /// Converts a Color to variant [`Color::Hsla`] and return lightness + pub fn l(&self) -> f32 { + match self.as_hsla() { + Color::Hsla { lightness, .. } => lightness, + _ => unreachable!(), + } + } + + /// Converts a Color to variant [`Color::Hsla`] and set hue + pub fn set_h(&mut self, h: f32) -> &mut Self { + *self = self.as_hsla(); + match self { + Color::Hsla { hue, .. } => *hue = h, + _ => unreachable!(), + } + self + } + + /// Converts a Color to variant [`Color::Hsla`] and return this color with hue set to a new value + #[must_use] + pub fn with_h(mut self, h: f32) -> Self { + self.set_h(h); + self + } + + /// Converts a Color to variant [`Color::Hsla`] and set saturation + pub fn set_s(&mut self, s: f32) -> &mut Self { + *self = self.as_hsla(); + match self { + Color::Hsla { saturation, .. } => *saturation = s, + _ => unreachable!(), + } + self + } + + /// Converts a Color to variant [`Color::Hsla`] and return this color with saturation set to a new value + #[must_use] + pub fn with_s(mut self, s: f32) -> Self { + self.set_s(s); + self + } + + /// Converts a Color to variant [`Color::Hsla`] and set lightness + pub fn set_l(&mut self, l: f32) -> &mut Self { + *self = self.as_hsla(); + match self { + Color::Hsla { lightness, .. } => *lightness = l, + _ => unreachable!(), + } + self + } + + /// Converts a Color to variant [`Color::Hsla`] and return this color with lightness set to a new value + #[must_use] + pub fn with_l(mut self, l: f32) -> Self { + self.set_l(l); + self + } + /// Get alpha. #[inline(always)] pub fn a(&self) -> f32 {