pub mod default_palettes; pub mod parser; #[cfg(feature = "wasm")] mod wasm; pub use ordered_float::OrderedFloat; #[derive(Copy, Clone, Debug, PartialEq)] #[cfg_attr(feature = "wasm", derive(::serde::Serialize))] pub struct Color { pub red: u8, pub green: u8, pub blue: u8, pub alpha: u8, } pub type Palette = Vec<((OrderedFloat, OrderedFloat), (Color, Color))>; #[macro_export] macro_rules! c { ($r:expr,$g:expr,$b:expr) => { $crate::Color { red: $r, green: $g, blue: $b, alpha: 255, } }; ($r:expr,$g:expr,$b:expr,$a:expr) => { $crate::Color { red: $r, green: $g, blue: $b, alpha: $a, } }; } #[macro_export] macro_rules! r { ($f:expr,$t:expr) => { ($crate::OrderedFloat($f), $crate::OrderedFloat($t)) }; } pub trait ColorPalette { fn colorize(&self, at: f64) -> Color; } impl ColorPalette for Palette { fn colorize(&self, at: f64) -> Color { for (raw_range, color_range) in self { let range = *raw_range.0..*raw_range.1; if range.contains(&at) { let mapped_end = *raw_range.1 - *raw_range.0; let mapped_point = at - *raw_range.0; let t = mapped_point / mapped_end; let color_start = color_range.0; let color_end = color_range.1; return lerp_color(color_start, color_end, t); } } Color { red: 0, green: 0, blue: 0, alpha: 0, } } } fn lerp(p0: f64, p1: f64, t: f64) -> f64 { p0 + t * (p1 - p0) } fn lerp_color(c0: Color, c1: Color, t: f64) -> Color { Color { red: lerp(c0.red as f64, c1.red as f64, t) as u8, green: lerp(c0.green as f64, c1.green as f64, t) as u8, blue: lerp(c0.blue as f64, c1.blue as f64, t) as u8, alpha: lerp(c0.alpha as f64, c1.alpha as f64, t) as u8, } }