use std::time::Instant;
use crate::scrin::Color;
pub struct Aisling {
started: Instant,
}
impl Aisling {
pub fn new() -> Self {
Self {
started: Instant::now(),
}
}
pub fn phase(&self, speed: f32, offset: f32) -> f32 {
let t = self.started.elapsed().as_secs_f32() * speed + offset;
(t.sin() + 1.0) * 0.5
}
pub fn tick(&self, rate: f32, modulo: usize) -> usize {
if modulo == 0 {
return 0;
}
((self.started.elapsed().as_secs_f32() * rate) as usize) % modulo
}
pub fn loader(&self, index: usize) -> Color {
let p = self.phase(4.5, index as f32 * 0.55);
blend(rgb(6, 182, 212), rgb(168, 85, 247), p)
}
pub fn title(&self, index: usize) -> Color {
let p = self.phase(2.3, index as f32 * 0.65);
blend(rgb(58, 189, 248), rgb(217, 70, 239), p)
}
pub fn accent(&self) -> Color {
let p = self.phase(1.7, 0.0);
blend(rgb(45, 212, 191), rgb(125, 92, 255), p)
}
pub fn selected_bg(&self) -> Color {
let p = self.phase(3.0, 1.0);
blend(rgb(31, 41, 55), rgb(49, 46, 129), p)
}
pub fn spotlight_bg(&self) -> Color {
let p = self.phase(1.2, 0.4);
blend(rgb(12, 20, 35), rgb(19, 28, 64), p)
}
pub fn matrix(&self, index: usize) -> Color {
let p = self.phase(2.8, index as f32 * 0.37);
blend(rgb(20, 184, 166), rgb(34, 197, 94), p)
}
pub fn glitch(&self, index: usize) -> Color {
let p = self.phase(9.0, index as f32 * 1.9);
blend(rgb(34, 211, 238), rgb(244, 114, 182), p)
}
pub fn burn(value: f32) -> Color {
let value = value.clamp(0.0, 1.0);
blend(rgb(251, 146, 60), rgb(239, 68, 68), value)
}
pub fn heat(value: f32) -> Color {
let value = value.clamp(0.0, 1.0);
if value < 0.50 {
blend(rgb(52, 211, 153), rgb(250, 204, 21), value / 0.50)
} else {
blend(rgb(250, 204, 21), rgb(248, 113, 113), (value - 0.50) / 0.50)
}
}
pub fn memory(value: f32) -> Color {
let value = value.clamp(0.0, 1.0);
blend(rgb(96, 165, 250), rgb(244, 114, 182), value)
}
pub fn dim() -> Color {
rgb(75, 85, 99)
}
pub fn soft() -> Color {
rgb(148, 163, 184)
}
pub fn ok() -> Color {
rgb(52, 211, 153)
}
pub fn warn() -> Color {
rgb(251, 191, 36)
}
pub fn danger() -> Color {
rgb(248, 113, 113)
}
}
fn rgb(r: u8, g: u8, b: u8) -> Color {
Color::Rgb { r, g, b }
}
fn blend(a: Color, b: Color, amount: f32) -> Color {
let amount = amount.clamp(0.0, 1.0);
match (a, b) {
(
Color::Rgb {
r: ar,
g: ag,
b: ab,
},
Color::Rgb {
r: br,
g: bg,
b: bb,
},
) => Color::Rgb {
r: lerp(ar, br, amount),
g: lerp(ag, bg, amount),
b: lerp(ab, bb, amount),
},
_ => a,
}
}
fn lerp(a: u8, b: u8, amount: f32) -> u8 {
(a as f32 + (b as f32 - a as f32) * amount).round() as u8
}