primitives/foundation/colorschemes/
compound.rs

1#![allow(unused_imports)]
2use crate::foundation::colorspace::{Color, HsvColor};
3
4use super::{ryb_rotate, wrap};
5
6/// Compound schemes (aka Split Complementary) are almost the same as complementary schemes.
7///
8/// Instead of using colors that are opposites, it uses colors on both sides of the opposite hue
9pub struct Compound {
10    colors: Vec<Color>,
11    primary_color: Color,
12}
13
14impl Compound {
15    /// Generate Compound scheme with your color
16    pub fn new(primary: Color) -> Self {
17        let mut instance = Self {
18            colors: Vec::new(),
19            primary_color: primary,
20        };
21
22        instance.generate();
23
24        instance
25    }
26
27    fn generate(&mut self) {
28        self.colors = vec![self.primary_color];
29        let primary_hsb: HsvColor = self.primary_color.into();
30
31        // value is brightness
32        let mut c1: HsvColor = ryb_rotate(self.primary_color, 30.0);
33        c1.value = wrap(primary_hsb.value, 25.0, 60.0, 25.0);
34        self.colors.push(c1.into());
35
36        let mut c2: HsvColor = ryb_rotate(self.primary_color, 30.0);
37        c2.value = wrap(primary_hsb.value, 40.0, 10.0, 40.0);
38        c2.saturation = wrap(primary_hsb.saturation, 40.0, 20.0, 40.0);
39        self.colors.push(c2.into());
40
41        let mut c3: HsvColor = ryb_rotate(self.primary_color, 160.0);
42        c3.value = primary_hsb.value.max(20.0);
43        c3.saturation = wrap(primary_hsb.saturation, 25.0, 10.0, 25.0);
44        self.colors.push(c3.into());
45
46        let mut c4: HsvColor = ryb_rotate(self.primary_color, 150.0);
47        c4.value = wrap(primary_hsb.value, 30.0, 60.0, 30.0);
48        c4.saturation = wrap(primary_hsb.saturation, 10.0, 80.0, 10.0);
49        self.colors.push(c4.into());
50
51        let mut c5: HsvColor = ryb_rotate(self.primary_color, 150.0);
52        c5.value = wrap(primary_hsb.value, 40.0, 20.0, 40.0);
53        c5.saturation = wrap(primary_hsb.saturation, 10.0, 80.0, 10.0);
54        self.colors.push(c5.into());
55    }
56
57    /// Retrieve count colors of scheme
58    pub fn num_of_colors(&self) -> usize {
59        self.colors.len()
60    }
61
62    /// Set color by index
63    pub fn get_color(&self, index: usize) -> Option<Color> {
64        self.colors.get(index).copied()
65    }
66
67    /// Retrieve primary color of scheme
68    pub fn primary_color(&self) -> Color {
69        self.primary_color
70    }
71
72    /// Set the primary color of scheme
73    pub fn set_primary_color(&mut self, val: Color) {
74        self.primary_color = val;
75        self.generate();
76    }
77}