optic_color/rgb.rs
1use crate::RGBA;
2
3/// RGB color with three 0..1 float channels.
4///
5/// This is a tuple struct with public fields:
6///
7/// | Field | Range | Description |
8/// |-------|--------|--------------|
9/// | `.0` | 0..1 | Red channel |
10/// | `.1` | 0..1 | Green channel |
11/// | `.2` | 0..1 | Blue channel |
12///
13/// # Arithmetic
14///
15/// `RGB` implements [`Add`], [`Sub`], [`Mul`] (componentwise), [`Mul<f32>`],
16/// and [`Div<f32>`] via the [`ChannelArray<3>`] impl. These operate on all
17/// three channels independently.
18///
19/// # Conversions
20///
21/// ```
22/// use optic_color::*;
23///
24/// let rgb = RGB(0.5, 0.2, 0.8);
25/// let rgba: RGBA = rgb.into(); // alpha = 1.0
26/// let rgba = rgb.to_rgba(0.5); // custom alpha
27/// let arr: [f32; 3] = rgb.into(); // flatten
28/// ```
29///
30/// See also [`RGBA`], [`HSV`], [`HSL`].
31#[derive(Copy, Clone, Debug)]
32pub struct RGB(pub f32, pub f32, pub f32);
33
34impl RGB {
35 /// Construct a greyscale RGB.
36 ///
37 /// All three channels are set to `lum`.
38 ///
39 /// ```
40 /// use optic_color::*;
41 ///
42 /// let grey = RGB::grey(0.5);
43 /// assert_eq!(grey.0, 0.5);
44 /// assert_eq!(grey.1, 0.5);
45 /// assert_eq!(grey.2, 0.5);
46 /// ```
47 pub fn grey(lum: f32) -> Self { RGB(lum, lum, lum) }
48
49 /// Construct an RGB from an RGBA, dropping alpha.
50 pub fn from_rgba(rgba: RGBA) -> Self { RGB(rgba.0, rgba.1, rgba.2) }
51
52 /// Convert to RGBA with a given alpha.
53 ///
54 /// ```
55 /// use optic_color::*;
56 ///
57 /// let rgb = RGB(1.0, 0.0, 0.0);
58 /// let rgba = rgb.to_rgba(0.5);
59 /// assert_eq!(rgba.3, 0.5);
60 /// ```
61 pub fn to_rgba(&self, alpha: f32) -> RGBA { RGBA(self.0, self.1, self.2, alpha) }
62}