refactor(color-module): 优化序列化实现并改进颜色计算逻辑
- 使用serde_json简化Swatch和ColorSet的序列化实现 - 修改Swatch.get()方法以使用0-1范围的亮度值 - 改进search_for_common_wacg_color算法,使用平均值替代最小值 - 为ColorSet添加hover字段的序列化
This commit is contained in:
parent
8a09806b8c
commit
a71a635eb8
@ -2,8 +2,9 @@ use core::f32;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use linked_hash_map::LinkedHashMap;
|
use linked_hash_map::LinkedHashMap;
|
||||||
use palette::{color_difference::Wcag21RelativeContrast, luma::Luma, Oklch};
|
use palette::{Oklch, color_difference::Wcag21RelativeContrast, luma::Luma};
|
||||||
use serde::{ser::SerializeStruct, Serialize};
|
use serde::Serialize;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
convert::{map_oklch_to_luma, map_oklch_to_srgb_hex},
|
convert::{map_oklch_to_luma, map_oklch_to_srgb_hex},
|
||||||
@ -44,11 +45,11 @@ fn search_for_common_wacg_color(
|
|||||||
for scan_lightness in (0..=100).map(|x| x as f32 / 100.0) {
|
for scan_lightness in (0..=100).map(|x| x as f32 / 100.0) {
|
||||||
let new_target = neutral_swatch.get(scan_lightness);
|
let new_target = neutral_swatch.get(scan_lightness);
|
||||||
let new_target_luma = map_oklch_to_luma(&new_target);
|
let new_target_luma = map_oklch_to_luma(&new_target);
|
||||||
let reference_wacgs = reference_colors
|
let reference_wacgs_sum: f32 = reference_colors
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ref_color| match_wacg(&ref_color, &new_target_luma) - minium_ratio)
|
.map(|ref_color| match_wacg(&ref_color, &new_target_luma) - minium_ratio)
|
||||||
.min_by(|a, b| a.abs().total_cmp(&b.abs()))
|
.sum();
|
||||||
.unwrap_or(f32::NEG_INFINITY);
|
let reference_wacgs = reference_wacgs_sum / reference_colors.len() as f32;
|
||||||
if reference_wacgs.abs() < closest_match.1.abs() {
|
if reference_wacgs.abs() < closest_match.1.abs() {
|
||||||
closest_match = (scan_lightness, reference_wacgs);
|
closest_match = (scan_lightness, reference_wacgs);
|
||||||
}
|
}
|
||||||
@ -273,19 +274,22 @@ impl Serialize for ColorSet {
|
|||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
{
|
{
|
||||||
let root = map_oklch_to_srgb_hex(&self.root);
|
let root = map_oklch_to_srgb_hex(&self.root);
|
||||||
|
let hover = map_oklch_to_srgb_hex(&self.hover);
|
||||||
let active = map_oklch_to_srgb_hex(&self.active);
|
let active = map_oklch_to_srgb_hex(&self.active);
|
||||||
let focus = map_oklch_to_srgb_hex(&self.focus);
|
let focus = map_oklch_to_srgb_hex(&self.focus);
|
||||||
let disabled = map_oklch_to_srgb_hex(&self.disabled);
|
let disabled = map_oklch_to_srgb_hex(&self.disabled);
|
||||||
let on_root = map_oklch_to_srgb_hex(&self.on_root);
|
let on_root = map_oklch_to_srgb_hex(&self.on_root);
|
||||||
let on_disabled = map_oklch_to_srgb_hex(&self.on_disabled);
|
let on_disabled = map_oklch_to_srgb_hex(&self.on_disabled);
|
||||||
|
|
||||||
let mut state = serializer.serialize_struct("ColorSet", 6)?;
|
let color_set_object = json!({
|
||||||
state.serialize_field("root", &root)?;
|
"root": root,
|
||||||
state.serialize_field("active", &active)?;
|
"hover": hover,
|
||||||
state.serialize_field("focus", &focus)?;
|
"active": active,
|
||||||
state.serialize_field("disabled", &disabled)?;
|
"focus": focus,
|
||||||
state.serialize_field("onRoot", &on_root)?;
|
"disabled": disabled,
|
||||||
state.serialize_field("onDisabled", &on_disabled)?;
|
"onRoot": on_root,
|
||||||
state.end()
|
"onDisabled": on_disabled,
|
||||||
|
});
|
||||||
|
color_set_object.serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use linked_hash_map::LinkedHashMap;
|
use linked_hash_map::LinkedHashMap;
|
||||||
use palette::Oklch;
|
use palette::Oklch;
|
||||||
use serde::{ser::SerializeMap, Serialize};
|
use serde::Serialize;
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::convert::map_oklch_to_srgb_hex;
|
use crate::convert::map_oklch_to_srgb_hex;
|
||||||
|
|
||||||
@ -17,9 +18,9 @@ impl Swatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get<L: Into<f32>>(&self, lightness: L) -> Oklch {
|
pub fn get<L: Into<f32>>(&self, lightness: L) -> Oklch {
|
||||||
let request_lightness: f32 = lightness.into();
|
let request_lightness: f32 = lightness.into() / 100.0;
|
||||||
Oklch {
|
Oklch {
|
||||||
l: request_lightness.clamp(10.0, 98.0),
|
l: request_lightness.clamp(0.1, 0.98),
|
||||||
..self.0.clone()
|
..self.0.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,13 +82,15 @@ impl Serialize for Swatch {
|
|||||||
where
|
where
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
{
|
{
|
||||||
let mut state = serializer.serialize_map(Some(SWATCH_LIGHTINGS.len()))?;
|
let swatch_object = SWATCH_LIGHTINGS
|
||||||
|
.iter()
|
||||||
|
.map(|l| {
|
||||||
|
let color = self.get_hex(*l);
|
||||||
|
let key = format!("{l:02}");
|
||||||
|
(key, color)
|
||||||
|
})
|
||||||
|
.collect::<Value>();
|
||||||
|
|
||||||
for l in SWATCH_LIGHTINGS {
|
swatch_object.serialize(serializer)
|
||||||
let color = self.get_hex(l);
|
|
||||||
state.serialize_entry(&format!("{l:02}"), &color)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.end()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user