mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 22:18:33 +00:00
bevy_color
: Created a private trait StandardColor
(#12072)
# Objective - Assist Bevy contributors in the creation of `bevy_color` spaces by ensuring consistent API implementation. ## Solution Created a `pub(crate)` trait `StandardColor` which has all the requirements for a typical color space (e.g, `Srgba`, `Color`, etc.). --- ## Changelog - Implemented traits missing from certain color spaces. ## Migration Guide _No migration required_
This commit is contained in:
parent
d31de3f139
commit
a52b2518fc
7 changed files with 152 additions and 12 deletions
|
@ -1,10 +1,14 @@
|
||||||
use crate::{Hsla, Lcha, LinearRgba, Oklaba, Srgba};
|
use crate::{Alpha, Hsla, Lcha, LinearRgba, Oklaba, Srgba, StandardColor};
|
||||||
|
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
||||||
|
use bevy_render::color::Color as LegacyColor;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// An enumerated type that can represent any of the color types in this crate.
|
/// An enumerated type that can represent any of the color types in this crate.
|
||||||
///
|
///
|
||||||
/// This is useful when you need to store a color in a data structure that can't be generic over
|
/// This is useful when you need to store a color in a data structure that can't be generic over
|
||||||
/// the color type.
|
/// the color type.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Reflect)]
|
||||||
|
#[reflect(PartialEq, Serialize, Deserialize)]
|
||||||
pub enum Color {
|
pub enum Color {
|
||||||
/// A color in the sRGB color space with alpha.
|
/// A color in the sRGB color space with alpha.
|
||||||
Srgba(Srgba),
|
Srgba(Srgba),
|
||||||
|
@ -18,6 +22,8 @@ pub enum Color {
|
||||||
Oklaba(Oklaba),
|
Oklaba(Oklaba),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StandardColor for Color {}
|
||||||
|
|
||||||
impl Color {
|
impl Color {
|
||||||
/// Return the color as a linear RGBA color.
|
/// Return the color as a linear RGBA color.
|
||||||
pub fn linear(&self) -> LinearRgba {
|
pub fn linear(&self) -> LinearRgba {
|
||||||
|
@ -37,6 +43,32 @@ impl Default for Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Alpha for Color {
|
||||||
|
fn with_alpha(&self, alpha: f32) -> Self {
|
||||||
|
let mut new = *self;
|
||||||
|
|
||||||
|
match &mut new {
|
||||||
|
Color::Srgba(x) => *x = x.with_alpha(alpha),
|
||||||
|
Color::LinearRgba(x) => *x = x.with_alpha(alpha),
|
||||||
|
Color::Hsla(x) => *x = x.with_alpha(alpha),
|
||||||
|
Color::Lcha(x) => *x = x.with_alpha(alpha),
|
||||||
|
Color::Oklaba(x) => *x = x.with_alpha(alpha),
|
||||||
|
}
|
||||||
|
|
||||||
|
new
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alpha(&self) -> f32 {
|
||||||
|
match self {
|
||||||
|
Color::Srgba(x) => x.alpha(),
|
||||||
|
Color::LinearRgba(x) => x.alpha(),
|
||||||
|
Color::Hsla(x) => x.alpha(),
|
||||||
|
Color::Lcha(x) => x.alpha(),
|
||||||
|
Color::Oklaba(x) => x.alpha(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<Srgba> for Color {
|
impl From<Srgba> for Color {
|
||||||
fn from(value: Srgba) -> Self {
|
fn from(value: Srgba) -> Self {
|
||||||
Self::Srgba(value)
|
Self::Srgba(value)
|
||||||
|
@ -126,3 +158,26 @@ impl From<Color> for Oklaba {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<LegacyColor> for Color {
|
||||||
|
fn from(value: LegacyColor) -> Self {
|
||||||
|
match value {
|
||||||
|
LegacyColor::Rgba { .. } => Srgba::from(value).into(),
|
||||||
|
LegacyColor::RgbaLinear { .. } => LinearRgba::from(value).into(),
|
||||||
|
LegacyColor::Hsla { .. } => Hsla::from(value).into(),
|
||||||
|
LegacyColor::Lcha { .. } => Lcha::from(value).into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Color> for LegacyColor {
|
||||||
|
fn from(value: Color) -> Self {
|
||||||
|
match value {
|
||||||
|
Color::Srgba(x) => x.into(),
|
||||||
|
Color::LinearRgba(x) => x.into(),
|
||||||
|
Color::Hsla(x) => x.into(),
|
||||||
|
Color::Lcha(x) => x.into(),
|
||||||
|
Color::Oklaba(x) => x.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{Alpha, LinearRgba, Luminance, Mix, Srgba};
|
use crate::{Alpha, Lcha, LinearRgba, Luminance, Mix, Oklaba, Srgba, StandardColor};
|
||||||
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
||||||
use bevy_render::color::HslRepresentation;
|
use bevy_render::color::HslRepresentation;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -17,6 +17,8 @@ pub struct Hsla {
|
||||||
pub alpha: f32,
|
pub alpha: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StandardColor for Hsla {}
|
||||||
|
|
||||||
impl Hsla {
|
impl Hsla {
|
||||||
/// Construct a new [`Hsla`] color from components.
|
/// Construct a new [`Hsla`] color from components.
|
||||||
///
|
///
|
||||||
|
@ -119,12 +121,6 @@ impl From<Srgba> for Hsla {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<LinearRgba> for Hsla {
|
|
||||||
fn from(value: LinearRgba) -> Self {
|
|
||||||
Hsla::from(Srgba::from(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Hsla> for bevy_render::color::Color {
|
impl From<Hsla> for bevy_render::color::Color {
|
||||||
fn from(value: Hsla) -> Self {
|
fn from(value: Hsla) -> Self {
|
||||||
bevy_render::color::Color::Hsla {
|
bevy_render::color::Color::Hsla {
|
||||||
|
@ -150,6 +146,24 @@ impl From<bevy_render::color::Color> for Hsla {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<LinearRgba> for Hsla {
|
||||||
|
fn from(value: LinearRgba) -> Self {
|
||||||
|
Srgba::from(value).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Oklaba> for Hsla {
|
||||||
|
fn from(value: Oklaba) -> Self {
|
||||||
|
Srgba::from(value).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Lcha> for Hsla {
|
||||||
|
fn from(value: Lcha) -> Self {
|
||||||
|
Srgba::from(value).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{Alpha, LinearRgba, Luminance, Mix, Srgba};
|
use crate::{Alpha, Hsla, LinearRgba, Luminance, Mix, Oklaba, Srgba, StandardColor};
|
||||||
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
||||||
use bevy_render::color::LchRepresentation;
|
use bevy_render::color::LchRepresentation;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -17,6 +17,8 @@ pub struct Lcha {
|
||||||
pub alpha: f32,
|
pub alpha: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StandardColor for Lcha {}
|
||||||
|
|
||||||
impl Lcha {
|
impl Lcha {
|
||||||
/// Construct a new [`Lcha`] color from components.
|
/// Construct a new [`Lcha`] color from components.
|
||||||
///
|
///
|
||||||
|
@ -165,6 +167,18 @@ impl From<bevy_render::color::Color> for Lcha {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Oklaba> for Lcha {
|
||||||
|
fn from(value: Oklaba) -> Self {
|
||||||
|
Srgba::from(value).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Hsla> for Lcha {
|
||||||
|
fn from(value: Hsla) -> Self {
|
||||||
|
Srgba::from(value).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -87,3 +87,25 @@ pub use lcha::*;
|
||||||
pub use linear_rgba::*;
|
pub use linear_rgba::*;
|
||||||
pub use oklaba::*;
|
pub use oklaba::*;
|
||||||
pub use srgba::*;
|
pub use srgba::*;
|
||||||
|
|
||||||
|
use bevy_render::color::Color as LegacyColor;
|
||||||
|
|
||||||
|
/// Describes the traits that a color should implement for consistency.
|
||||||
|
pub(crate) trait StandardColor
|
||||||
|
where
|
||||||
|
Self: core::fmt::Debug,
|
||||||
|
Self: Clone + Copy,
|
||||||
|
Self: PartialEq,
|
||||||
|
Self: serde::Serialize + for<'a> serde::Deserialize<'a>,
|
||||||
|
Self: bevy_reflect::Reflect,
|
||||||
|
Self: Default,
|
||||||
|
Self: From<Color> + Into<Color>,
|
||||||
|
Self: From<LegacyColor> + Into<LegacyColor>,
|
||||||
|
Self: From<Srgba> + Into<Srgba>,
|
||||||
|
Self: From<LinearRgba> + Into<LinearRgba>,
|
||||||
|
Self: From<Hsla> + Into<Hsla>,
|
||||||
|
Self: From<Lcha> + Into<Lcha>,
|
||||||
|
Self: From<Oklaba> + Into<Oklaba>,
|
||||||
|
Self: Alpha,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
color_difference::EuclideanDistance, oklaba::Oklaba, Alpha, Hsla, Luminance, Mix, Srgba,
|
color_difference::EuclideanDistance, oklaba::Oklaba, Alpha, Hsla, Luminance, Mix, Srgba,
|
||||||
|
StandardColor,
|
||||||
};
|
};
|
||||||
use bevy_math::Vec4;
|
use bevy_math::Vec4;
|
||||||
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
||||||
|
@ -20,6 +21,8 @@ pub struct LinearRgba {
|
||||||
pub alpha: f32,
|
pub alpha: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StandardColor for LinearRgba {}
|
||||||
|
|
||||||
impl LinearRgba {
|
impl LinearRgba {
|
||||||
/// Construct a new [`LinearRgba`] color from components.
|
/// Construct a new [`LinearRgba`] color from components.
|
||||||
pub const fn new(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
|
pub const fn new(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
use crate::{color_difference::EuclideanDistance, Alpha, LinearRgba, Luminance, Mix, Srgba};
|
use crate::{
|
||||||
|
color_difference::EuclideanDistance, Alpha, Hsla, Lcha, LinearRgba, Luminance, Mix, Srgba,
|
||||||
|
StandardColor,
|
||||||
|
};
|
||||||
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
||||||
|
use bevy_render::color::Color as LegacyColor;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Color in Oklaba color space, with alpha
|
/// Color in Oklaba color space, with alpha
|
||||||
|
@ -16,6 +20,8 @@ pub struct Oklaba {
|
||||||
pub alpha: f32,
|
pub alpha: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StandardColor for Oklaba {}
|
||||||
|
|
||||||
impl Oklaba {
|
impl Oklaba {
|
||||||
/// Construct a new [`Oklaba`] color from components.
|
/// Construct a new [`Oklaba`] color from components.
|
||||||
///
|
///
|
||||||
|
@ -132,6 +138,30 @@ impl From<Srgba> for Oklaba {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Lcha> for Oklaba {
|
||||||
|
fn from(value: Lcha) -> Self {
|
||||||
|
LinearRgba::from(value).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Hsla> for Oklaba {
|
||||||
|
fn from(value: Hsla) -> Self {
|
||||||
|
LinearRgba::from(value).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<LegacyColor> for Oklaba {
|
||||||
|
fn from(value: LegacyColor) -> Self {
|
||||||
|
LinearRgba::from(value).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Oklaba> for LegacyColor {
|
||||||
|
fn from(value: Oklaba) -> Self {
|
||||||
|
LinearRgba::from(value).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::color_difference::EuclideanDistance;
|
use crate::color_difference::EuclideanDistance;
|
||||||
use crate::oklaba::Oklaba;
|
use crate::oklaba::Oklaba;
|
||||||
use crate::{Alpha, Hsla, LinearRgba, Luminance, Mix};
|
use crate::{Alpha, Hsla, LinearRgba, Luminance, Mix, StandardColor};
|
||||||
use bevy_math::Vec4;
|
use bevy_math::Vec4;
|
||||||
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
|
||||||
use bevy_render::color::{HexColorError, HslRepresentation, SrgbColorSpace};
|
use bevy_render::color::{HexColorError, HslRepresentation, SrgbColorSpace};
|
||||||
|
@ -20,6 +20,8 @@ pub struct Srgba {
|
||||||
pub alpha: f32,
|
pub alpha: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StandardColor for Srgba {}
|
||||||
|
|
||||||
impl Srgba {
|
impl Srgba {
|
||||||
// The standard VGA colors, with alpha set to 1.0.
|
// The standard VGA colors, with alpha set to 1.0.
|
||||||
// https://en.wikipedia.org/wiki/Web_colors#Basic_colors
|
// https://en.wikipedia.org/wiki/Web_colors#Basic_colors
|
||||||
|
|
Loading…
Add table
Reference in a new issue