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 let f = |ch: u8| (ch as f32 * factor) as u8;
24 Color(canvas::Color(f(c.0), f(c.1), f(c.2), c.3))
25 }
26
27 pub fn is_high_contrast(&self) -> bool {
28 let c: canvas::Color = (*self).into();
29 0.299*(c.0 as f32) + 0.587*(c.1 as f32) + 0.114*(c.2 as f32) > 128.0
30 }
31
32 pub fn contrasted(&self) -> Color {
33 let canvas::Color(r, g, b, _) = self.0;
34 let r = r as f64 / 255.0;
35 let g = g as f64 / 255.0;
36 let b = b as f64 / 255.0;
37
38 let luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
39 let saturation = r.max(g.max(b)) - r.min(g.min(b));
40
41 match luminance < 0.6 || (luminance < 0.75 && saturation > 0.25) {
42 true => Color::WHITE,
43 false => Color::BLACK
44 }
45 }
46
47 pub fn from_canvas(color: canvas::Color) -> Self {
48 Color(color)
49 }
50}
51
52impl From<Color> for canvas::Color {
53 fn from(val: Color) -> Self {
54 val.0
55 }
56}