color_gradient/blenders/hsv/
mod.rs

1use crate::Interpolator;
2use color_core::HSVA32;
3use std::ops::Range;
4mod builtin;
5
6/// A color interpolator that interpolates between colors in the [HSV Color Space](https://en.wikipedia.org/wiki/HSL_and_HSV).
7#[derive(Clone, Debug)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct HsvGradient {
10    hue: Interpolator,
11    saturation: Interpolator,
12    brightness: Interpolator,
13    alpha: Interpolator,
14    range: Range<f32>,
15}
16
17impl HsvGradient {
18    /// Creates a new gradient sampler with the given min and max values.
19    ///
20    /// # Examples
21    ///
22    /// ```
23    /// # use color_core::HSVA32;
24    /// # use color_gradient::{HsvGradient};
25    /// let mut gradient = HsvGradient::default();
26    /// assert_eq!(gradient.get_linear(0.5), HSVA32::new(180.0, 100.0, 100.0, 100.0));
27    /// ```
28    pub fn new(min: f32, max: f32) -> Self {
29        debug_assert!(max > min, "max must be greater than min");
30        Self {
31            hue: Interpolator::new(0.0, 360.0),
32            saturation: Interpolator::new(100.0, 100.0),
33            brightness: Interpolator::new(100.0, 100.0),
34            alpha: Interpolator::new(100.0, 100.0),
35            range: Range { start: min, end: max },
36        }
37    }
38    /// Rescales the gradient to the given min and max values.
39    ///
40    /// # Examples
41    ///
42    /// ```
43    /// # use color_core::HSVA32;
44    /// # use color_gradient::{HsvGradient};
45    /// let mut gradient = HsvGradient::default();
46    /// gradient.rescale(0.0, 360.0);
47    /// assert_eq!(gradient.get_linear(180.0), HSVA32::new(180.0, 100.0, 100.0, 100.0));
48    /// ```
49    pub fn rescale(&mut self, min: f32, max: f32) {
50        debug_assert!(max > min, "max must be greater than min");
51        self.range = Range { start: min, end: max };
52    }
53    /// Creates a new HSVGradient with the given min and max values.
54    ///
55    /// # Arguments
56    ///
57    /// * `min`:
58    /// * `max`:
59    ///
60    /// returns: HSVGradient
61    ///
62    /// # Examples
63    ///
64    /// ```
65    /// # use color_gradient;
66    /// ```
67    pub fn insert_color<HSV>(&mut self, key: f32, color: HSV)
68    where
69        HSV: Into<HSVA32>,
70    {
71        let hsva = color.into();
72        let ratio = self.get_ratio(key);
73        self.hue.insert(ratio, hsva.h);
74        self.saturation.insert(ratio, hsva.s);
75        self.brightness.insert(ratio, hsva.v);
76        self.alpha.insert(ratio, hsva.a);
77    }
78    /// Creates a new HSVGradient with the given min and max values.
79    ///
80    /// # Arguments
81    ///
82    /// * `min`:
83    /// * `max`:
84    ///
85    /// returns: HSVGradient
86    ///
87    /// # Examples
88    ///
89    /// ```
90    /// # use color_gradient;
91    /// ```
92    pub fn remove_color(&mut self, key: f32) {
93        let ratio = self.get_ratio(key);
94        self.hue.remove(ratio);
95        self.saturation.remove(ratio);
96        self.brightness.remove(ratio);
97        self.alpha.remove(ratio);
98    }
99    /// Creates a new HSVGradient with the given min and max values.
100    ///
101    /// # Arguments
102    ///
103    /// * `min`:
104    /// * `max`:
105    ///
106    /// returns: HSVGradient
107    ///
108    /// # Examples
109    ///
110    /// ```
111    /// # use color_gradient;
112    /// ```
113    pub fn insert_hue(&mut self, key: f32, value: f32) {
114        let ratio = self.get_ratio(key);
115        self.hue.insert(ratio, value);
116    }
117    /// Creates a new HSVGradient with the given min and max values.
118    ///
119    /// # Arguments
120    ///
121    /// * `min`:
122    /// * `max`:
123    ///
124    /// returns: HSVGradient
125    ///
126    /// # Examples
127    ///
128    /// ```
129    /// # use color_gradient;
130    /// ```
131    pub fn remove_hue(&mut self, key: f32) {
132        let ratio = self.get_ratio(key);
133        self.hue.remove(ratio);
134    }
135    /// Creates a new HSVGradient with the given min and max values.
136    ///
137    /// # Arguments
138    ///
139    /// * `min`:
140    /// * `max`:
141    ///
142    /// returns: HSVGradient
143    ///
144    /// # Examples
145    ///
146    /// ```
147    /// # use color_gradient;
148    /// ```
149    pub fn insert_saturation(&mut self, key: f32, value: f32) {
150        let ratio = self.get_ratio(key);
151        self.saturation.insert(ratio, value);
152    }
153    /// Creates a new HSVGradient with the given min and max values.
154    ///
155    /// # Arguments
156    ///
157    /// * `min`:
158    /// * `max`:
159    ///
160    /// returns: HSVGradient
161    ///
162    /// # Examples
163    ///
164    /// ```
165    /// # use color_gradient;
166    /// ```
167    pub fn remove_saturation(&mut self, key: f32) {
168        let ratio = self.get_ratio(key);
169        self.saturation.remove(ratio);
170    }
171    /// Creates a new HSVGradient with the given min and max values.
172    ///
173    /// # Arguments
174    ///
175    /// * `min`:
176    /// * `max`:
177    ///
178    /// returns: HSVGradient
179    ///
180    /// # Examples
181    ///
182    /// ```
183    /// # use color_gradient;
184    /// ```
185    pub fn insert_brightness(&mut self, key: f32, value: f32) {
186        let ratio = self.get_ratio(key);
187        self.brightness.insert(ratio, value);
188    }
189    /// Creates a new HSVGradient with the given min and max values.
190    ///
191    /// # Arguments
192    ///
193    /// * `min`:
194    /// * `max`:
195    ///
196    /// returns: HSVGradient
197    ///
198    /// # Examples
199    ///
200    /// ```
201    /// # use color_gradient;
202    /// ```
203    pub fn remove_brightness(&mut self, key: f32) {
204        let ratio = self.get_ratio(key);
205        self.brightness.remove(ratio);
206    }
207    /// Insert a new alpha control point at the given key.
208    ///
209    /// # Examples
210    ///
211    /// ```
212    /// # use color_core::HSVA32;
213    /// # use color_gradient::HsvGradient;
214    /// let mut gradient = HsvGradient::default();
215    /// assert_eq!(gradient.get_linear(0.5), HSVA32::new(180.0, 100.0, 100.0, 100.0));
216    /// gradient.insert_alpha(0.1, 50.0);
217    /// assert_eq!(gradient.get_linear(0.5), HSVA32::new(180.0, 100.0, 100.0, 72.22203));
218    /// ```
219    pub fn insert_alpha(&mut self, key: f32, value: f32) {
220        let ratio = self.get_ratio(key);
221        self.alpha.insert(ratio, value);
222    }
223    /// Remove the alpha control point at the given key.
224    ///
225    /// # Examples
226    ///
227    /// ```
228    /// # use color_core::HSVA32;
229    /// # use color_gradient::HsvGradient;
230    /// let mut gradient = HsvGradient::default();
231    /// gradient.insert_alpha(0.1, 50.0);
232    /// assert_eq!(gradient.get_linear(0.5), HSVA32::new(180.0, 100.0, 100.0, 72.22203));
233    /// gradient.remove_alpha(0.1);
234    /// assert_eq!(gradient.get_linear(0.5), HSVA32::new(180.0, 100.0, 100.0, 100.0));
235    /// ```
236    pub fn remove_alpha(&mut self, key: f32) {
237        let ratio = self.get_ratio(key);
238        self.alpha.remove(ratio);
239    }
240    /// Clears all alpha control points from the gradient.
241    ///
242    /// # Examples
243    ///
244    /// ```
245    /// # use color_gradient::HsvGradient;
246    /// let mut gradient = HsvGradient::default();
247    /// gradient.insert_alpha(0.0, 0.0);
248    /// gradient.insert_alpha(1.0, 1.0);
249    /// gradient.clear_alpha();
250    /// ```
251    pub fn clear_alpha(&mut self) {
252        self.alpha.clear();
253    }
254}
255
256impl HsvGradient {
257    fn get_ratio(&self, value: f32) -> u16 {
258        Interpolator::get_ratio(&self.range, value)
259    }
260    /// Creates a new HSVGradient with the given min and max values.
261    ///
262    /// # Arguments
263    ///
264    /// * `min`:
265    /// * `max`:
266    ///
267    /// returns: HSVGradient
268    ///
269    /// # Examples
270    ///
271    /// ```
272    /// # use color_gradient;
273    /// ```
274    pub fn get_step(&self, value: f32) -> HSVA32 {
275        let ratio = self.get_ratio(value);
276        HSVA32 {
277            h: self.hue.get_step(ratio),
278            s: self.saturation.get_step(ratio),
279            v: self.brightness.get_step(ratio),
280            a: self.alpha.get_step(ratio),
281        }
282    }
283    /// Creates a new HSVGradient with the given min and max values.
284    ///
285    /// # Arguments
286    ///
287    /// * `min`:
288    /// * `max`:
289    ///
290    /// returns: HSVGradient
291    ///
292    /// # Examples
293    ///
294    /// ```
295    /// # use color_gradient;
296    /// ```
297    pub fn get_linear(&self, value: f32) -> HSVA32 {
298        let ratio = self.get_ratio(value);
299        HSVA32 {
300            h: self.hue.get_linear(ratio),
301            s: self.saturation.get_linear(ratio),
302            v: self.brightness.get_linear(ratio),
303            a: self.alpha.get_linear(ratio),
304        }
305    }
306}