Skip to main content

ptsd/
color.rs

1use prism::canvas;
2
3#[derive(Copy, Clone, Debug, PartialEq)]
4pub struct Color(canvas::Color);
5
6impl Default for Color {
7    fn default() -> Color {Color::from_hex("#fa00d5", 255)}
8}
9
10impl Color {
11    pub const WHITE: Color = Color(canvas::Color(255, 255, 255, 255));
12    pub const BLACK: Color = Color(canvas::Color(0, 0, 0, 255));
13    pub const TRANSPARENT: Color = Color(canvas::Color(0, 0, 0, 0));
14
15    pub fn from_hex(color: &str, alpha: u8) -> Self {
16        let ce = "Color was not a Hex Value";
17        let c = hex::decode(color.strip_prefix('#').unwrap_or(color)).expect(ce);
18        Color(canvas::Color(c[0], c[1], c[2], alpha))
19    }
20
21    pub fn darken(&self, factor: f32) -> Color {
22        let c: canvas::Color = (*self).into();
23        Color(canvas::Color((c.0 as f32 * (factor * 1.3)) as u8, (c.1 as f32 * (factor * 1.1)) as u8, (c.2 as f32 * factor) as u8, c.3))
24    }
25
26    pub fn is_high_contrast(&self) -> bool {
27        let c: canvas::Color = (*self).into();
28        0.299*(c.0 as f32) + 0.587*(c.1 as f32) + 0.114*(c.2 as f32) > 128.0
29    }
30
31    pub fn contrasted(&self) -> Color {
32        let canvas::Color(r, g, b, _) = self.0;
33        let r = r as f64 / 255.0;
34        let g = g as f64 / 255.0;
35        let b = b as f64 / 255.0;
36
37        let luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
38        let saturation = r.max(g.max(b)) - r.min(g.min(b));
39
40        match luminance < 0.6 || (luminance < 0.75 && saturation > 0.25) {
41            true => Color::WHITE,
42            false => Color::BLACK
43        }
44    }
45
46    pub fn from_canvas(color: canvas::Color) -> Self {
47        Color(color)
48    }
49}
50
51impl From<Color> for canvas::Color {
52    fn from(val: Color) -> Self {
53        val.0
54    }
55}