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}