116 lines
4.3 KiB
Rust
116 lines
4.3 KiB
Rust
//! Color palate generator.
|
|
|
|
use crate::RandomExt;
|
|
use palette::rgb::Rgb;
|
|
use palette::FromColor;
|
|
use palette::Hsl;
|
|
use palette::Hsv;
|
|
use palette::IntoColor;
|
|
use rand::prelude::*;
|
|
|
|
/// The palette that is used
|
|
/// to generate the image.
|
|
pub struct Palette {
|
|
pub background_color: Rgb,
|
|
pub fill_color: Rgb,
|
|
}
|
|
|
|
impl Palette {
|
|
/// generate a random color that is not to dark
|
|
/// and to color less.
|
|
#[allow(dead_code)]
|
|
pub fn random_color(mut rng: StdRng) -> Rgb {
|
|
let hue: f32 = rng.gen_interval(0., 360.);
|
|
let saturation: f32 = rng.gen_interval(0.9, 1.0);
|
|
let value: f32 = rng.gen_interval(0.8, 1.0);
|
|
Palette::color(hue, saturation, value)
|
|
}
|
|
|
|
pub fn color(hue: f32, saturation: f32, value: f32) -> Rgb {
|
|
Rgb::from_linear(Hsv::new(hue, saturation, value).into_rgb())
|
|
}
|
|
|
|
/// generate a palette from the tint and shade palette
|
|
/// algorithm. choose a dark background, and a bright filling color
|
|
pub fn bright_on_dark(input: Rgb) -> Palette {
|
|
let tint_and_shade_palette = TintAndShadePalette::create(input);
|
|
Palette {
|
|
background_color: tint_and_shade_palette.base_shade_30,
|
|
fill_color: tint_and_shade_palette.inverse_saturation_tint_30,
|
|
}
|
|
}
|
|
|
|
/// generate a palette from the tint and shade palette
|
|
/// algorithm. choose a bright background, and a dark filling color
|
|
pub fn dark_on_bright(input: Rgb) -> Palette {
|
|
let tint_and_shade_palette = TintAndShadePalette::create(input);
|
|
Palette {
|
|
background_color: tint_and_shade_palette.base_tint_30,
|
|
fill_color: tint_and_shade_palette.inverse_saturation_shade_30,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// The Tint and Shade Palette from https://gitlab.com/cameralibre/tint-and-shade
|
|
/// Thank you, Sam
|
|
struct TintAndShadePalette {
|
|
base_color: Rgb,
|
|
base_tint_30: Rgb,
|
|
base_tint_15: Rgb,
|
|
base_shade_15: Rgb,
|
|
base_shade_30: Rgb,
|
|
complement_tint_30: Rgb,
|
|
complement_tint_15: Rgb,
|
|
complement_color: Rgb,
|
|
complement_shade_15: Rgb,
|
|
complement_shade_30: Rgb,
|
|
inverse_saturation_tint_30: Rgb,
|
|
inverse_saturation_tint_15: Rgb,
|
|
inverse_saturation_color: Rgb,
|
|
inverse_saturation_shade_15: Rgb,
|
|
inverse_saturation_shade_30: Rgb,
|
|
}
|
|
|
|
impl TintAndShadePalette {
|
|
/// create a Palette based on one input color
|
|
pub fn create(input: Rgb) -> TintAndShadePalette {
|
|
let hsl: Hsl = Hsl::from_rgb(input.into_linear());
|
|
let h = hsl.hue;
|
|
let s = hsl.saturation;
|
|
let l = hsl.lightness;
|
|
let complement = h + 180.0 % 360.0;
|
|
let tint_15 = l + 0.15;
|
|
let tint_30 = l + 0.30;
|
|
let shade_15 = l - 0.15;
|
|
let shade_30 = l - 0.30;
|
|
let inverse_saturation = 1.0 - s;
|
|
|
|
TintAndShadePalette {
|
|
base_color: Rgb::from_linear(Hsl::new(h, s, l).into_rgb()),
|
|
base_tint_15: Rgb::from_linear(Hsl::new(h, s, tint_15).into_rgb()),
|
|
base_tint_30: Rgb::from_linear(Hsl::new(h, s, tint_30).into_rgb()),
|
|
base_shade_15: Rgb::from_linear(Hsl::new(h, s, shade_15).into_rgb()),
|
|
base_shade_30: Rgb::from_linear(Hsl::new(h, s, shade_30).into_rgb()),
|
|
complement_color: Rgb::from_linear(Hsl::new(complement, s, l).into_rgb()),
|
|
complement_tint_15: Rgb::from_linear(Hsl::new(complement, s, tint_15).into_rgb()),
|
|
complement_tint_30: Rgb::from_linear(Hsl::new(complement, s, tint_30).into_rgb()),
|
|
complement_shade_15: Rgb::from_linear(Hsl::new(complement, s, shade_15).into_rgb()),
|
|
complement_shade_30: Rgb::from_linear(Hsl::new(complement, s, shade_30).into_rgb()),
|
|
inverse_saturation_color: Rgb::from_linear(
|
|
Hsl::new(complement, inverse_saturation, l).into_rgb(),
|
|
),
|
|
inverse_saturation_tint_15: Rgb::from_linear(
|
|
Hsl::new(complement, inverse_saturation, tint_15).into_rgb(),
|
|
),
|
|
inverse_saturation_tint_30: Rgb::from_linear(
|
|
Hsl::new(complement, inverse_saturation, tint_30).into_rgb(),
|
|
),
|
|
inverse_saturation_shade_15: Rgb::from_linear(
|
|
Hsl::new(complement, inverse_saturation, shade_15).into_rgb(),
|
|
),
|
|
inverse_saturation_shade_30: Rgb::from_linear(
|
|
Hsl::new(complement, inverse_saturation, shade_30).into_rgb(),
|
|
),
|
|
}
|
|
}
|
|
}
|