1use anyhow::{anyhow, Result};
2use ratatui::style::Color;
3
4use crate::config::{ColorG, MAX_GRADIENT_NORMAL};
5
6#[derive(Debug, Clone, Copy)]
13pub struct Gradient {
14 start: ColorG,
15 end: ColorG,
16 step_ratio: f32,
17 len: usize,
18}
19
20impl Gradient {
21 pub fn new(start: ColorG, end: ColorG, len: usize) -> Self {
22 let step_ratio = 1_f32 / len as f32;
23 Self {
24 start,
25 end,
26 step_ratio,
27 len,
28 }
29 }
30
31 fn step(&self, step: usize) -> ColorG {
32 let position = self.step_ratio * step as f32;
33
34 let r = self.start.r as f32 + (self.end.r as f32 - self.start.r as f32) * position;
35 let g = self.start.g as f32 + (self.end.g as f32 - self.start.g as f32) * position;
36 let b = self.start.b as f32 + (self.end.b as f32 - self.start.b as f32) * position;
37
38 ColorG {
39 r: r.round() as u8,
40 g: g.round() as u8,
41 b: b.round() as u8,
42 }
43 }
44
45 pub fn as_array(&self) -> Result<[Color; MAX_GRADIENT_NORMAL]> {
46 self.gradient()
47 .collect::<Vec<Color>>()
48 .try_into()
49 .map_err(|_| anyhow!("Couldn't create an array for gradient"))
50 }
51
52 pub fn gradient(&self) -> impl Iterator<Item = Color> + '_ {
53 (0..self.len).map(|step| self.step(step).as_ratatui())
54 }
55}