use crate::{ANSIColorCode, TargetGround, RGB};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Gradient {
pub start: RGB,
pub end: RGB,
}
impl Gradient {
#[inline]
pub const fn new(start: RGB, end: RGB) -> Self {
Self { start, end }
}
pub fn at(&self, t: f32) -> RGB {
self.start.lerp(self.end, t)
}
#[inline]
pub const fn reverse(&self) -> Self {
Self::new(self.end, self.start)
}
pub(crate) fn build(&self, text: &str, target: TargetGround) -> String {
let delta = 1.0 / text.len() as f32;
let mut result = text.char_indices().fold(String::new(), |mut acc, (i, c)| {
let temp = format!(
"\x1B[{}m{}",
self.at(i as f32 * delta).ansi_color_code(target),
c
);
acc.push_str(&temp);
acc
});
result.push_str("\x1B[0m");
result
}
}
pub(crate) fn build_all_gradient_text(
text: &str,
foreground: Gradient,
background: Gradient,
) -> String {
let delta = 1.0 / text.len() as f32;
let mut result = text.char_indices().fold(String::new(), |mut acc, (i, c)| {
let step = i as f32 * delta;
let temp = format!(
"\x1B[{};{}m{}",
foreground
.at(step)
.ansi_color_code(TargetGround::Foreground),
background
.at(step)
.ansi_color_code(TargetGround::Background),
c
);
acc.push_str(&temp);
acc
});
result.push_str("\x1B[0m");
result
}