1use crate::{rgb::Rgb, Color};
2
3/// Linear color gradient between two color stops
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct Gradient {
6 /// Start Color of Gradient
7 pub start: Rgb,
8
9 /// End Color of Gradient
10 pub end: Rgb,
11}
12
13impl Gradient {
14 /// Creates a new [Gradient] with two [Rgb] colors, `start` and `end`
15 #[inline]
16 pub const fn new(start: Rgb, end: Rgb) -> Self {
17 Self { start, end }
18 }
19
20 pub const fn from_color_rgb(start: Color, end: Color) -> Self {
21 let start_grad = match start {
22 Color::Rgb(r, g, b) => Rgb { r, g, b },
23 _ => Rgb { r: 0, g: 0, b: 0 },
24 };
25 let end_grad = match end {
26 Color::Rgb(r, g, b) => Rgb { r, g, b },
27 _ => Rgb { r: 0, g: 0, b: 0 },
28 };
29
30 Self {
31 start: start_grad,
32 end: end_grad,
33 }
34 }
35
36 /// Computes the [Rgb] color between `start` and `end` for `t`
37 pub fn at(&self, t: f32) -> Rgb {
38 self.start.lerp(self.end, t)
39 }
40
41 /// Returns the reverse of `self`
42 #[inline]
43 pub const fn reverse(&self) -> Self {
44 Self::new(self.end, self.start)
45 }
46
47 pub fn build(&self, text: &str, target: TargetGround) -> String {
48 let delta = 1.0 / text.len() as f32;
49 let mut result = text.char_indices().fold(String::new(), |mut acc, (i, c)| {
50 let temp = format!(
51 "\x1B[{}m{}",
52 self.at(i as f32 * delta).ansi_color_code(target),
53 c
54 );
55 acc.push_str(&temp);
56 acc
57 });
58
59 result.push_str("\x1B[0m");
60 result
61 }
62}
63
64pub fn build_all_gradient_text(text: &str, foreground: Gradient, background: Gradient) -> String {
65 let delta: f32 = 1.0 / text.len() as f32;
66 let mut result: String = text.char_indices().fold(init:String::new(), |mut acc: String, (i: usize, c: char)| {
67 let step: f32 = i as f32 * delta;
68 let temp: String = format!(
69 "\x1B[{};{}m{}",
70 foreground
71 .at(step)
72 .ansi_color_code(TargetGround::Foreground),
73 background
74 .at(step)
75 .ansi_color_code(TargetGround::Background),
76 c
77 );
78 acc.push_str(&temp);
79 acc
80 });
81
82 result.push_str(string:"\x1B[0m");
83 result
84}
85
86#[derive(Debug, Clone, Copy, PartialEq, Eq)]
87pub enum TargetGround {
88 Foreground,
89 Background,
90}
91
92impl TargetGround {
93 #[inline]
94 pub const fn code(&self) -> u8 {
95 match self {
96 Self::Foreground => 30,
97 Self::Background => 40,
98 }
99 }
100}
101
102pub trait ANSIColorCode {
103 fn ansi_color_code(&self, target: TargetGround) -> String;
104}
105

Provided by KDAB

Privacy Policy
Learn Rust with the experts
Find out more