Skip to content

Commit

Permalink
[RAINBOW EFFECT] Added methods to get HSL components from Color (bevy…
Browse files Browse the repository at this point in the history
…engine#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)
  • Loading branch information
IDEDARY authored Aug 21, 2023
1 parent 8cd77e8 commit af0323a
Showing 1 changed file with 84 additions and 9 deletions.
93 changes: 84 additions & 9 deletions crates/bevy_render/src/color/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,31 +368,31 @@ 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,
_ => unreachable!(),
}
}

/// 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,
_ => unreachable!(),
}
}

/// 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,
_ => unreachable!(),
}
}

/// 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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down

0 comments on commit af0323a

Please sign in to comment.