增加构建M3各个色盘的能力。
This commit is contained in:
		@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					use std::collections::HashMap;
 | 
				
			||||||
use std::str::FromStr;
 | 
					use std::str::FromStr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub use baseline::M3BaselineColors;
 | 
					pub use baseline::M3BaselineColors;
 | 
				
			||||||
@@ -5,6 +6,7 @@ pub use color_set::M3ColorSet;
 | 
				
			|||||||
use palette::{IntoColor, Lch, Srgb};
 | 
					use palette::{IntoColor, Lch, Srgb};
 | 
				
			||||||
use serde::Serialize;
 | 
					use serde::Serialize;
 | 
				
			||||||
pub use surface::M3SurfaceSet;
 | 
					pub use surface::M3SurfaceSet;
 | 
				
			||||||
 | 
					pub use swatch::M3PaletteSwatch;
 | 
				
			||||||
pub use tonal_palette::TonalPalette;
 | 
					pub use tonal_palette::TonalPalette;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::convert::map_lch_to_srgb_hex;
 | 
					use crate::convert::map_lch_to_srgb_hex;
 | 
				
			||||||
@@ -15,6 +17,7 @@ use super::SchemeExport;
 | 
				
			|||||||
mod baseline;
 | 
					mod baseline;
 | 
				
			||||||
mod color_set;
 | 
					mod color_set;
 | 
				
			||||||
mod surface;
 | 
					mod surface;
 | 
				
			||||||
 | 
					mod swatch;
 | 
				
			||||||
mod tonal_palette;
 | 
					mod tonal_palette;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, Serialize)]
 | 
					#[derive(Debug, Clone, Serialize)]
 | 
				
			||||||
