综合调整Q Scheme的生成算法。
This commit is contained in:
@@ -48,16 +48,19 @@ impl Baseline {
|
||||
let outline_color = neutral_swatch.get(background.l * 0.7);
|
||||
|
||||
Self {
|
||||
primary: ColorSet::new(primary, &neutral_swatch, &setting),
|
||||
secondary: secondary.map(|color| ColorSet::new(&color, &neutral_swatch, &setting)),
|
||||
tertiary: tertiary.map(|color| ColorSet::new(&color, &neutral_swatch, &setting)),
|
||||
accent: accent.map(|color| ColorSet::new(&color, &neutral_swatch, &setting)),
|
||||
neutral: ColorSet::new(&neutral_color, &neutral_swatch, &setting),
|
||||
danger: ColorSet::new(danger, &neutral_swatch, &setting),
|
||||
success: ColorSet::new(success, &neutral_swatch, &setting),
|
||||
warning: ColorSet::new(warning, &neutral_swatch, &setting),
|
||||
info: ColorSet::new(info, &neutral_swatch, &setting),
|
||||
outline: ColorSet::new(&outline_color, &neutral_swatch, &setting),
|
||||
primary: ColorSet::new(primary, &neutral_swatch, foreground.l, &setting),
|
||||
secondary: secondary
|
||||
.map(|color| ColorSet::new(&color, &neutral_swatch, foreground.l, &setting)),
|
||||
tertiary: tertiary
|
||||
.map(|color| ColorSet::new(&color, &neutral_swatch, foreground.l, &setting)),
|
||||
accent: accent
|
||||
.map(|color| ColorSet::new(&color, &neutral_swatch, foreground.l, &setting)),
|
||||
neutral: ColorSet::new(&neutral_color, &neutral_swatch, foreground.l, &setting),
|
||||
danger: ColorSet::new(danger, &neutral_swatch, foreground.l, &setting),
|
||||
success: ColorSet::new(success, &neutral_swatch, foreground.l, &setting),
|
||||
warning: ColorSet::new(warning, &neutral_swatch, foreground.l, &setting),
|
||||
info: ColorSet::new(info, &neutral_swatch, foreground.l, &setting),
|
||||
outline: ColorSet::new(&outline_color, &neutral_swatch, foreground.l, &setting),
|
||||
foreground: *foreground,
|
||||
background: *background,
|
||||
_neutral_swatch: neutral_swatch,
|
||||
|
@@ -32,35 +32,35 @@ fn fit_to_wacg(reference: &Oklch, neutral_swatch: &NeutralSwatch, ratio: f32) ->
|
||||
luma.relative_contrast(*reference)
|
||||
};
|
||||
|
||||
let mut last_contrast_ratio = 0.0;
|
||||
let mut repeat_count = 0;
|
||||
let mut target_ratio = ratio;
|
||||
loop {
|
||||
let contrast_ratio = match_wacg(&new_target, &reference_luma);
|
||||
if contrast_ratio >= target_ratio {
|
||||
if contrast_ratio >= ratio || new_target.l <= 0.0 || new_target.l >= 1.0 {
|
||||
break;
|
||||
}
|
||||
if (contrast_ratio - last_contrast_ratio).abs() / last_contrast_ratio < 0.001 {
|
||||
repeat_count += 1;
|
||||
if repeat_count > 20 {
|
||||
target_ratio *= 1.0 - 0.01;
|
||||
repeat_count = 0;
|
||||
}
|
||||
web_sys::console::log_3(
|
||||
&"fit_to_wacg".into(),
|
||||
&contrast_ratio.into(),
|
||||
&new_target.l.into(),
|
||||
);
|
||||
new_target = neutral_swatch.get(if new_target.l + factor <= 0.0 {
|
||||
0.0
|
||||
} else if new_target.l + factor >= 1.0 {
|
||||
1.0
|
||||
} else {
|
||||
repeat_count = 0;
|
||||
}
|
||||
last_contrast_ratio = contrast_ratio;
|
||||
new_target = Oklch {
|
||||
l: new_target.l * (1.0 + factor),
|
||||
..new_target
|
||||
};
|
||||
new_target.l + factor
|
||||
});
|
||||
}
|
||||
|
||||
new_target
|
||||
}
|
||||
|
||||
impl ColorSet {
|
||||
pub fn new(color: &Oklch, neutral_swatch: &NeutralSwatch, setting: &SchemeSetting) -> Self {
|
||||
pub fn new(
|
||||
color: &Oklch,
|
||||
neutral_swatch: &NeutralSwatch,
|
||||
foreground_lightness: f32,
|
||||
setting: &SchemeSetting,
|
||||
) -> Self {
|
||||
let root = color.clone();
|
||||
let hover = color * setting.hover;
|
||||
let active = color * setting.active;
|
||||
@@ -69,11 +69,11 @@ impl ColorSet {
|
||||
|
||||
let (on_root, on_hover, on_active, on_focus, on_disabled) = match setting.wacg_follows {
|
||||
WACGSetting::Fixed => (
|
||||
neutral_swatch.get(root.l),
|
||||
neutral_swatch.get(hover.l),
|
||||
neutral_swatch.get(active.l),
|
||||
neutral_swatch.get(focus.l),
|
||||
neutral_swatch.get(disabled.l),
|
||||
neutral_swatch.get(foreground_lightness),
|
||||
neutral_swatch.get(foreground_lightness),
|
||||
neutral_swatch.get(foreground_lightness),
|
||||
neutral_swatch.get(foreground_lightness),
|
||||
neutral_swatch.get(foreground_lightness),
|
||||
),
|
||||
WACGSetting::AutomaticAA => (
|
||||
fit_to_wacg(&root, neutral_swatch, 4.5),
|
||||
|
@@ -58,7 +58,7 @@ impl QScheme {
|
||||
&(success * setting.dark_convert),
|
||||
&(warning * setting.dark_convert),
|
||||
&(info * setting.dark_convert),
|
||||
&(&background * setting.dark_convert),
|
||||
&(&background * (setting.dark_convert / 2.0)),
|
||||
&(&foreground * setting.dark_convert),
|
||||
setting.clone(),
|
||||
),
|
||||
@@ -112,7 +112,7 @@ impl QScheme {
|
||||
&(success * setting.dark_convert),
|
||||
&(warning * setting.dark_convert),
|
||||
&(info * setting.dark_convert),
|
||||
&(foreground * setting.dark_convert),
|
||||
&(foreground * (setting.dark_convert / 2.0)),
|
||||
&(background * setting.dark_convert),
|
||||
setting.clone(),
|
||||
),
|
||||
|
@@ -1,4 +1,4 @@
|
||||
use std::ops::Mul;
|
||||
use std::ops::{Div, Mul};
|
||||
|
||||
use enum_iterator::Sequence;
|
||||
use palette::Oklch;
|
||||
@@ -65,6 +65,28 @@ impl Mul<ColorShifting> for &Oklch<f32> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<f32> for ColorShifting {
|
||||
type Output = ColorShifting;
|
||||
|
||||
fn div(self, rhs: f32) -> Self::Output {
|
||||
ColorShifting {
|
||||
chroma: self.chroma / rhs,
|
||||
lightness: self.lightness / rhs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<f32> for &ColorShifting {
|
||||
type Output = ColorShifting;
|
||||
|
||||
fn div(self, rhs: f32) -> Self::Output {
|
||||
ColorShifting {
|
||||
chroma: self.chroma / rhs,
|
||||
lightness: self.lightness / rhs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
#[wasm_bindgen]
|
||||
pub struct SchemeSetting {
|
||||
@@ -140,7 +162,7 @@ impl Default for SchemeSetting {
|
||||
},
|
||||
disabled: ColorShifting {
|
||||
chroma: -0.9,
|
||||
lightness: -0.2,
|
||||
lightness: 0.2,
|
||||
},
|
||||
dark_convert: ColorShifting {
|
||||
chroma: -0.3,
|
||||
|
Reference in New Issue
Block a user