use crate::color::Color;
use palette::{FromColor, Lab, Mix, Srgb};
pub fn gradient_rgb(start: Srgb<u8>, end: Srgb<u8>, count: usize) -> Vec<Color> {
let start_lab = Lab::from_color(start.into_format());
let end_lab = Lab::from_color(end.into_format());
(0..count)
.map(|i| {
let factor = if count > 1 {
i as f32 / (count - 1) as f32
} else {
0.0
};
let blended_lab = start_lab.mix(end_lab, factor);
let blended_rgb = Srgb::from_color(blended_lab).into_format::<u8>();
Color::from(
format!(
"#{:02x}{:02x}{:02x}",
blended_rgb.red, blended_rgb.green, blended_rgb.blue
)
.as_str(),
)
})
.collect()
}
pub fn gradient(start_hex: &str, end_hex: &str, count: usize) -> Vec<Color> {
let start_rgb = parse_hex_color(start_hex);
let end_rgb = parse_hex_color(end_hex);
gradient_rgb(start_rgb, end_rgb, count)
}
pub fn bilinear_interpolation_grid(
x_steps: usize,
y_steps: usize,
corners: (&str, &str, &str, &str),
) -> Vec<Vec<Color>> {
let (top_left, top_right, bottom_left, bottom_right) = corners;
let x0y0 = Lab::from_color(parse_hex_color(top_left).into_format());
let x1y0 = Lab::from_color(parse_hex_color(top_right).into_format());
let x0y1 = Lab::from_color(parse_hex_color(bottom_left).into_format());
let x1y1 = Lab::from_color(parse_hex_color(bottom_right).into_format());
let left_edge: Vec<Lab> = (0..y_steps)
.map(|i| {
let factor = if y_steps > 1 {
i as f32 / (y_steps - 1) as f32
} else {
0.0
};
x0y0.mix(x0y1, factor)
})
.collect();
let right_edge: Vec<Lab> = (0..y_steps)
.map(|i| {
let factor = if y_steps > 1 {
i as f32 / (y_steps - 1) as f32
} else {
0.0
};
x1y0.mix(x1y1, factor)
})
.collect();
(0..y_steps)
.map(|y| {
let start_of_row = left_edge[y];
let end_of_row = right_edge[y];
(0..x_steps)
.map(|x| {
let factor = if x_steps > 1 {
x as f32 / (x_steps - 1) as f32
} else {
0.0
};
let blended_lab = start_of_row.mix(end_of_row, factor);
let blended_rgb = Srgb::from_color(blended_lab).into_format::<u8>();
Color::from(
format!(
"#{:02x}{:02x}{:02x}",
blended_rgb.red, blended_rgb.green, blended_rgb.blue
)
.as_str(),
)
})
.collect()
})
.collect()
}
fn parse_hex_color(hex: &str) -> Srgb<u8> {
let hex = hex.trim_start_matches('#');
let r = u8::from_str_radix(&hex[0..2], 16).unwrap_or(0);
let g = u8::from_str_radix(&hex[2..4], 16).unwrap_or(0);
let b = u8::from_str_radix(&hex[4..6], 16).unwrap_or(0);
Srgb::new(r, g, b)
}