@@ -23,6 +26,7 @@ pub struct MaterialDesign3Scheme {
 | 
				
			|||||||
    pub black: String,
 | 
					    pub black: String,
 | 
				
			||||||
    pub light_baseline: M3BaselineColors,
 | 
					    pub light_baseline: M3BaselineColors,
 | 
				
			||||||
    pub dark_baseline: M3BaselineColors,
 | 
					    pub dark_baseline: M3BaselineColors,
 | 
				
			||||||
 | 
					    pub swatches: HashMap<String, M3PaletteSwatch>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl MaterialDesign3Scheme {
 | 
					impl MaterialDesign3Scheme {
 | 
				
			||||||
@@ -43,11 +47,20 @@ impl MaterialDesign3Scheme {
 | 
				
			|||||||
        let nv = TonalPalette::from_hue_and_chroma(source_hue, (source.chroma / 6.0).min(8.0));
 | 
					        let nv = TonalPalette::from_hue_and_chroma(source_hue, (source.chroma / 6.0).min(8.0));
 | 
				
			||||||
        let e = TonalPalette::from_hue_and_chroma(error.hue.into_positive_degrees(), 84.0);
 | 
					        let e = TonalPalette::from_hue_and_chroma(error.hue.into_positive_degrees(), 84.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut swatches = HashMap::new();
 | 
				
			||||||
 | 
					        swatches.insert("primary".to_string(), M3PaletteSwatch::new(&p));
 | 
				
			||||||
 | 
					        swatches.insert("secondary".to_string(), M3PaletteSwatch::new(&s));
 | 
				
			||||||
 | 
					        swatches.insert("tertiary".to_string(), M3PaletteSwatch::new(&t));
 | 
				
			||||||
 | 
					        swatches.insert("error".to_string(), M3PaletteSwatch::new(&e));
 | 
				
			||||||
 | 
					        swatches.insert("neutral".to_string(), M3PaletteSwatch::new(&n));
 | 
				
			||||||
 | 
					        swatches.insert("neutral_variant".to_string(), M3PaletteSwatch::new(&nv));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(Self {
 | 
					        Ok(Self {
 | 
				
			||||||
            white: map_lch_to_srgb_hex(&Lch::new(100.0, 0.0, 0.0)),
 | 
					            white: map_lch_to_srgb_hex(&Lch::new(100.0, 0.0, 0.0)),
 | 
				
			||||||
            black: map_lch_to_srgb_hex(&Lch::new(0.0, 0.0, 0.0)),
 | 
					            black: map_lch_to_srgb_hex(&Lch::new(0.0, 0.0, 0.0)),
 | 
				
			||||||
            light_baseline: M3BaselineColors::new(&p, &s, &t, &n, &nv, &e, false),
 | 
					            light_baseline: M3BaselineColors::new(&p, &s, &t, &n, &nv, &e, false),
 | 
				
			||||||
            dark_baseline: M3BaselineColors::new(&p, &s, &t, &n, &nv, &e, true),
 | 
					            dark_baseline: M3BaselineColors::new(&p, &s, &t, &n, &nv, &e, true),
 | 
				
			||||||
 | 
					            swatches,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -64,15 +77,21 @@ impl MaterialDesign3Scheme {
 | 
				
			|||||||
        let palette = TonalPalette::from_hue_and_chroma(hue, custom_color.chroma);
 | 
					        let palette = TonalPalette::from_hue_and_chroma(hue, custom_color.chroma);
 | 
				
			||||||
        self.light_baseline.add_custom_set(name.clone(), &palette);
 | 
					        self.light_baseline.add_custom_set(name.clone(), &palette);
 | 
				
			||||||
        self.dark_baseline.add_custom_set(name.clone(), &palette);
 | 
					        self.dark_baseline.add_custom_set(name.clone(), &palette);
 | 
				
			||||||
 | 
					        self.swatches.insert(name, M3PaletteSwatch::new(&palette));
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn full_custom(light_baseline: M3BaselineColors, dark_baseline: M3BaselineColors) -> Self {
 | 
					    pub fn full_custom(
 | 
				
			||||||
 | 
					        light_baseline: M3BaselineColors,
 | 
				
			||||||
 | 
					        dark_baseline: M3BaselineColors,
 | 
				
			||||||
 | 
					        swatches: HashMap<String, M3PaletteSwatch>,
 | 
				
			||||||
 | 
					    ) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            white: map_lch_to_srgb_hex(&Lch::new(100.0, 0.0, 0.0)),
 | 
					            white: map_lch_to_srgb_hex(&Lch::new(100.0, 0.0, 0.0)),
 | 
				
			||||||
            black: map_lch_to_srgb_hex(&Lch::new(0.0, 0.0, 0.0)),
 | 
					            black: map_lch_to_srgb_hex(&Lch::new(0.0, 0.0, 0.0)),
 | 
				
			||||||
            light_baseline,
 | 
					            light_baseline,
 | 
				
			||||||
            dark_baseline,
 | 
					            dark_baseline,
 | 
				
			||||||
 | 
					            swatches,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -85,6 +104,9 @@ impl SchemeExport for MaterialDesign3Scheme {
 | 
				
			|||||||
        css_variables.push(format!("--color-black: #{};", self.black));
 | 
					        css_variables.push(format!("--color-black: #{};", self.black));
 | 
				
			||||||
        css_variables.extend(self.light_baseline.to_css_variables());
 | 
					        css_variables.extend(self.light_baseline.to_css_variables());
 | 
				
			||||||
        css_variables.extend(self.dark_baseline.to_css_variables());
 | 
					        css_variables.extend(self.dark_baseline.to_css_variables());
 | 
				
			||||||
 | 
					        for (name, swatch) in &self.swatches {
 | 
				
			||||||
 | 
					            css_variables.extend(swatch.to_css_variables(name));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        css_variables.join("\n")
 | 
					        css_variables.join("\n")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -96,6 +118,9 @@ impl SchemeExport for MaterialDesign3Scheme {
 | 
				
			|||||||
        scss_variables.push(format!("$color-black: #{};", self.black));
 | 
					        scss_variables.push(format!("$color-black: #{};", self.black));
 | 
				
			||||||
        scss_variables.extend(self.light_baseline.to_scss_variables());
 | 
					        scss_variables.extend(self.light_baseline.to_scss_variables());
 | 
				
			||||||
        scss_variables.extend(self.dark_baseline.to_scss_variables());
 | 
					        scss_variables.extend(self.dark_baseline.to_scss_variables());
 | 
				
			||||||
 | 
					        for (name, swatch) in &self.swatches {
 | 
				
			||||||
 | 
					            scss_variables.extend(swatch.to_scss_variables(name));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        scss_variables.join("\n")
 | 
					        scss_variables.join("\n")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -111,8 +136,7 @@ impl SchemeExport for MaterialDesign3Scheme {
 | 
				
			|||||||
            self.light_baseline
 | 
					            self.light_baseline
 | 
				
			||||||
                .to_javascript_object_fields()
 | 
					                .to_javascript_object_fields()
 | 
				
			||||||
                .into_iter()
 | 
					                .into_iter()
 | 
				
			||||||
                .map(|s| format!("    {}", s))
 | 
					                .map(|s| format!("    {}", s)),
 | 
				
			||||||
                .collect::<Vec<String>>(),
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        js_object.push("  },".to_string());
 | 
					        js_object.push("  },".to_string());
 | 
				
			||||||
        js_object.push("  dark: {".to_string());
 | 
					        js_object.push("  dark: {".to_string());
 | 
				
			||||||
@@ -120,10 +144,19 @@ impl SchemeExport for MaterialDesign3Scheme {
 | 
				
			|||||||
            self.dark_baseline
 | 
					            self.dark_baseline
 | 
				
			||||||
                .to_javascript_object_fields()
 | 
					                .to_javascript_object_fields()
 | 
				
			||||||
                .into_iter()
 | 
					                .into_iter()
 | 
				
			||||||
                .map(|s| format!("    {}", s))
 | 
					                .map(|s| format!("    {}", s)),
 | 
				
			||||||
                .collect::<Vec<String>>(),
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        js_object.push("  },".to_string());
 | 
					        js_object.push("  },".to_string());
 | 
				
			||||||
 | 
					        js_object.push("  swatches: {".to_string());
 | 
				
			||||||
 | 
					        for (name, swatch) in &self.swatches {
 | 
				
			||||||
 | 
					            js_object.extend(
 | 
				
			||||||
 | 
					                swatch
 | 
				
			||||||
 | 
					                    .to_javascript_object_fields(name)
 | 
				
			||||||
 | 
					                    .into_iter()
 | 
				
			||||||
 | 
					                    .map(|s| format!("  {}", s)),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        js_object.push("  }".to_string());
 | 
				
			||||||
        js_object.push("}".to_string());
 | 
					        js_object.push("}".to_string());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        js_object.join("\n")
 | 
					        js_object.join("\n")
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										72
									
								
								color-module/src/schemes/material_design_3/swatch.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								color-module/src/schemes/material_design_3/swatch.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					use std::collections::HashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use serde::Serialize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::convert::map_lch_to_srgb_hex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use super::TonalPalette;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static SWATCH_TONES: [u8; 18] = [
 | 
				
			||||||
 | 
					    0, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 95, 98, 99, 100,
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, Serialize)]
 | 
				
			||||||
 | 
					pub struct M3PaletteSwatch(HashMap<u8, String>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl M3PaletteSwatch {
 | 
				
			||||||
 | 
					    pub fn new(palette: &TonalPalette) -> Self {
 | 
				
			||||||
 | 
					        let mut swatch = HashMap::new();
 | 
				
			||||||
 | 
					        for &tone in SWATCH_TONES.iter() {
 | 
				
			||||||
 | 
					            let color = palette.tone(tone as f32);
 | 
				
			||||||
 | 
					            swatch.insert(tone, map_lch_to_srgb_hex(&color));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Self(swatch)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn to_css_variables(&self, name: &str) -> Vec<String> {
 | 
				
			||||||
 | 
					        let mut variable_lines = Vec::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for &tone in SWATCH_TONES.iter() {
 | 
				
			||||||
 | 
					            let color = self.0.get(&tone).unwrap();
 | 
				
			||||||
 | 
					            variable_lines.push(format!("--color-swatch-{}-{}: #{};", name, tone, color));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        variable_lines
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn to_scss_variables(&self, name: &str) -> Vec<String> {
 | 
				
			||||||
 | 
					        let mut variable_lines = Vec::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for &tone in SWATCH_TONES.iter() {
 | 
				
			||||||
 | 
					            let color = self.0.get(&tone).unwrap();
 | 
				
			||||||
 | 
					            variable_lines.push(format!("$color-swatch-{}-{}: #{};", name, tone, color));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        variable_lines
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn to_javascript_object_fields(&self, name: &str) -> Vec<String> {
 | 
				
			||||||
 | 
					        let mut js_object = Vec::new();
 | 
				
			||||||
 | 
					        let name = name
 | 
				
			||||||
 | 
					            .split('_')
 | 
				
			||||||
 | 
					            .enumerate()
 | 
				
			||||||
 | 
					            .map(|(i, part)| {
 | 
				
			||||||
 | 
					                if i == 0 {
 | 
				
			||||||
 | 
					                    part.to_string()
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    let mut c = part.chars();
 | 
				
			||||||
 | 
					                    c.next().unwrap().to_uppercase().collect::<String>() + c.as_str()
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .collect::<String>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        js_object.push(format!("{}: {{", name));
 | 
				
			||||||
 | 
					        for &tone in SWATCH_TONES.iter() {
 | 
				
			||||||
 | 
					            let color = self.0.get(&tone).unwrap();
 | 
				
			||||||
 | 
					            js_object.push(format!("  {}: '#{}',", tone, color));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        js_object.push("},".to_string());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        js_object
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -7,7 +7,7 @@ use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use crate::{cond, convert::map_lch_to_srgb_hex, errors};
 | 
					use crate::{cond, convert::map_lch_to_srgb_hex, errors};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use super::material_design_3::{M3BaselineColors, M3ColorSet, M3SurfaceSet};
 | 
					use super::material_design_3::{M3BaselineColors, M3ColorSet, M3PaletteSwatch, M3SurfaceSet};
 | 
				
			||||||
pub use constants::Variant;
 | 
					pub use constants::Variant;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod constants;
 | 
					mod constants;
 | 
				
			||||||
@@ -147,6 +147,40 @@ pub fn build_baseline(scheme: &DynamicScheme) -> M3BaselineColors {
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn build_swatches(scheme: &DynamicScheme) -> HashMap<String, M3PaletteSwatch> {
 | 
				
			||||||
 | 
					    let mut swatches = HashMap::new();
 | 
				
			||||||
 | 
					    swatches.insert(
 | 
				
			||||||
 | 
					        "primary".to_string(),
 | 
				
			||||||
 | 
					        M3PaletteSwatch::new(&scheme.primary_palette),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    swatches.insert(
 | 
				
			||||||
 | 
					        "secondary".to_string(),
 | 
				
			||||||
 | 
					        M3PaletteSwatch::new(&scheme.secondary_palette),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    swatches.insert(
 | 
				
			||||||
 | 
					        "tertiary".to_string(),
 | 
				
			||||||
 | 
					        M3PaletteSwatch::new(&scheme.tertiary_palette),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    swatches.insert(
 | 
				
			||||||
 | 
					        "error".to_string(),
 | 
				
			||||||
 | 
					        M3PaletteSwatch::new(&scheme.error_palette),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    swatches.insert(
 | 
				
			||||||
 | 
					        "neutral".to_string(),
 | 
				
			||||||
 | 
					        M3PaletteSwatch::new(&scheme.neutral_palette),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    swatches.insert(
 | 
				
			||||||
 | 
					        "neutral_variant".to_string(),
 | 
				
			||||||
 | 
					        M3PaletteSwatch::new(&scheme.neutral_variant_palette),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (name, palette) in &scheme.custom_palettes {
 | 
				
			||||||
 | 
					        swatches.insert(name.clone(), M3PaletteSwatch::new(palette));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    swatches
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn build_dynamic_scheme(
 | 
					pub fn build_dynamic_scheme(
 | 
				
			||||||
    source_color: &str,
 | 
					    source_color: &str,
 | 
				
			||||||
    error_color: Option<String>,
 | 
					    error_color: Option<String>,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ use std::collections::HashMap;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use material_design_2::MaterialDesign2Scheme;
 | 
					use material_design_2::MaterialDesign2Scheme;
 | 
				
			||||||
use material_design_3::MaterialDesign3Scheme;
 | 
					use material_design_3::MaterialDesign3Scheme;
 | 
				
			||||||
use material_design_3_dynamic::{build_baseline, build_dynamic_scheme, Variant};
 | 
					use material_design_3_dynamic::{build_baseline, build_dynamic_scheme, build_swatches, Variant};
 | 
				
			||||||
use q_style::{QScheme, SchemeSetting};
 | 
					use q_style::{QScheme, SchemeSetting};
 | 
				
			||||||
use swatch_style::{SwatchEntry, SwatchSchemeSetting};
 | 
					use swatch_style::{SwatchEntry, SwatchSchemeSetting};
 | 
				
			||||||
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
 | 
					use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
 | 
				
			||||||
@@ -180,6 +180,7 @@ pub fn generate_material_design_3_dynamic_scheme(
 | 
				
			|||||||
    let scheme = MaterialDesign3Scheme::full_custom(
 | 
					    let scheme = MaterialDesign3Scheme::full_custom(
 | 
				
			||||||
        build_baseline(&light_scheme),
 | 
					        build_baseline(&light_scheme),
 | 
				
			||||||
        build_baseline(&dark_scheme),
 | 
					        build_baseline(&dark_scheme),
 | 
				
			||||||
 | 
					        build_swatches(&light_scheme),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Ok(serde_wasm_bindgen::to_value(&(
 | 
					    Ok(serde_wasm_bindgen::to_value(&(
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user