暂存M3D的动态颜色生成功能。待重构。

This commit is contained in:
徐涛 2025-02-14 08:05:14 +08:00
parent d0e8acc5c0
commit 4054c2ce56
5 changed files with 223 additions and 154 deletions

View File

@ -43,6 +43,22 @@ impl Variant {
Variant::FruitSalad => "Fruit Salad".to_string(),
}
}
pub fn from_u8(value: u8) -> Variant {
match value {
0 => Variant::Monochrome,
1 => Variant::Neutral,
2 => Variant::TonalSpot,
3 => Variant::Vibrant,
4 => Variant::Expressive,
5 => Variant::Fidelity,
6 => Variant::Content,
7 => Variant::Rainbow,
8 => Variant::FruitSalad,
_ => Variant::Expressive,
}
}
pub fn hues(&self) -> Vec<f32> {
match self {
Variant::Vibrant => vec![0.0, 41.0, 61.0, 101.0, 131.0, 181.0, 251.0, 301.0, 360.0],

View File

@ -1,3 +1,5 @@
use std::rc::Rc;
use palette::Lch;
use crate::schemes::material_design_3::TonalPalette;
@ -6,7 +8,7 @@ use super::{contrast_curve::ContrastCurve, dynamic_scheme::DynamicScheme};
pub type TonalPaletteGenerator = Box<dyn Fn(&DynamicScheme) -> TonalPalette>;
pub type ToneSearcher = Box<dyn Fn(&DynamicScheme) -> f32>;
pub type DynamicColorSearcher = Box<dyn Fn(&DynamicScheme) -> DynamicColor>;
pub type DynamicColorSearcher = Box<dyn Fn(&DynamicScheme) -> Rc<DynamicColor>>;
pub type ToneDeltaPairGenerator = Box<dyn Fn(&DynamicScheme) -> ToneDeltaPair>;
pub type CustomPaletteGenerator = Box<dyn Fn(&Lch) -> TonalPalette>;
@ -31,8 +33,8 @@ pub struct DynamicColor {
}
pub struct ToneDeltaPair {
pub role_a: DynamicColor,
pub role_b: DynamicColor,
pub role_a: Rc<DynamicColor>,
pub role_b: Rc<DynamicColor>,
pub delta: f32,
pub polarity: TonePolarity,
pub togather: bool,

View File

@ -1,3 +1,5 @@
use std::{cell::LazyCell, rc::Rc};
use crate::cond;
use super::{
@ -8,9 +10,9 @@ use super::{
};
macro_rules! dynamic_gen {
($name: ident, $palette: expr, $tone: expr) => {
pub fn $name() -> DynamicColor {
DynamicColor::new(
($variable: ident, $name: ident, $palette: expr, $tone: expr) => {
pub const $variable: LazyCell<Rc<DynamicColor>> = LazyCell::new(|| {
Rc::new(DynamicColor::new(
Some(stringify!($name)),
Box::new($palette),
Box::new($tone),
@ -19,12 +21,12 @@ macro_rules! dynamic_gen {
None,
None,
None,
)
}
))
});
};
($name: ident, $palette: expr, $tone: expr, $is_background: expr) => {
pub fn $name() -> DynamicColor {
DynamicColor::new(
($variable: ident, $name: ident, $palette: expr, $tone: expr, $is_background: expr) => {
pub const $variable: LazyCell<Rc<DynamicColor>> = LazyCell::new(|| {
Rc::new(DynamicColor::new(
Some(stringify!($name)),
Box::new($palette),
Box::new($tone),
@ -33,12 +35,12 @@ macro_rules! dynamic_gen {
None,
None,
None,
)
}
))
});
};
($name: ident, $palette: expr, $tone: expr, $background: expr, $contrast_curve: expr) => {
pub fn $name() -> DynamicColor {
DynamicColor::new(
($variable: ident, $name: ident, $palette: expr, $tone: expr, $background: expr, $contrast_curve: expr) => {
pub const $variable: LazyCell<Rc<DynamicColor>> = LazyCell::new(|| {
Rc::new(DynamicColor::new(
Some(stringify!($name)),
Box::new($palette),
Box::new($tone),
@ -47,12 +49,12 @@ macro_rules! dynamic_gen {
None,
Some($contrast_curve),
None,
)
}
))
});
};
($name: ident, $palette: expr, $tone: expr, $is_background: expr, $background: expr, $secondary_background: expr, $contrast_curve: expr, $tone_delta_pairs: expr) => {
pub fn $name() -> DynamicColor {
DynamicColor::new(
($variable: ident, $name: ident, $palette: expr, $tone: expr, $is_background: expr, $background: expr, $secondary_background: expr, $contrast_curve: expr, $tone_delta_pairs: expr) => {
pub const $variable: LazyCell<Rc<DynamicColor>> = LazyCell::new(|| {
Rc::new(DynamicColor::new(
Some(stringify!($name)),
Box::new($palette),
Box::new($tone),
@ -61,8 +63,8 @@ macro_rules! dynamic_gen {
$secondary_background,
$contrast_curve,
$tone_delta_pairs,
)
}
))
});
};
}
@ -76,17 +78,19 @@ fn is_monochrome(scheme: &DynamicScheme) -> bool {
scheme.variant == Variant::Monochrome
}
fn highest_surface(s: &DynamicScheme) -> DynamicColor {
cond!(s.is_dark, surface_bright(), surface())
fn highest_surface(s: &DynamicScheme) -> Rc<DynamicColor> {
cond!(s.is_dark, Rc::clone(&SURFACE_BRIGHT), Rc::clone(&SURFACE))
}
dynamic_gen!(
SURFACE,
surface,
|s: &DynamicScheme| s.neutral_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 6.0, 98.0),
true
);
dynamic_gen!(
SURFACE_DIM,
surface_dim,
|s: &DynamicScheme| s.neutral_palette.clone(),
|s: &DynamicScheme| cond!(
@ -97,6 +101,7 @@ dynamic_gen!(
true
);
dynamic_gen!(
SURFACE_BRIGHT,
surface_bright,
|s: &DynamicScheme| s.neutral_palette.clone(),
|s: &DynamicScheme| cond!(
@ -107,6 +112,7 @@ dynamic_gen!(
true
);
dynamic_gen!(
SURFACE_CONTAINER_LOWEST,
surface_container_lowest,
|s: &DynamicScheme| s.neutral_palette.clone(),
|s: &DynamicScheme| cond!(
@ -117,6 +123,7 @@ dynamic_gen!(
true
);
dynamic_gen!(
SURFACE_CONTAINER_LOW,
surface_container_low,
|s: &DynamicScheme| s.neutral_palette.clone(),
|s: &DynamicScheme| cond!(
@ -127,6 +134,7 @@ dynamic_gen!(
true
);
dynamic_gen!(
SURFACE_CONTAINER,
surface_container,
|s: &DynamicScheme| s.neutral_palette.clone(),
|s: &DynamicScheme| cond!(
@ -137,6 +145,7 @@ dynamic_gen!(
true
);
dynamic_gen!(
SURFACE_CONTAINER_HIGH,
surface_container_high,
|s: &DynamicScheme| s.neutral_palette.clone(),
|s: &DynamicScheme| cond!(
@ -147,6 +156,7 @@ dynamic_gen!(
true
);
dynamic_gen!(
SURFACE_CONTAINER_HIGHEST,
surface_container_highest,
|s: &DynamicScheme| s.neutral_palette.clone(),
|s: &DynamicScheme| cond!(
@ -157,6 +167,7 @@ dynamic_gen!(
true
);
dynamic_gen!(
ON_SURFACE,
on_surface,
|s: &DynamicScheme| s.neutral_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 90.0, 10.0),
@ -164,12 +175,14 @@ dynamic_gen!(
ContrastCurve::new(4.5, 7.0, 11.0, 21.0)
);
dynamic_gen!(
SURFACE_VARIANT,
surface_variant,
|s: &DynamicScheme| s.neutral_variant_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 30.0, 90.0),
true
);
dynamic_gen!(
ON_SURFACE_VARIANT,
on_surface_variant,
|s: &DynamicScheme| s.neutral_variant_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 80.0, 30.0),
@ -177,18 +190,21 @@ dynamic_gen!(
ContrastCurve::new(3.0, 4.5, 7.0, 11.0)
);
dynamic_gen!(
INVERSE_SURFACE,
inverse_surface,
|s: &DynamicScheme| s.neutral_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 20.0, 95.0)
);
dynamic_gen!(
INVERSE_ON_SURFACE,
inverse_on_surface,
|s: &DynamicScheme| s.neutral_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 20.0, 95.0),
|_| inverse_surface(),
|_| Rc::clone(&INVERSE_SURFACE),
ContrastCurve::new(4.5, 7.0, 11.0, 21.0)
);
dynamic_gen!(
OUTLINE,
outline,
|s: &DynamicScheme| s.neutral_variant_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 60.0, 50.0),
@ -196,6 +212,7 @@ dynamic_gen!(
ContrastCurve::new(1.5, 3.0, 4.5, 7.0)
);
dynamic_gen!(
OUTLINE_VARIANT,
outline_variant,
|s: &DynamicScheme| s.neutral_variant_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 30.0, 80.0),
@ -203,14 +220,19 @@ dynamic_gen!(
ContrastCurve::new(1.0, 1.0, 3.0, 4.5)
);
dynamic_gen!(
SHADOW,
shadow,
|s: &DynamicScheme| s.neutral_palette.clone(),
|_| 0.0
);
dynamic_gen!(scrim, |s: &DynamicScheme| s.neutral_palette.clone(), |_| {
0.0
});
dynamic_gen!(
SCRIM,
scrim,
|s: &DynamicScheme| s.neutral_palette.clone(),
|_| { 0.0 }
);
dynamic_gen!(
PRIMARY,
primary,
|s: &DynamicScheme| s.primary_palette.clone(),
|s: &DynamicScheme| {
@ -225,14 +247,15 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(3.0, 4.5, 7.0, 7.0)),
Some(Box::new(|_| ToneDeltaPair {
role_a: primary_container(),
role_b: primary(),
role_a: Rc::clone(&PRIMARY_CONTAINER),
role_b: Rc::clone(&PRIMARY),
delta: 10.0,
polarity: TonePolarity::Nearer,
togather: false,
}))
);
dynamic_gen!(
ON_PRIMARY,
on_primary,
|s: &DynamicScheme| s.primary_palette.clone(),
|s: &DynamicScheme| {
@ -242,10 +265,11 @@ dynamic_gen!(
cond!(s.is_dark, 20.0, 100.0)
}
},
|_| primary(),
|_| Rc::clone(&PRIMARY),
ContrastCurve::new(4.5, 7.0, 11.0, 21.0)
);
dynamic_gen!(
PRIMARY_CONTAINER,
primary_container,
|s: &DynamicScheme| s.primary_palette.clone(),
|s: &DynamicScheme| {
@ -263,19 +287,20 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(1.0, 1.0, 3.0, 4.5)),
Some(Box::new(|_| ToneDeltaPair {
role_a: primary_container(),
role_b: primary(),
role_a: Rc::clone(&PRIMARY_CONTAINER),
role_b: Rc::clone(&PRIMARY),
delta: 10.0,
polarity: TonePolarity::Nearer,
togather: false,
}))
);
dynamic_gen!(
ON_PRIMARY_CONTAINER,
on_primary_container,
|s: &DynamicScheme| s.primary_palette.clone(),
|s: &DynamicScheme| {
if is_fidelity(s) {
return foreground_tone(primary_container().get_tone(s), 4.5);
return foreground_tone(Rc::clone(&PRIMARY_CONTAINER).get_tone(s), 4.5);
}
if is_monochrome(s) {
cond!(s.is_dark, 0.0, 100.0)
@ -283,17 +308,19 @@ dynamic_gen!(
cond!(s.is_dark, 90.0, 30.0)
}
},
|_| primary_container(),
|_| Rc::clone(&PRIMARY_CONTAINER),
ContrastCurve::new(3.0, 4.5, 7.0, 11.0)
);
dynamic_gen!(
INVERSE_PRIMARY,
inverse_primary,
|s: &DynamicScheme| s.primary_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 40.0, 80.0),
|_| inverse_surface(),
|_| Rc::clone(&INVERSE_SURFACE),
ContrastCurve::new(3.0, 4.5, 7.0, 7.0)
);
dynamic_gen!(
SECONDARY,
secondary,
|s: &DynamicScheme| s.secondary_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 80.0, 40.0),
@ -304,6 +331,7 @@ dynamic_gen!(
None
);
dynamic_gen!(
ON_SECONDARY,
on_secondary,
|s: &DynamicScheme| s.secondary_palette.clone(),
|s: &DynamicScheme| {
@ -313,10 +341,11 @@ dynamic_gen!(
cond!(s.is_dark, 20.0, 100.0)
}
},
|_| secondary(),
|_| Rc::clone(&SECONDARY),
ContrastCurve::new(4.5, 7.0, 11.0, 21.0)
);
dynamic_gen!(
SECONDARY_CONTAINER,
secondary_container,
|s: &DynamicScheme| s.secondary_palette.clone(),
|s: &DynamicScheme| {
@ -331,14 +360,15 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(1.0, 1.0, 3.0, 4.5)),
Some(Box::new(|_| ToneDeltaPair {
role_a: secondary_container(),
role_b: secondary(),
role_a: Rc::clone(&SECONDARY_CONTAINER),
role_b: Rc::clone(&SECONDARY),
delta: 10.0,
polarity: TonePolarity::Nearer,
togather: false,
}))
);
dynamic_gen!(
ON_SECONDARY_CONTAINER,
on_secondary_container,
|s: &DynamicScheme| s.secondary_palette.clone(),
|s: &DynamicScheme| {
@ -348,12 +378,13 @@ dynamic_gen!(
if !is_fidelity(s) {
return cond!(s.is_dark, 90.0, 30.0);
}
foreground_tone(secondary_container().get_tone(s), 4.5)
foreground_tone(Rc::clone(&SECONDARY_CONTAINER).get_tone(s), 4.5)
},
|_| secondary_container(),
|_| Rc::clone(&SECONDARY_CONTAINER),
ContrastCurve::new(3.0, 4.5, 7.0, 11.0)
);
dynamic_gen!(
TERTIARY,
tertiary,
|s: &DynamicScheme| s.tertiary_palette.clone(),
|s: &DynamicScheme| {
@ -367,14 +398,15 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(3.0, 4.5, 7.0, 7.0)),
Some(Box::new(|_| ToneDeltaPair {
role_a: tertiary_container(),
role_b: tertiary(),
role_a: Rc::clone(&TERTIARY_CONTAINER),
role_b: Rc::clone(&TERTIARY),
delta: 10.0,
polarity: TonePolarity::Nearer,
togather: false,
}))
);
dynamic_gen!(
ON_TERTIARY,
on_tertiary,
|s: &DynamicScheme| s.tertiary_palette.clone(),
|s: &DynamicScheme| {
@ -383,10 +415,11 @@ dynamic_gen!(
}
cond!(s.is_dark, 20.0, 100.0)
},
|_| tertiary(),
|_| Rc::clone(&TERTIARY),
ContrastCurve::new(4.5, 7.0, 11.0, 21.0)
);
dynamic_gen!(
TERTIARY_CONTAINER,
tertiary_container,
|s: &DynamicScheme| s.tertiary_palette.clone(),
|s: &DynamicScheme| {
@ -404,14 +437,15 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(1.0, 1.0, 3.0, 4.5)),
Some(Box::new(|_| ToneDeltaPair {
role_a: tertiary_container(),
role_b: tertiary(),
role_a: Rc::clone(&TERTIARY_CONTAINER),
role_b: Rc::clone(&TERTIARY),
delta: 10.0,
polarity: TonePolarity::Nearer,
togather: false,
}))
);
dynamic_gen!(
ON_TERTIARY_CONTAINER,
on_tertiary_container,
|s: &DynamicScheme| s.tertiary_palette.clone(),
|s: &DynamicScheme| {
@ -421,12 +455,13 @@ dynamic_gen!(
if !is_fidelity(s) {
return cond!(s.is_dark, 90.0, 30.0);
}
foreground_tone(tertiary_container().get_tone(s), 4.5)
foreground_tone(Rc::clone(&TERTIARY_CONTAINER).get_tone(s), 4.5)
},
|_| tertiary_container(),
|_| Rc::clone(&TERTIARY_CONTAINER),
ContrastCurve::new(3.0, 4.5, 7.0, 11.0)
);
dynamic_gen!(
ERROR,
error,
|s: &DynamicScheme| s.error_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 80.0, 40.0),
@ -435,21 +470,23 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(3.0, 4.5, 7.0, 7.0)),
Some(Box::new(|_| ToneDeltaPair {
role_a: error_container(),
role_b: error(),
role_a: Rc::clone(&ERROR_CONTAINER),
role_b: Rc::clone(&ERROR),
delta: 10.0,
polarity: TonePolarity::Nearer,
togather: false,
}))
);
dynamic_gen!(
ON_ERROR,
on_error,
|s: &DynamicScheme| s.error_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 20.0, 100.0),
|_| error(),
|_| Rc::clone(&ERROR),
ContrastCurve::new(4.5, 7.0, 11.0, 21.0)
);
dynamic_gen!(
ERROR_CONTAINER,
error_container,
|s: &DynamicScheme| s.error_palette.clone(),
|s: &DynamicScheme| cond!(s.is_dark, 30.0, 90.0),
@ -458,14 +495,15 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(1.0, 1.0, 3.0, 4.5)),
Some(Box::new(|_| ToneDeltaPair {
role_a: error_container(),
role_b: error(),
role_a: Rc::clone(&ERROR_CONTAINER),
role_b: Rc::clone(&ERROR),
delta: 10.0,
polarity: TonePolarity::Nearer,
togather: false,
}))
);
dynamic_gen!(
ON_ERROR_CONTAINER,
on_error_container,
|s: &DynamicScheme| s.error_palette.clone(),
|s: &DynamicScheme| {
@ -475,10 +513,11 @@ dynamic_gen!(
cond!(s.is_dark, 90.0, 30.0)
}
},
|_| error_container(),
|_| Rc::clone(&ERROR_CONTAINER),
ContrastCurve::new(3.0, 4.5, 7.0, 11.0)
);
dynamic_gen!(
PRIMARY_FIXED,
primary_fixed,
|s: &DynamicScheme| s.primary_palette.clone(),
|s: &DynamicScheme| cond!(is_monochrome(s), 40.0, 90.0),
@ -487,14 +526,15 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(1.0, 1.0, 3.0, 4.5)),
Some(Box::new(|_| ToneDeltaPair {
role_a: primary_fixed(),
role_b: primary_fixed_dim(),
role_a: Rc::clone(&PRIMARY_FIXED),
role_b: Rc::clone(&PRIMARY_FIXED_DIM),
delta: 10.0,
polarity: TonePolarity::Lighter,
togather: true,
}))
);
dynamic_gen!(
PRIMARY_FIXED_DIM,
primary_fixed_dim,
|s: &DynamicScheme| s.primary_palette.clone(),
|s: &DynamicScheme| cond!(is_monochrome(s), 30.0, 80.0),
@ -503,34 +543,37 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(1.0, 1.0, 3.0, 4.5)),
Some(Box::new(|_| ToneDeltaPair {
role_a: primary_fixed(),
role_b: primary_fixed_dim(),
role_a: Rc::clone(&PRIMARY_FIXED),
role_b: Rc::clone(&PRIMARY_FIXED_DIM),
delta: 10.0,
polarity: TonePolarity::Lighter,
togather: true,
}))
);
dynamic_gen!(
ON_PRIMARY_FIXED,
on_primary_fixed,
|s: &DynamicScheme| s.primary_palette.clone(),
|s: &DynamicScheme| cond!(is_monochrome(s), 100.0, 10.0),
None,
Some(Box::new(|_| primary_fixed_dim())),
Some(Box::new(|_| primary_fixed())),
Some(Box::new(|_| Rc::clone(&PRIMARY_FIXED_DIM))),
Some(Box::new(|_| Rc::clone(&PRIMARY_FIXED))),
Some(ContrastCurve::new(4.5, 7.0, 11.0, 21.0)),
None
);
dynamic_gen!(
ON_PRIMARY_FIXED_VARIANT,
on_primary_fixed_variant,
|s: &DynamicScheme| s.primary_palette.clone(),
|s: &DynamicScheme| cond!(is_monochrome(s), 90.0, 30.0),
None,
Some(Box::new(|_| primary_fixed_dim())),
Some(Box::new(|_| primary_fixed())),
Some(Box::new(|_| Rc::clone(&PRIMARY_FIXED_DIM))),
Some(Box::new(|_| Rc::clone(&PRIMARY_FIXED))),
Some(ContrastCurve::new(3.0, 4.5, 7.0, 11.0)),
None
);
dynamic_gen!(
SECONDARY_FIXED,
secondary_fixed,
|s: &DynamicScheme| s.secondary_palette.clone(),
|s: &DynamicScheme| cond!(is_monochrome(s), 80.0, 90.0),
@ -539,14 +582,15 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(1.0, 1.0, 3.0, 4.5)),
Some(Box::new(|_| ToneDeltaPair {
role_a: secondary_fixed(),
role_b: secondary_fixed_dim(),
role_a: Rc::clone(&SECONDARY_FIXED),
role_b: Rc::clone(&SECONDARY_FIXED_DIM),
delta: 10.0,
polarity: TonePolarity::Lighter,
togather: true,
}))
);
dynamic_gen!(
SECONDARY_FIXED_DIM,
secondary_fixed_dim,
|s: &DynamicScheme| s.secondary_palette.clone(),
|s: &DynamicScheme| cond!(is_monochrome(s), 70.0, 80.0),
@ -555,34 +599,37 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(1.0, 1.0, 3.0, 4.5)),
Some(Box::new(|_| ToneDeltaPair {
role_a: secondary_fixed(),
role_b: secondary_fixed_dim(),
role_a: Rc::clone(&SECONDARY_FIXED),
role_b: Rc::clone(&SECONDARY_FIXED_DIM),
delta: 10.0,
polarity: TonePolarity::Lighter,
togather: true,
}))
);
dynamic_gen!(
ON_SECONDARY_FIXED,
on_secondary_fixed,
|s: &DynamicScheme| s.secondary_palette.clone(),
|_| 10.0,
None,
Some(Box::new(|_| secondary_fixed_dim())),
Some(Box::new(|_| secondary_fixed())),
Some(Box::new(|_| Rc::clone(&SECONDARY_FIXED_DIM))),
Some(Box::new(|_| Rc::clone(&SECONDARY_FIXED))),
Some(ContrastCurve::new(4.5, 7.0, 11.0, 21.0)),
None
);
dynamic_gen!(
ON_SECONDARY_FIXED_VARIANT,
on_secondary_fixed_variant,
|s: &DynamicScheme| s.secondary_palette.clone(),
|s: &DynamicScheme| cond!(is_monochrome(s), 25.0, 30.0),
None,
Some(Box::new(|_| secondary_fixed_dim())),
Some(Box::new(|_| secondary_fixed())),
Some(Box::new(|_| Rc::clone(&SECONDARY_FIXED_DIM))),
Some(Box::new(|_| Rc::clone(&SECONDARY_FIXED))),
Some(ContrastCurve::new(3.0, 4.5, 7.0, 11.0)),
None
);
dynamic_gen!(
TERTIARY_FIXED,
tertiary_fixed,
|s: &DynamicScheme| s.tertiary_palette.clone(),
|s: &DynamicScheme| cond!(is_monochrome(s), 40.0, 90.0),
@ -591,14 +638,15 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(1.0, 1.0, 3.0, 4.5)),
Some(Box::new(|_| ToneDeltaPair {
role_a: tertiary_fixed(),
role_b: tertiary_fixed_dim(),
role_a: Rc::clone(&TERTIARY_FIXED),
role_b: Rc::clone(&TERTIARY_FIXED_DIM),
delta: 10.0,
polarity: TonePolarity::Lighter,
togather: true,
}))
);
dynamic_gen!(
TERTIARY_FIXED_DIM,
tertiary_fixed_dim,
|s: &DynamicScheme| s.tertiary_palette.clone(),
|s: &DynamicScheme| cond!(is_monochrome(s), 30.0, 80.0),
@ -607,36 +655,38 @@ dynamic_gen!(
None,
Some(ContrastCurve::new(1.0, 1.0, 3.0, 4.5)),
Some(Box::new(|_| ToneDeltaPair {
role_a: tertiary_fixed(),
role_b: tertiary_fixed_dim(),
role_a: Rc::clone(&TERTIARY_FIXED),
role_b: Rc::clone(&TERTIARY_FIXED_DIM),
delta: 10.0,
polarity: TonePolarity::Lighter,
togather: true,
}))
);
dynamic_gen!(
ON_TERTIARY_FIXED,
on_tertiary_fixed,
|s: &DynamicScheme| s.tertiary_palette.clone(),
|s: &DynamicScheme| cond!(is_monochrome(s), 100.0, 10.0),
None,
Some(Box::new(|_| tertiary_fixed_dim())),
Some(Box::new(|_| tertiary_fixed())),
Some(Box::new(|_| Rc::clone(&TERTIARY_FIXED_DIM))),
Some(Box::new(|_| Rc::clone(&TERTIARY_FIXED))),
Some(ContrastCurve::new(4.5, 7.0, 11.0, 21.0)),
None
);
dynamic_gen!(
ON_TERTIARY_FIXED_VARIANT,
on_tertiary_fixed_variant,
|s: &DynamicScheme| s.tertiary_palette.clone(),
|s: &DynamicScheme| cond!(is_monochrome(s), 90.0, 30.0),
None,
Some(Box::new(|_| tertiary_fixed_dim())),
Some(Box::new(|_| tertiary_fixed())),
Some(Box::new(|_| Rc::clone(&TERTIARY_FIXED_DIM))),
Some(Box::new(|_| Rc::clone(&TERTIARY_FIXED))),
Some(ContrastCurve::new(3.0, 4.5, 7.0, 11.0)),
None
);
pub fn custom(name: String) -> DynamicColor {
DynamicColor::new(
pub fn custom(name: String) -> Rc<DynamicColor> {
Rc::new(DynamicColor::new(
Some(&format!("{}", name)),
{
let name = name.clone();
@ -663,11 +713,11 @@ pub fn custom(name: String) -> DynamicColor {
togather: false,
}))
},
)
))
}
pub fn on_custom(name: String) -> DynamicColor {
DynamicColor::new(
pub fn on_custom(name: String) -> Rc<DynamicColor> {
Rc::new(DynamicColor::new(
Some(&format!("on_{}", name)),
{
let name = name.clone();
@ -691,11 +741,11 @@ pub fn on_custom(name: String) -> DynamicColor {
None,
Some(ContrastCurve::new(4.5, 7.0, 11.0, 21.0)),
None,
)
))
}
pub fn custom_container(name: String) -> DynamicColor {
DynamicColor::new(
pub fn custom_container(name: String) -> Rc<DynamicColor> {
Rc::new(DynamicColor::new(
Some(&format!("{}_container", name)),
{
let name = name.clone();
@ -725,11 +775,11 @@ pub fn custom_container(name: String) -> DynamicColor {
togather: false,
}))
},
)
))
}
pub fn on_custom_container(name: String) -> DynamicColor {
DynamicColor::new(
pub fn on_custom_container(name: String) -> Rc<DynamicColor> {
Rc::new(DynamicColor::new(
Some(&format!("on_{}_container", name)),
{
let name = name.clone();
@ -759,11 +809,11 @@ pub fn on_custom_container(name: String) -> DynamicColor {
None,
Some(ContrastCurve::new(3.0, 4.5, 7.0, 11.0)),
None,
)
))
}
pub fn inverse_custom(name: String) -> DynamicColor {
DynamicColor::new(
pub fn inverse_custom(name: String) -> Rc<DynamicColor> {
Rc::new(DynamicColor::new(
Some(&format!("inverse_{}", name)),
{
let name = name.clone();
@ -771,15 +821,15 @@ pub fn inverse_custom(name: String) -> DynamicColor {
},
Box::new(|s| cond!(s.is_dark, 20.0, 95.0)),
None,
Some(Box::new(|_| inverse_surface())),
Some(Box::new(|_| Rc::clone(&INVERSE_SURFACE))),
None,
Some(ContrastCurve::new(3.0, 4.5, 7.0, 11.0)),
None,
)
))
}
pub fn custom_fixed(name: String) -> DynamicColor {
DynamicColor::new(
pub fn custom_fixed(name: String) -> Rc<DynamicColor> {
Rc::new(DynamicColor::new(
Some(&format!("{}_fixed", name)),
{
let name = name.clone();
@ -800,11 +850,11 @@ pub fn custom_fixed(name: String) -> DynamicColor {
togather: true,
}))
},
)
))
}
pub fn custom_fixed_dim(name: String) -> DynamicColor {
DynamicColor::new(
pub fn custom_fixed_dim(name: String) -> Rc<DynamicColor> {
Rc::new(DynamicColor::new(
Some(&format!("{}_fixed_dim", name)),
{
let name = name.clone();
@ -825,11 +875,11 @@ pub fn custom_fixed_dim(name: String) -> DynamicColor {
togather: true,
}))
},
)
))
}
pub fn on_custom_fixed(name: String) -> DynamicColor {
DynamicColor::new(
pub fn on_custom_fixed(name: String) -> Rc<DynamicColor> {
Rc::new(DynamicColor::new(
Some(&format!("on_{}_fixed", name)),
{
let name = name.clone();
@ -844,11 +894,11 @@ pub fn on_custom_fixed(name: String) -> DynamicColor {
Some(Box::new(move |_| custom_fixed(String::from(&name)))),
Some(ContrastCurve::new(4.5, 7.0, 11.0, 21.0)),
None,
)
))
}
pub fn on_custom_fixed_variant(name: String) -> DynamicColor {
DynamicColor::new(
pub fn on_custom_fixed_variant(name: String) -> Rc<DynamicColor> {
Rc::new(DynamicColor::new(
Some(&format!("on_{}_fixed_variant", name)),
{
let name = name.clone();
@ -863,5 +913,5 @@ pub fn on_custom_fixed_variant(name: String) -> DynamicColor {
Some(Box::new(move |_| custom_fixed(String::from(&name)))),
Some(ContrastCurve::new(3.0, 4.5, 7.0, 11.0)),
None,
)
))
}

View File

@ -33,28 +33,28 @@ pub fn material_design_3_dynamic_variant() -> Result<JsValue, String> {
fn build_primary_color_set(scheme: &DynamicScheme) -> M3ColorSet {
M3ColorSet {
root: map_lch_to_srgb_hex(&primary().get_lch(scheme)),
on_root: map_lch_to_srgb_hex(&on_primary().get_lch(scheme)),
container: map_lch_to_srgb_hex(&primary_container().get_lch(scheme)),
on_container: map_lch_to_srgb_hex(&on_primary_container().get_lch(scheme)),
fixed: map_lch_to_srgb_hex(&primary_fixed().get_lch(scheme)),
on_fixed: map_lch_to_srgb_hex(&on_primary_fixed().get_lch(scheme)),
fixed_variant: map_lch_to_srgb_hex(&on_primary_fixed_variant().get_lch(scheme)),
fixed_dim: map_lch_to_srgb_hex(&primary_fixed_dim().get_lch(scheme)),
inverse: map_lch_to_srgb_hex(&inverse_primary().get_lch(scheme)),
root: map_lch_to_srgb_hex(&PRIMARY.get_lch(scheme)),
on_root: map_lch_to_srgb_hex(&ON_PRIMARY.get_lch(scheme)),
container: map_lch_to_srgb_hex(&PRIMARY_CONTAINER.get_lch(scheme)),
on_container: map_lch_to_srgb_hex(&ON_PRIMARY_CONTAINER.get_lch(scheme)),
fixed: map_lch_to_srgb_hex(&PRIMARY_FIXED.get_lch(scheme)),
on_fixed: map_lch_to_srgb_hex(&ON_PRIMARY_FIXED.get_lch(scheme)),
fixed_variant: map_lch_to_srgb_hex(&ON_PRIMARY_FIXED_VARIANT.get_lch(scheme)),
fixed_dim: map_lch_to_srgb_hex(&PRIMARY_FIXED_DIM.get_lch(scheme)),
inverse: map_lch_to_srgb_hex(&INVERSE_PRIMARY.get_lch(scheme)),
}
}
fn build_secondary_color_set(scheme: &DynamicScheme) -> M3ColorSet {
M3ColorSet {
root: map_lch_to_srgb_hex(&secondary().get_lch(scheme)),
on_root: map_lch_to_srgb_hex(&on_secondary().get_lch(scheme)),
container: map_lch_to_srgb_hex(&secondary_container().get_lch(scheme)),
on_container: map_lch_to_srgb_hex(&on_secondary_container().get_lch(scheme)),
fixed: map_lch_to_srgb_hex(&secondary_fixed().get_lch(scheme)),
on_fixed: map_lch_to_srgb_hex(&on_secondary_fixed().get_lch(scheme)),
fixed_variant: map_lch_to_srgb_hex(&on_secondary_fixed_variant().get_lch(scheme)),
fixed_dim: map_lch_to_srgb_hex(&secondary_fixed_dim().get_lch(scheme)),
root: map_lch_to_srgb_hex(&SECONDARY.get_lch(scheme)),
on_root: map_lch_to_srgb_hex(&ON_SECONDARY.get_lch(scheme)),
container: map_lch_to_srgb_hex(&SECONDARY_CONTAINER.get_lch(scheme)),
on_container: map_lch_to_srgb_hex(&ON_SECONDARY_CONTAINER.get_lch(scheme)),
fixed: map_lch_to_srgb_hex(&SECONDARY_FIXED.get_lch(scheme)),
on_fixed: map_lch_to_srgb_hex(&ON_SECONDARY_FIXED.get_lch(scheme)),
fixed_variant: map_lch_to_srgb_hex(&ON_SECONDARY_FIXED_VARIANT.get_lch(scheme)),
fixed_dim: map_lch_to_srgb_hex(&SECONDARY_FIXED_DIM.get_lch(scheme)),
..cond!(
scheme.is_dark,
M3ColorSet::new_dark_set(&scheme.secondary_palette),
@ -65,14 +65,14 @@ fn build_secondary_color_set(scheme: &DynamicScheme) -> M3ColorSet {
fn build_tertiary_color_set(scheme: &DynamicScheme) -> M3ColorSet {
M3ColorSet {
root: map_lch_to_srgb_hex(&tertiary().get_lch(scheme)),
on_root: map_lch_to_srgb_hex(&on_tertiary().get_lch(scheme)),
container: map_lch_to_srgb_hex(&tertiary_container().get_lch(scheme)),
on_container: map_lch_to_srgb_hex(&on_tertiary_container().get_lch(scheme)),
fixed: map_lch_to_srgb_hex(&tertiary_fixed().get_lch(scheme)),
on_fixed: map_lch_to_srgb_hex(&on_tertiary_fixed().get_lch(scheme)),
fixed_variant: map_lch_to_srgb_hex(&on_tertiary_fixed_variant().get_lch(scheme)),
fixed_dim: map_lch_to_srgb_hex(&tertiary_fixed_dim().get_lch(scheme)),
root: map_lch_to_srgb_hex(&TERTIARY.get_lch(scheme)),
on_root: map_lch_to_srgb_hex(&ON_TERTIARY.get_lch(scheme)),
container: map_lch_to_srgb_hex(&TERTIARY_CONTAINER.get_lch(scheme)),
on_container: map_lch_to_srgb_hex(&ON_TERTIARY_CONTAINER.get_lch(scheme)),
fixed: map_lch_to_srgb_hex(&TERTIARY_FIXED.get_lch(scheme)),
on_fixed: map_lch_to_srgb_hex(&ON_TERTIARY_FIXED.get_lch(scheme)),
fixed_variant: map_lch_to_srgb_hex(&ON_TERTIARY_FIXED_VARIANT.get_lch(scheme)),
fixed_dim: map_lch_to_srgb_hex(&TERTIARY_FIXED_DIM.get_lch(scheme)),
..cond!(
scheme.is_dark,
M3ColorSet::new_dark_set(&scheme.tertiary_palette),
@ -83,28 +83,28 @@ fn build_tertiary_color_set(scheme: &DynamicScheme) -> M3ColorSet {
fn build_surface_color_set(scheme: &DynamicScheme) -> M3SurfaceSet {
M3SurfaceSet {
root: map_lch_to_srgb_hex(&surface().get_lch(scheme)),
dim: map_lch_to_srgb_hex(&surface_dim().get_lch(scheme)),
bright: map_lch_to_srgb_hex(&surface_bright().get_lch(scheme)),
variant: map_lch_to_srgb_hex(&surface_variant().get_lch(scheme)),
container: map_lch_to_srgb_hex(&surface_container().get_lch(scheme)),
container_lowest: map_lch_to_srgb_hex(&surface_container_lowest().get_lch(scheme)),
container_low: map_lch_to_srgb_hex(&surface_container_low().get_lch(scheme)),
container_high: map_lch_to_srgb_hex(&surface_container_high().get_lch(scheme)),
container_highest: map_lch_to_srgb_hex(&surface_container_highest().get_lch(scheme)),
on_root: map_lch_to_srgb_hex(&on_surface().get_lch(scheme)),
on_root_variant: map_lch_to_srgb_hex(&on_surface_variant().get_lch(scheme)),
inverse: map_lch_to_srgb_hex(&inverse_surface().get_lch(scheme)),
on_inverse: map_lch_to_srgb_hex(&inverse_on_surface().get_lch(scheme)),
root: map_lch_to_srgb_hex(&SURFACE.get_lch(scheme)),
dim: map_lch_to_srgb_hex(&SURFACE_DIM.get_lch(scheme)),
bright: map_lch_to_srgb_hex(&SURFACE_BRIGHT.get_lch(scheme)),
variant: map_lch_to_srgb_hex(&SURFACE_VARIANT.get_lch(scheme)),
container: map_lch_to_srgb_hex(&SURFACE_CONTAINER.get_lch(scheme)),
container_lowest: map_lch_to_srgb_hex(&SURFACE_CONTAINER_LOWEST.get_lch(scheme)),
container_low: map_lch_to_srgb_hex(&SURFACE_CONTAINER_LOW.get_lch(scheme)),
container_high: map_lch_to_srgb_hex(&SURFACE_CONTAINER_HIGH.get_lch(scheme)),
container_highest: map_lch_to_srgb_hex(&SURFACE_CONTAINER_HIGHEST.get_lch(scheme)),
on_root: map_lch_to_srgb_hex(&ON_SURFACE.get_lch(scheme)),
on_root_variant: map_lch_to_srgb_hex(&ON_SURFACE_VARIANT.get_lch(scheme)),
inverse: map_lch_to_srgb_hex(&INVERSE_SURFACE.get_lch(scheme)),
on_inverse: map_lch_to_srgb_hex(&INVERSE_ON_SURFACE.get_lch(scheme)),
}
}
fn build_error_color_set(scheme: &DynamicScheme) -> M3ColorSet {
M3ColorSet {
root: map_lch_to_srgb_hex(&error().get_lch(scheme)),
on_root: map_lch_to_srgb_hex(&on_error().get_lch(scheme)),
container: map_lch_to_srgb_hex(&error_container().get_lch(scheme)),
on_container: map_lch_to_srgb_hex(&on_error_container().get_lch(scheme)),
root: map_lch_to_srgb_hex(&ERROR.get_lch(scheme)),
on_root: map_lch_to_srgb_hex(&ON_ERROR.get_lch(scheme)),
container: map_lch_to_srgb_hex(&ERROR_CONTAINER.get_lch(scheme)),
on_container: map_lch_to_srgb_hex(&ON_ERROR_CONTAINER.get_lch(scheme)),
..cond!(
scheme.is_dark,
M3ColorSet::new_dark_set(&scheme.error_palette),
@ -134,10 +134,10 @@ pub fn build_baseline(scheme: &DynamicScheme) -> M3BaselineColors {
build_tertiary_color_set(scheme),
build_error_color_set(scheme),
build_surface_color_set(scheme),
map_lch_to_srgb_hex(&outline().get_lch(scheme)),
map_lch_to_srgb_hex(&outline_variant().get_lch(scheme)),
map_lch_to_srgb_hex(&scrim().get_lch(scheme)),
map_lch_to_srgb_hex(&shadow().get_lch(scheme)),
map_lch_to_srgb_hex(&OUTLINE.get_lch(scheme)),
map_lch_to_srgb_hex(&OUTLINE_VARIANT.get_lch(scheme)),
map_lch_to_srgb_hex(&SCRIM.get_lch(scheme)),
map_lch_to_srgb_hex(&SHADOW.get_lch(scheme)),
scheme
.custom_palettes
.keys()

View File

@ -149,13 +149,14 @@ pub fn generate_swatch_scheme(
pub fn generate_material_design_3_dynamic_scheme(
source_color: &str,
error_color: Option<String>,
variant: Variant,
variant: u8,
contrast_level: f32,
harmonize_customs: bool,
custom_colors: JsValue,
) -> Result<JsValue, errors::ColorError> {
let custom_colors: HashMap<String, String> = serde_wasm_bindgen::from_value(custom_colors)
.map_err(|_| errors::ColorError::UnableToParseArgument)?;
let variant = Variant::from_u8(variant);
let light_scheme = build_dynamic_scheme(
source_color,