use palette::{IntoColor, Lch, Hsl, FromColor, Oklch};
pub enum GradientMethod {
LCH,
HSL,
OKLCH,
}
pub trait IntoGradientLch: Sized + IntoColor<Lch> + FromColor<Lch> + Copy {
fn build_gradient_lch(self, shades: u16) -> Vec<Self> {
let step_size = 100.0 / (shades+1) as f32;
(1..shades)
.into_iter()
.map(|i| {
let mut color: Lch = self.into_color();
color.l = i as f32 * step_size;
Self::from_color(color)
})
.collect()
}
}
pub trait IntoGradientHsl: Sized + IntoColor<Hsl> + FromColor<Hsl> + Copy {
fn build_gradient_hsl(self, shades: u16) -> Vec<Self> {
let step_size = 1.0 / (shades+1) as f32;
(1..shades)
.into_iter()
.map(|i| {
let mut color: Hsl = self.into_color();
color.lightness = i as f32 * step_size;
Self::from_color(color)
})
.collect()
}
}
pub trait IntoGradientOklch: Sized + IntoColor<Oklch> + FromColor<Oklch> + Copy {
fn build_gradient_oklch(self, shades: u16) -> Vec<Self> {
let step_size = 1.0 / (shades+1) as f32;
(1..shades)
.into_iter()
.map(|i| {
let mut color: Oklch = self.into_color();
color.l = i as f32 * step_size;
Self::from_color(color)
})
.collect()
}
}
pub trait IntoGradient: IntoGradientHsl + IntoGradientLch + IntoGradientOklch {
fn build_gradient(self, shades: u16, method: GradientMethod) -> Vec<Self> {
match method {
GradientMethod::HSL => self.build_gradient_hsl(shades),
GradientMethod::LCH => self.build_gradient_lch(shades),
GradientMethod::OKLCH => self.build_gradient_oklch(shades),
}
}
}
impl<C> IntoGradientHsl for C where
C: Sized + IntoColor<Hsl> + FromColor<Hsl> + Copy {}
impl<C> IntoGradientLch for C where
C: Sized + IntoColor<Lch> + FromColor<Lch> + Copy {}
impl<C> IntoGradientOklch for C where
C: Sized + IntoColor<Oklch> + FromColor<Oklch> + Copy {}
impl<C> IntoGradient for C where
C: IntoGradientHsl + IntoGradientLch + IntoGradientOklch {}