bevy_color/
color_range.rs

1use core::ops::Range;
2
3use crate::Mix;
4
5/// Represents a range of colors that can be linearly interpolated, defined by a start and
6/// end point which must be in the same color space. It works for any color type that
7/// implements [`Mix`].
8///
9/// This is useful for defining gradients or animated color transitions.
10pub trait ColorRange<T: Mix> {
11    /// Get the color value at the given interpolation factor, which should be between 0.0 (start)
12    /// and 1.0 (end).
13    fn at(&self, factor: f32) -> T;
14}
15
16impl<T: Mix> ColorRange<T> for Range<T> {
17    fn at(&self, factor: f32) -> T {
18        self.start.mix(&self.end, factor.clamp(0.0, 1.0))
19    }
20}
21
22#[cfg(test)]
23mod tests {
24    use super::*;
25    use crate::{palettes::basic, LinearRgba, Srgba};
26
27    #[test]
28    fn test_color_range() {
29        let range = basic::RED..basic::BLUE;
30        assert_eq!(range.at(-0.5), basic::RED);
31        assert_eq!(range.at(0.0), basic::RED);
32        assert_eq!(range.at(0.5), Srgba::new(0.5, 0.0, 0.5, 1.0));
33        assert_eq!(range.at(1.0), basic::BLUE);
34        assert_eq!(range.at(1.5), basic::BLUE);
35
36        let lred: LinearRgba = basic::RED.into();
37        let lblue: LinearRgba = basic::BLUE.into();
38
39        let range = lred..lblue;
40        assert_eq!(range.at(-0.5), lred);
41        assert_eq!(range.at(0.0), lred);
42        assert_eq!(range.at(0.5), LinearRgba::new(0.5, 0.0, 0.5, 1.0));
43        assert_eq!(range.at(1.0), lblue);
44        assert_eq!(range.at(1.5), lblue);
45    }
46}