progress_bar/
progress_bar.rs

1//! Example demonstrating a colored progress bar with gradient color change
2
3use inksac::prelude::*;
4use std::{io::Write, thread, time::Duration};
5
6/// Linear interpolation between two RGB colors
7fn lerp_color(start: (u8, u8, u8), end: (u8, u8, u8), t: f32) -> (u8, u8, u8) {
8    let t = t.clamp(0.0, 1.0);
9    (
10        (start.0 as f32 + (end.0 as f32 - start.0 as f32) * t) as u8,
11        (start.1 as f32 + (end.1 as f32 - start.1 as f32) * t) as u8,
12        (start.2 as f32 + (end.2 as f32 - start.2 as f32) * t) as u8,
13    )
14}
15
16fn main() -> Result<(), Box<dyn std::error::Error>> {
17    let total = 50;
18    // More vibrant and pleasing colors
19    let start_color = (86, 171, 255); // Light blue
20    let mid_color = (255, 135, 255); // Pink/Purple
21    let end_color = (98, 255, 161); // Mint green
22
23    // Styles for different parts of the progress bar
24    let empty_style = Style::builder()
25        .foreground(Color::new_rgb(70, 70, 70)?) // Darker gray for empty section
26        .build();
27
28    let border_style = Style::builder()
29        .foreground(Color::new_rgb(150, 150, 150)?) // Lighter gray for borders
30        .bold()
31        .build();
32
33    let percent_style = Style::builder().foreground(Color::White).bold().build();
34
35    print!("\n"); // Start with a newline for better spacing
36
37    for i in 0..=total {
38        let progress = i as f32 / total as f32;
39        let filled = (progress * 30.0) as usize; // Slightly shorter bar
40        let empty = 30 - filled;
41
42        // Two-stage color interpolation for smoother gradient
43        let (r, g, b) = if progress < 0.5 {
44            lerp_color(start_color, mid_color, progress * 2.0)
45        } else {
46            lerp_color(mid_color, end_color, (progress - 0.5) * 2.0)
47        };
48
49        let bar_style = Style::builder()
50            .foreground(Color::new_rgb(r, g, b)?)
51            .bold()
52            .build();
53
54        // Using better characters for the progress bar
55        print!("\r  "); // Add some left padding
56        print!("{}", "├".style(border_style));
57        print!("{}", "━".repeat(filled).style(bar_style));
58        print!("{}", "─".repeat(empty).style(empty_style));
59        print!("{}", "┤".style(border_style));
60
61        // Percentage with padding to prevent jitter
62        print!(
63            " {}%",
64            format!("{:>3}", (progress * 100.0) as u8).style(percent_style)
65        );
66
67        // Existing spinner for visual feedback
68        let spinner = match i % 10 {
69            0 => "⠋",
70            1 => "⠙",
71            2 => "⠹",
72            3 => "⠸",
73            4 => "⠼",
74            5 => "⠴",
75            6 => "⠦",
76            7 => "⠧",
77            8 => "⠇",
78            9 => "⠏",
79            _ => "",
80        };
81        print!(" {}", spinner.style(bar_style));
82
83        // Added spinning circle indicator on the right
84        let circle_spinner = match i % 4 {
85            0 => "◐",
86            1 => "◓",
87            2 => "◑",
88            3 => "◒",
89            _ => "",
90        };
91        print!(" {}", circle_spinner.style(bar_style));
92
93        std::io::stdout().flush()?;
94        thread::sleep(Duration::from_millis(50));
95    }
96    println!("\n"); // Add final newlines for spacing
97
98    Ok(())
99}