bottomless_pit/
colour.rs

1//! The colour struct module
2
3use encase::ShaderType;
4/// A struct containing RGBA Colours (spelled properly) with some predefind colour consts
5#[derive(Copy, Clone, Debug, PartialEq, ShaderType)]
6pub struct Colour {
7    r: f32,
8    g: f32,
9    b: f32,
10    a: f32,
11}
12
13impl Colour {
14    pub const WHITE: Self = Self {
15        r: 1.0,
16        g: 1.0,
17        b: 1.0,
18        a: 1.0,
19    };
20
21    pub const BLACK: Self = Self {
22        r: 0.0,
23        g: 0.0,
24        b: 0.0,
25        a: 1.0,
26    };
27
28    pub const RED: Self = Self {
29        r: 1.0,
30        g: 0.0,
31        b: 0.0,
32        a: 1.0,
33    };
34
35    pub const GREEN: Self = Self {
36        r: 0.0,
37        g: 1.0,
38        b: 0.0,
39        a: 1.0,
40    };
41
42    pub const BLUE: Self = Self {
43        r: 0.0,
44        g: 0.0,
45        b: 1.0,
46        a: 1.0,
47    };
48
49    pub const YELLOW: Self = Self {
50        r: 1.0,
51        g: 1.0,
52        b: 0.0,
53        a: 1.0,
54    };
55
56    pub const ORANGE: Self = Self {
57        r: 1.0,
58        g: 0.64705884,
59        b: 0.0,
60        a: 1.0,
61    };
62
63    pub const PINK: Self = Self {
64        r: 1.0,
65        g: 0.7529412,
66        b: 0.79607844,
67        a: 1.0,
68    };
69
70    pub const BROWN: Self = Self {
71        r: 0.63529414,
72        g: 0.16470589,
73        b: 0.16470589,
74        a: 1.0,
75    };
76
77    /// Takes a hex string like `#805E4E` and turns into a colour. Can fail if an
78    /// invaild string is provided
79    pub fn from_hex(hex_str: &str) -> Result<Self, std::num::ParseIntError> {
80        let colour_values = i32::from_str_radix(hex_str, 16)?;
81        let b = colour_values % 0x100;
82        let g = (colour_values - b) / 0x100 % 0x100;
83        let r = (colour_values - g) / 0x10000;
84        Ok(Self {
85            r: r as f32 / 255.0,
86            g: g as f32 / 255.0,
87            b: b as f32 / 255.0,
88            a: 1.0,
89        })
90    }
91
92    /// Creates a colour from seperate values beteen 0.0 and 255.0
93    /// and an alpha value of 0 to 1.
94    pub fn from_rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
95        Self {
96            r: r / 255.0,
97            g: g / 255.0,
98            b: b / 255.0,
99            a,
100        }
101    }
102
103    /// Interpolates between two colours by the specified fraction which should be between 1.0
104    /// and 0.0
105    pub fn linear_interpolation(start: Colour, end: Colour, fraction: f32) -> Self {
106        Self {
107            r: (end.r - start.r) * fraction + start.r,
108            g: (end.g - start.g) * fraction + start.g,
109            b: (end.b - start.b) * fraction + start.b,
110            a: (end.a - start.a) * fraction + start.a,
111        }
112    }
113
114    pub(crate) fn as_raw(&self) -> [f32; 4] {
115        [self.r, self.g, self.b, self.a]
116    }
117}
118
119impl From<Colour> for wgpu::Color {
120    fn from(value: Colour) -> Self {
121        wgpu::Color {
122            r: value.r as f64,
123            g: value.g as f64,
124            b: value.b as f64,
125            a: value.a as f64,
126        }
127    }
128}
129
130impl From<Colour> for glyphon::Color {
131    fn from(value: Colour) -> Self {
132        // should work as it is always a number betweeon 1-0
133        let r = (value.r * 255.0) as u8;
134        let g = (value.g * 255.0) as u8;
135        let b = (value.b * 255.0) as u8;
136        let a = (value.a * 255.0) as u8;
137        Self::rgba(r, g, b, a)
138    }
139}
140
141impl From<Colour> for [f32; 4] {
142    fn from(value: Colour) -> Self {
143        [value.r, value.g, value.b, value.a]
144    }
145}