Compare commits
11 Commits
8efb3ec318
...
b124bb4eda
Author | SHA1 | Date | |
---|---|---|---|
|
b124bb4eda | ||
|
92229b0de4 | ||
|
e3642cad97 | ||
|
59519e1408 | ||
|
56a4786675 | ||
|
838f0c0fa0 | ||
|
9fa05824d2 | ||
|
14851c8284 | ||
|
50646ffccf | ||
|
a9ad4dea5d | ||
|
7b26c95a9a |
|
@ -17,6 +17,7 @@ strum = { version = "0.26.3", features = ["derive", "strum_macros"] }
|
|||
strum_macros = "0.26.4"
|
||||
thiserror = "2.0.9"
|
||||
wasm-bindgen = { version = "0.2.99", features = ["serde", "serde_json", "serde-serialize"] }
|
||||
web-sys = {version = "0.3.77", features = ["console", "Window"]}
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.49"
|
||||
|
|
|
@ -25,28 +25,37 @@ pub struct ColorSet {
|
|||
fn fit_to_wacg(reference: &Oklch, neutral_swatch: &NeutralSwatch, ratio: f32) -> Oklch {
|
||||
let reference_luma = map_oklch_to_luma(reference);
|
||||
let mut new_target = neutral_swatch.get(reference.l);
|
||||
let quick_factor: f32 = if reference.l <= 0.5 { 0.05 } else { -0.05 };
|
||||
let fine_factor: f32 = if reference.l <= 0.5 { 0.01 } else { -0.01 };
|
||||
let factor: f32 = if reference.l <= 0.5 { 0.01 } else { -0.01 };
|
||||
|
||||
let match_wacg = |original: &Oklch<f32>, reference: &Luma| {
|
||||
let luma = map_oklch_to_luma(original);
|
||||
luma.relative_contrast(*reference)
|
||||
};
|
||||
|
||||
while match_wacg(&new_target, &reference_luma) < ratio {
|
||||
new_target.l = new_target.l * (1.0 + quick_factor);
|
||||
if new_target.l > 1.0 {
|
||||
new_target.l = 1.0;
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while match_wacg(&new_target, &reference_luma) < ratio {
|
||||
new_target.l = new_target.l * (1.0 + fine_factor);
|
||||
if new_target.l > 1.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;
|
||||
}
|
||||
} else {
|
||||
repeat_count = 0;
|
||||
}
|
||||
last_contrast_ratio = contrast_ratio;
|
||||
new_target = Oklch {
|
||||
l: new_target.l * (1.0 + factor),
|
||||
..new_target
|
||||
};
|
||||
}
|
||||
|
||||
new_target
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,14 @@ pub struct ColorShifting {
|
|||
pub lightness: f32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl ColorShifting {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(chroma: f32, lightness: f32) -> Self {
|
||||
ColorShifting { chroma, lightness }
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<ColorShifting> for Oklch<f32> {
|
||||
type Output = Oklch<f32>;
|
||||
|
||||
|
@ -143,3 +151,27 @@ impl Default for SchemeSetting {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl SchemeSetting {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(
|
||||
hover: ColorShifting,
|
||||
active: ColorShifting,
|
||||
focus: ColorShifting,
|
||||
disabled: ColorShifting,
|
||||
dark_convert: ColorShifting,
|
||||
expand_method: ColorExpand,
|
||||
wacg_follows: WACGSetting,
|
||||
) -> Self {
|
||||
SchemeSetting {
|
||||
hover,
|
||||
active,
|
||||
focus,
|
||||
disabled,
|
||||
dark_convert,
|
||||
expand_method,
|
||||
wacg_follows,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
76
src/color_functions/color_module.d.ts
vendored
76
src/color_functions/color_module.d.ts
vendored
|
@ -14,20 +14,20 @@ export function relative_differ_in_oklch(color: string, other: string): OklchDif
|
|||
export function tint_scale(basic_color: string, mixed_color: string): MixReversing;
|
||||
export function shade_scale(basic_color: string, mixed_color: string): MixReversing;
|
||||
export function shift_hue(color: string, degree: number): string;
|
||||
export function analogous_30(color: string): (string)[];
|
||||
export function analogous_60(color: string): (string)[];
|
||||
export function analogous_30(color: string): string[];
|
||||
export function analogous_60(color: string): string[];
|
||||
export function complementary(color: string): string;
|
||||
export function split_complementary(color: string): (string)[];
|
||||
export function tetradic(color: string): (string)[];
|
||||
export function triadic(color: string): (string)[];
|
||||
export function generate_palette_from_color(reference_color: string, swatch_amount: number, minimum_lightness: number, maximum_lightness: number, use_reference_color?: boolean, reference_color_bias?: number): (string)[];
|
||||
export function split_complementary(color: string): string[];
|
||||
export function tetradic(color: string): string[];
|
||||
export function triadic(color: string): string[];
|
||||
export function generate_palette_from_color(reference_color: string, swatch_amount: number, minimum_lightness: number, maximum_lightness: number, use_reference_color?: boolean | null, reference_color_bias?: number | null): string[];
|
||||
export function color_categories(): any;
|
||||
export function search_color_cards(tag: string, category?: string): any;
|
||||
export function search_color_cards(tag: string, category?: string | null): any;
|
||||
export function generate_material_design_3_scheme(source_color: string, error_color: string, custom_colors: any): any;
|
||||
export function generate_material_design_2_scheme(primary_color: string, secondary_color: string, error_color: string, custom_colors: any): any;
|
||||
export function generate_q_scheme_automatically(primary_color: string, danger_color: string, success_color: string, warning_color: string, info_color: string, fg_color: string, bg_color: string, setting: SchemeSetting): any;
|
||||
export function generate_q_scheme_manually(primary_color: string, secondary_color: string | undefined, tertiary_color: string | undefined, accent_color: string | undefined, danger_color: string, success_color: string, warning_color: string, info_color: string, fg_color: string, bg_color: string, setting: SchemeSetting): any;
|
||||
export function generate_swatch_scheme(colors: (SwatchEntry)[], setting: SwatchSchemeSetting): any;
|
||||
export function generate_q_scheme_manually(primary_color: string, secondary_color: string | null | undefined, tertiary_color: string | null | undefined, accent_color: string | null | undefined, danger_color: string, success_color: string, warning_color: string, info_color: string, fg_color: string, bg_color: string, setting: SchemeSetting): any;
|
||||
export function generate_swatch_scheme(colors: SwatchEntry[], setting: SwatchSchemeSetting): any;
|
||||
export function lighten(color: string, percent: number): string;
|
||||
export function lighten_absolute(color: string, value: number): string;
|
||||
export function darken(color: string, percent: number): string;
|
||||
|
@ -35,9 +35,9 @@ export function darken_absolute(color: string, value: number): string;
|
|||
export function mix(color1: string, color2: string, percent: number): string;
|
||||
export function tint(color: string, percent: number): string;
|
||||
export function shade(color: string, percent: number): string;
|
||||
export function series(color: string, expand_amount: number, step: number): (string)[];
|
||||
export function tonal_lighten_series(color: string, expand_amount: number, step: number): (string)[];
|
||||
export function tonal_darken_series(color: string, expand_amount: number, step: number): (string)[];
|
||||
export function series(color: string, expand_amount: number, step: number): string[];
|
||||
export function tonal_lighten_series(color: string, expand_amount: number, step: number): string[];
|
||||
export function tonal_darken_series(color: string, expand_amount: number, step: number): string[];
|
||||
export function represent_rgb(color: string): Uint8Array;
|
||||
export function rgb_to_hex(r: number, g: number, b: number): string;
|
||||
export function represent_hsl(color: string): Float32Array;
|
||||
|
@ -64,8 +64,8 @@ export enum WACGSetting {
|
|||
AutomaticAAA = 2,
|
||||
}
|
||||
export class ColorShifting {
|
||||
private constructor();
|
||||
free(): void;
|
||||
constructor(chroma: number, lightness: number);
|
||||
chroma: number;
|
||||
lightness: number;
|
||||
}
|
||||
|
@ -112,8 +112,8 @@ export class RGBDifference {
|
|||
b: Differ;
|
||||
}
|
||||
export class SchemeSetting {
|
||||
private constructor();
|
||||
free(): void;
|
||||
constructor(hover: ColorShifting, active: ColorShifting, focus: ColorShifting, disabled: ColorShifting, dark_convert: ColorShifting, expand_method: ColorExpand, wacg_follows: WACGSetting);
|
||||
hover: ColorShifting;
|
||||
active: ColorShifting;
|
||||
focus: ColorShifting;
|
||||
|
@ -182,15 +182,6 @@ export interface InitOutput {
|
|||
readonly __wbg_set_hctdiffference_chroma: (a: number, b: number) => void;
|
||||
readonly __wbg_get_hctdiffference_lightness: (a: number) => number;
|
||||
readonly __wbg_set_hctdiffference_lightness: (a: number, b: number) => void;
|
||||
readonly __wbg_mixreversing_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_mixreversing_r_factor: (a: number) => number;
|
||||
readonly __wbg_set_mixreversing_r_factor: (a: number, b: number) => void;
|
||||
readonly __wbg_get_mixreversing_g_factor: (a: number) => number;
|
||||
readonly __wbg_set_mixreversing_g_factor: (a: number, b: number) => void;
|
||||
readonly __wbg_get_mixreversing_b_factor: (a: number) => number;
|
||||
readonly __wbg_set_mixreversing_b_factor: (a: number, b: number) => void;
|
||||
readonly __wbg_get_mixreversing_average: (a: number) => number;
|
||||
readonly __wbg_set_mixreversing_average: (a: number, b: number) => void;
|
||||
readonly color_categories: () => [number, number, number];
|
||||
readonly search_color_cards: (a: number, b: number, c: number, d: number) => [number, number, number];
|
||||
readonly __wbg_colorshifting_free: (a: number, b: number) => void;
|
||||
|
@ -198,6 +189,7 @@ export interface InitOutput {
|
|||
readonly __wbg_set_colorshifting_chroma: (a: number, b: number) => void;
|
||||
readonly __wbg_get_colorshifting_lightness: (a: number) => number;
|
||||
readonly __wbg_set_colorshifting_lightness: (a: number, b: number) => void;
|
||||
readonly colorshifting_new: (a: number, b: number) => number;
|
||||
readonly __wbg_schemesetting_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_schemesetting_hover: (a: number) => number;
|
||||
readonly __wbg_set_schemesetting_hover: (a: number, b: number) => void;
|
||||
|
@ -213,18 +205,28 @@ export interface InitOutput {
|
|||
readonly __wbg_set_schemesetting_expand_method: (a: number, b: number) => void;
|
||||
readonly __wbg_get_schemesetting_wacg_follows: (a: number) => number;
|
||||
readonly __wbg_set_schemesetting_wacg_follows: (a: number, b: number) => void;
|
||||
readonly schemesetting_new: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => number;
|
||||
readonly generate_material_design_3_scheme: (a: number, b: number, c: number, d: number, e: any) => [number, number, number];
|
||||
readonly generate_material_design_2_scheme: (a: number, b: number, c: number, d: number, e: number, f: number, g: any) => [number, number, number];
|
||||
readonly generate_q_scheme_automatically: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number) => [number, number, number];
|
||||
readonly generate_q_scheme_manually: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number) => [number, number, number];
|
||||
readonly generate_swatch_scheme: (a: number, b: number, c: number) => [number, number, number];
|
||||
readonly __wbg_hsldifference_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_hsldifference_hue: (a: number) => number;
|
||||
readonly __wbg_set_hsldifference_hue: (a: number, b: number) => void;
|
||||
readonly __wbg_get_hsldifference_saturation: (a: number) => number;
|
||||
readonly __wbg_set_hsldifference_saturation: (a: number, b: number) => void;
|
||||
readonly __wbg_get_hsldifference_lightness: (a: number) => number;
|
||||
readonly __wbg_set_hsldifference_lightness: (a: number, b: number) => void;
|
||||
readonly __wbg_mixreversing_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_mixreversing_r_factor: (a: number) => number;
|
||||
readonly __wbg_set_mixreversing_r_factor: (a: number, b: number) => void;
|
||||
readonly __wbg_get_mixreversing_g_factor: (a: number) => number;
|
||||
readonly __wbg_set_mixreversing_g_factor: (a: number, b: number) => void;
|
||||
readonly __wbg_get_mixreversing_b_factor: (a: number) => number;
|
||||
readonly __wbg_set_mixreversing_b_factor: (a: number, b: number) => void;
|
||||
readonly __wbg_get_mixreversing_average: (a: number) => number;
|
||||
readonly __wbg_set_mixreversing_average: (a: number, b: number) => void;
|
||||
readonly __wbg_rgbdifference_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_rgbdifference_r: (a: number) => number;
|
||||
readonly __wbg_set_rgbdifference_r: (a: number, b: number) => void;
|
||||
readonly __wbg_get_rgbdifference_g: (a: number) => number;
|
||||
readonly __wbg_set_rgbdifference_g: (a: number, b: number) => void;
|
||||
readonly __wbg_get_rgbdifference_b: (a: number) => number;
|
||||
readonly __wbg_set_rgbdifference_b: (a: number, b: number) => void;
|
||||
readonly __wbg_swatchentry_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_swatchentry_name: (a: number) => [number, number];
|
||||
readonly __wbg_set_swatchentry_name: (a: number, b: number, c: number) => void;
|
||||
|
@ -251,13 +253,13 @@ export interface InitOutput {
|
|||
readonly represent_hct: (a: number, b: number) => [number, number, number, number];
|
||||
readonly hct_to_hex: (a: number, b: number, c: number) => [number, number, number, number];
|
||||
readonly wacg_relative_contrast: (a: number, b: number, c: number, d: number) => [number, number, number];
|
||||
readonly __wbg_rgbdifference_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_rgbdifference_r: (a: number) => number;
|
||||
readonly __wbg_set_rgbdifference_r: (a: number, b: number) => void;
|
||||
readonly __wbg_get_rgbdifference_g: (a: number) => number;
|
||||
readonly __wbg_set_rgbdifference_g: (a: number, b: number) => void;
|
||||
readonly __wbg_get_rgbdifference_b: (a: number) => number;
|
||||
readonly __wbg_set_rgbdifference_b: (a: number, b: number) => void;
|
||||
readonly __wbg_hsldifference_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_hsldifference_hue: (a: number) => number;
|
||||
readonly __wbg_set_hsldifference_hue: (a: number, b: number) => void;
|
||||
readonly __wbg_get_hsldifference_saturation: (a: number) => number;
|
||||
readonly __wbg_set_hsldifference_saturation: (a: number, b: number) => void;
|
||||
readonly __wbg_get_hsldifference_lightness: (a: number) => number;
|
||||
readonly __wbg_set_hsldifference_lightness: (a: number, b: number) => void;
|
||||
readonly __wbg_swatchschemesetting_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_swatchschemesetting_amount: (a: number) => number;
|
||||
readonly __wbg_set_swatchschemesetting_amount: (a: number, b: number) => void;
|
||||
|
|
|
@ -410,7 +410,7 @@ function getArrayJsValueFromWasm0(ptr, len) {
|
|||
}
|
||||
/**
|
||||
* @param {string} color
|
||||
* @returns {(string)[]}
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function analogous_30(color) {
|
||||
const ptr0 = passStringToWasm0(color, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -426,7 +426,7 @@ export function analogous_30(color) {
|
|||
|
||||
/**
|
||||
* @param {string} color
|
||||
* @returns {(string)[]}
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function analogous_60(color) {
|
||||
const ptr0 = passStringToWasm0(color, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -467,7 +467,7 @@ export function complementary(color) {
|
|||
|
||||
/**
|
||||
* @param {string} color
|
||||
* @returns {(string)[]}
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function split_complementary(color) {
|
||||
const ptr0 = passStringToWasm0(color, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -483,7 +483,7 @@ export function split_complementary(color) {
|
|||
|
||||
/**
|
||||
* @param {string} color
|
||||
* @returns {(string)[]}
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function tetradic(color) {
|
||||
const ptr0 = passStringToWasm0(color, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -499,7 +499,7 @@ export function tetradic(color) {
|
|||
|
||||
/**
|
||||
* @param {string} color
|
||||
* @returns {(string)[]}
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function triadic(color) {
|
||||
const ptr0 = passStringToWasm0(color, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -523,9 +523,9 @@ function _assertClass(instance, klass) {
|
|||
* @param {number} swatch_amount
|
||||
* @param {number} minimum_lightness
|
||||
* @param {number} maximum_lightness
|
||||
* @param {boolean | undefined} [use_reference_color]
|
||||
* @param {number | undefined} [reference_color_bias]
|
||||
* @returns {(string)[]}
|
||||
* @param {boolean | null} [use_reference_color]
|
||||
* @param {number | null} [reference_color_bias]
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function generate_palette_from_color(reference_color, swatch_amount, minimum_lightness, maximum_lightness, use_reference_color, reference_color_bias) {
|
||||
const ptr0 = passStringToWasm0(reference_color, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -552,7 +552,7 @@ export function color_categories() {
|
|||
|
||||
/**
|
||||
* @param {string} tag
|
||||
* @param {string | undefined} [category]
|
||||
* @param {string | null} [category]
|
||||
* @returns {any}
|
||||
*/
|
||||
export function search_color_cards(tag, category) {
|
||||
|
@ -643,9 +643,9 @@ export function generate_q_scheme_automatically(primary_color, danger_color, suc
|
|||
|
||||
/**
|
||||
* @param {string} primary_color
|
||||
* @param {string | undefined} secondary_color
|
||||
* @param {string | undefined} tertiary_color
|
||||
* @param {string | undefined} accent_color
|
||||
* @param {string | null | undefined} secondary_color
|
||||
* @param {string | null | undefined} tertiary_color
|
||||
* @param {string | null | undefined} accent_color
|
||||
* @param {string} danger_color
|
||||
* @param {string} success_color
|
||||
* @param {string} warning_color
|
||||
|
@ -687,15 +687,15 @@ export function generate_q_scheme_manually(primary_color, secondary_color, terti
|
|||
|
||||
function passArrayJsValueToWasm0(array, malloc) {
|
||||
const ptr = malloc(array.length * 4, 4) >>> 0;
|
||||
const mem = getDataViewMemory0();
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
mem.setUint32(ptr + 4 * i, addToExternrefTable0(array[i]), true);
|
||||
const add = addToExternrefTable0(array[i]);
|
||||
getDataViewMemory0().setUint32(ptr + 4 * i, add, true);
|
||||
}
|
||||
WASM_VECTOR_LEN = array.length;
|
||||
return ptr;
|
||||
}
|
||||
/**
|
||||
* @param {(SwatchEntry)[]} colors
|
||||
* @param {SwatchEntry[]} colors
|
||||
* @param {SwatchSchemeSetting} setting
|
||||
* @returns {any}
|
||||
*/
|
||||
|
@ -900,7 +900,7 @@ export function shade(color, percent) {
|
|||
* @param {string} color
|
||||
* @param {number} expand_amount
|
||||
* @param {number} step
|
||||
* @returns {(string)[]}
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function series(color, expand_amount, step) {
|
||||
const ptr0 = passStringToWasm0(color, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -918,7 +918,7 @@ export function series(color, expand_amount, step) {
|
|||
* @param {string} color
|
||||
* @param {number} expand_amount
|
||||
* @param {number} step
|
||||
* @returns {(string)[]}
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function tonal_lighten_series(color, expand_amount, step) {
|
||||
const ptr0 = passStringToWasm0(color, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -936,7 +936,7 @@ export function tonal_lighten_series(color, expand_amount, step) {
|
|||
* @param {string} color
|
||||
* @param {number} expand_amount
|
||||
* @param {number} step
|
||||
* @returns {(string)[]}
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function tonal_darken_series(color, expand_amount, step) {
|
||||
const ptr0 = passStringToWasm0(color, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -1261,6 +1261,16 @@ export class ColorShifting {
|
|||
set lightness(arg0) {
|
||||
wasm.__wbg_set_colorshifting_lightness(this.__wbg_ptr, arg0);
|
||||
}
|
||||
/**
|
||||
* @param {number} chroma
|
||||
* @param {number} lightness
|
||||
*/
|
||||
constructor(chroma, lightness) {
|
||||
const ret = wasm.colorshifting_new(chroma, lightness);
|
||||
this.__wbg_ptr = ret >>> 0;
|
||||
ColorShiftingFinalization.register(this, this.__wbg_ptr, this);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
const DifferFinalization = (typeof FinalizationRegistry === 'undefined')
|
||||
|
@ -1809,6 +1819,31 @@ export class SchemeSetting {
|
|||
set wacg_follows(arg0) {
|
||||
wasm.__wbg_set_schemesetting_wacg_follows(this.__wbg_ptr, arg0);
|
||||
}
|
||||
/**
|
||||
* @param {ColorShifting} hover
|
||||
* @param {ColorShifting} active
|
||||
* @param {ColorShifting} focus
|
||||
* @param {ColorShifting} disabled
|
||||
* @param {ColorShifting} dark_convert
|
||||
* @param {ColorExpand} expand_method
|
||||
* @param {WACGSetting} wacg_follows
|
||||
*/
|
||||
constructor(hover, active, focus, disabled, dark_convert, expand_method, wacg_follows) {
|
||||
_assertClass(hover, ColorShifting);
|
||||
var ptr0 = hover.__destroy_into_raw();
|
||||
_assertClass(active, ColorShifting);
|
||||
var ptr1 = active.__destroy_into_raw();
|
||||
_assertClass(focus, ColorShifting);
|
||||
var ptr2 = focus.__destroy_into_raw();
|
||||
_assertClass(disabled, ColorShifting);
|
||||
var ptr3 = disabled.__destroy_into_raw();
|
||||
_assertClass(dark_convert, ColorShifting);
|
||||
var ptr4 = dark_convert.__destroy_into_raw();
|
||||
const ret = wasm.schemesetting_new(ptr0, ptr1, ptr2, ptr3, ptr4, expand_method, wacg_follows);
|
||||
this.__wbg_ptr = ret >>> 0;
|
||||
SchemeSettingFinalization.register(this, this.__wbg_ptr, this);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
const SwatchEntryFinalization = (typeof FinalizationRegistry === 'undefined')
|
||||
|
@ -2010,31 +2045,31 @@ function __wbg_get_imports() {
|
|||
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
||||
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
||||
};
|
||||
imports.wbg.__wbg_buffer_61b7ce01341d7f88 = function(arg0) {
|
||||
imports.wbg.__wbg_buffer_609cc3eee51ed158 = function(arg0) {
|
||||
const ret = arg0.buffer;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_call_b0d8e36992d9900d = function() { return handleError(function (arg0, arg1) {
|
||||
imports.wbg.__wbg_call_672a4d21634d4a24 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = arg0.call(arg1);
|
||||
return ret;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_done_f22c1561fa919baa = function(arg0) {
|
||||
imports.wbg.__wbg_done_769e5ede4b31c67b = function(arg0) {
|
||||
const ret = arg0.done;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_entries_4f2bb9b0d701c0f6 = function(arg0) {
|
||||
imports.wbg.__wbg_entries_3265d4158b33e5dc = function(arg0) {
|
||||
const ret = Object.entries(arg0);
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_get_9aa3dff3f0266054 = function(arg0, arg1) {
|
||||
const ret = arg0[arg1 >>> 0];
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_get_bbccf8970793c087 = function() { return handleError(function (arg0, arg1) {
|
||||
imports.wbg.__wbg_get_67b2ba62fc30de12 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = Reflect.get(arg0, arg1);
|
||||
return ret;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_instanceof_ArrayBuffer_670ddde44cdb2602 = function(arg0) {
|
||||
imports.wbg.__wbg_get_b9b93047fe3cf45b = function(arg0, arg1) {
|
||||
const ret = arg0[arg1 >>> 0];
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_ArrayBuffer_e14585432e3737fc = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = arg0 instanceof ArrayBuffer;
|
||||
|
@ -2044,7 +2079,7 @@ function __wbg_get_imports() {
|
|||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_Uint8Array_28af5bc19d6acad8 = function(arg0) {
|
||||
imports.wbg.__wbg_instanceof_Uint8Array_17156bcf118086a9 = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = arg0 instanceof Uint8Array;
|
||||
|
@ -2054,52 +2089,52 @@ function __wbg_get_imports() {
|
|||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_iterator_23604bb983791576 = function() {
|
||||
imports.wbg.__wbg_iterator_9a24c88df860dc65 = function() {
|
||||
const ret = Symbol.iterator;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_length_65d1cd11729ced11 = function(arg0) {
|
||||
imports.wbg.__wbg_length_a446193dc22c12f8 = function(arg0) {
|
||||
const ret = arg0.length;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_length_d65cf0786bfc5739 = function(arg0) {
|
||||
imports.wbg.__wbg_length_e2d2a49132c1b256 = function(arg0) {
|
||||
const ret = arg0.length;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_new_254fa9eac11932ae = function() {
|
||||
const ret = new Array();
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_new_3ff5b33b1ce712df = function(arg0) {
|
||||
const ret = new Uint8Array(arg0);
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_new_688846f374351c92 = function() {
|
||||
imports.wbg.__wbg_new_405e22f390576ce2 = function() {
|
||||
const ret = new Object();
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_new_bc96c6a1c0786643 = function() {
|
||||
imports.wbg.__wbg_new_5e0be73521bc8c17 = function() {
|
||||
const ret = new Map();
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_next_01dd9234a5bf6d05 = function() { return handleError(function (arg0) {
|
||||
const ret = arg0.next();
|
||||
imports.wbg.__wbg_new_78feb108b6472713 = function() {
|
||||
const ret = new Array();
|
||||
return ret;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_next_137428deb98342b0 = function(arg0) {
|
||||
};
|
||||
imports.wbg.__wbg_new_a12002a7f91c75be = function(arg0) {
|
||||
const ret = new Uint8Array(arg0);
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_next_25feadfc0913fea9 = function(arg0) {
|
||||
const ret = arg0.next;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_set_1d80752d0d5f0b21 = function(arg0, arg1, arg2) {
|
||||
imports.wbg.__wbg_next_6574e1a8a62d1055 = function() { return handleError(function (arg0) {
|
||||
const ret = arg0.next();
|
||||
return ret;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_set_37837023f3d740e8 = function(arg0, arg1, arg2) {
|
||||
arg0[arg1 >>> 0] = arg2;
|
||||
};
|
||||
imports.wbg.__wbg_set_23d69db4e5c66a6e = function(arg0, arg1, arg2) {
|
||||
arg0.set(arg1, arg2 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_set_3f1d0b984ed272ed = function(arg0, arg1, arg2) {
|
||||
arg0[arg1] = arg2;
|
||||
};
|
||||
imports.wbg.__wbg_set_76818dc3c59a63d5 = function(arg0, arg1, arg2) {
|
||||
imports.wbg.__wbg_set_65595bdd868b3009 = function(arg0, arg1, arg2) {
|
||||
arg0.set(arg1, arg2 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_set_8fc6bf8a5b1071d1 = function(arg0, arg1, arg2) {
|
||||
const ret = arg0.set(arg1, arg2);
|
||||
return ret;
|
||||
};
|
||||
|
@ -2107,7 +2142,7 @@ function __wbg_get_imports() {
|
|||
const ret = SwatchEntry.__unwrap(arg0);
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_value_4c32fd138a88eee2 = function(arg0) {
|
||||
imports.wbg.__wbg_value_cd1ffa7b1ab794f1 = function(arg0) {
|
||||
const ret = arg0.value;
|
||||
return ret;
|
||||
};
|
||||
|
|
Binary file not shown.
48
src/color_functions/color_module_bg.wasm.d.ts
vendored
48
src/color_functions/color_module_bg.wasm.d.ts
vendored
|
@ -41,15 +41,6 @@ export const __wbg_get_hctdiffference_chroma: (a: number) => number;
|
|||
export const __wbg_set_hctdiffference_chroma: (a: number, b: number) => void;
|
||||
export const __wbg_get_hctdiffference_lightness: (a: number) => number;
|
||||
export const __wbg_set_hctdiffference_lightness: (a: number, b: number) => void;
|
||||
export const __wbg_mixreversing_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_mixreversing_r_factor: (a: number) => number;
|
||||
export const __wbg_set_mixreversing_r_factor: (a: number, b: number) => void;
|
||||
export const __wbg_get_mixreversing_g_factor: (a: number) => number;
|
||||
export const __wbg_set_mixreversing_g_factor: (a: number, b: number) => void;
|
||||
export const __wbg_get_mixreversing_b_factor: (a: number) => number;
|
||||
export const __wbg_set_mixreversing_b_factor: (a: number, b: number) => void;
|
||||
export const __wbg_get_mixreversing_average: (a: number) => number;
|
||||
export const __wbg_set_mixreversing_average: (a: number, b: number) => void;
|
||||
export const color_categories: () => [number, number, number];
|
||||
export const search_color_cards: (a: number, b: number, c: number, d: number) => [number, number, number];
|
||||
export const __wbg_colorshifting_free: (a: number, b: number) => void;
|
||||
|
@ -57,6 +48,7 @@ export const __wbg_get_colorshifting_chroma: (a: number) => number;
|
|||
export const __wbg_set_colorshifting_chroma: (a: number, b: number) => void;
|
||||
export const __wbg_get_colorshifting_lightness: (a: number) => number;
|
||||
export const __wbg_set_colorshifting_lightness: (a: number, b: number) => void;
|
||||
export const colorshifting_new: (a: number, b: number) => number;
|
||||
export const __wbg_schemesetting_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_schemesetting_hover: (a: number) => number;
|
||||
export const __wbg_set_schemesetting_hover: (a: number, b: number) => void;
|
||||
|
@ -72,18 +64,28 @@ export const __wbg_get_schemesetting_expand_method: (a: number) => number;
|
|||
export const __wbg_set_schemesetting_expand_method: (a: number, b: number) => void;
|
||||
export const __wbg_get_schemesetting_wacg_follows: (a: number) => number;
|
||||
export const __wbg_set_schemesetting_wacg_follows: (a: number, b: number) => void;
|
||||
export const schemesetting_new: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => number;
|
||||
export const generate_material_design_3_scheme: (a: number, b: number, c: number, d: number, e: any) => [number, number, number];
|
||||
export const generate_material_design_2_scheme: (a: number, b: number, c: number, d: number, e: number, f: number, g: any) => [number, number, number];
|
||||
export const generate_q_scheme_automatically: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number) => [number, number, number];
|
||||
export const generate_q_scheme_manually: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number, m: number, n: number, o: number, p: number, q: number, r: number, s: number, t: number, u: number) => [number, number, number];
|
||||
export const generate_swatch_scheme: (a: number, b: number, c: number) => [number, number, number];
|
||||
export const __wbg_hsldifference_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_hsldifference_hue: (a: number) => number;
|
||||
export const __wbg_set_hsldifference_hue: (a: number, b: number) => void;
|
||||
export const __wbg_get_hsldifference_saturation: (a: number) => number;
|
||||
export const __wbg_set_hsldifference_saturation: (a: number, b: number) => void;
|
||||
export const __wbg_get_hsldifference_lightness: (a: number) => number;
|
||||
export const __wbg_set_hsldifference_lightness: (a: number, b: number) => void;
|
||||
export const __wbg_mixreversing_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_mixreversing_r_factor: (a: number) => number;
|
||||
export const __wbg_set_mixreversing_r_factor: (a: number, b: number) => void;
|
||||
export const __wbg_get_mixreversing_g_factor: (a: number) => number;
|
||||
export const __wbg_set_mixreversing_g_factor: (a: number, b: number) => void;
|
||||
export const __wbg_get_mixreversing_b_factor: (a: number) => number;
|
||||
export const __wbg_set_mixreversing_b_factor: (a: number, b: number) => void;
|
||||
export const __wbg_get_mixreversing_average: (a: number) => number;
|
||||
export const __wbg_set_mixreversing_average: (a: number, b: number) => void;
|
||||
export const __wbg_rgbdifference_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_rgbdifference_r: (a: number) => number;
|
||||
export const __wbg_set_rgbdifference_r: (a: number, b: number) => void;
|
||||
export const __wbg_get_rgbdifference_g: (a: number) => number;
|
||||
export const __wbg_set_rgbdifference_g: (a: number, b: number) => void;
|
||||
export const __wbg_get_rgbdifference_b: (a: number) => number;
|
||||
export const __wbg_set_rgbdifference_b: (a: number, b: number) => void;
|
||||
export const __wbg_swatchentry_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_swatchentry_name: (a: number) => [number, number];
|
||||
export const __wbg_set_swatchentry_name: (a: number, b: number, c: number) => void;
|
||||
|
@ -110,13 +112,13 @@ export const oklch_to_hex: (a: number, b: number, c: number) => [number, number,
|
|||
export const represent_hct: (a: number, b: number) => [number, number, number, number];
|
||||
export const hct_to_hex: (a: number, b: number, c: number) => [number, number, number, number];
|
||||
export const wacg_relative_contrast: (a: number, b: number, c: number, d: number) => [number, number, number];
|
||||
export const __wbg_rgbdifference_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_rgbdifference_r: (a: number) => number;
|
||||
export const __wbg_set_rgbdifference_r: (a: number, b: number) => void;
|
||||
export const __wbg_get_rgbdifference_g: (a: number) => number;
|
||||
export const __wbg_set_rgbdifference_g: (a: number, b: number) => void;
|
||||
export const __wbg_get_rgbdifference_b: (a: number) => number;
|
||||
export const __wbg_set_rgbdifference_b: (a: number, b: number) => void;
|
||||
export const __wbg_hsldifference_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_hsldifference_hue: (a: number) => number;
|
||||
export const __wbg_set_hsldifference_hue: (a: number, b: number) => void;
|
||||
export const __wbg_get_hsldifference_saturation: (a: number) => number;
|
||||
export const __wbg_set_hsldifference_saturation: (a: number, b: number) => void;
|
||||
export const __wbg_get_hsldifference_lightness: (a: number) => number;
|
||||
export const __wbg_set_hsldifference_lightness: (a: number, b: number) => void;
|
||||
export const __wbg_swatchschemesetting_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_swatchschemesetting_amount: (a: number) => number;
|
||||
export const __wbg_set_swatchschemesetting_amount: (a: number, b: number) => void;
|
||||
|
|
|
@ -18,7 +18,7 @@ export function ActionIcon({ icon, onClick, extendClassName }: ActionIconProps)
|
|||
);
|
||||
|
||||
return (
|
||||
<button onClick={handleClick} className={cx(styles.action_icon, extendClassName)}>
|
||||
<button type="button" onClick={handleClick} className={cx(styles.action_icon, extendClassName)}>
|
||||
<Icon icon={icon} className={styles.icon} />
|
||||
</button>
|
||||
);
|
||||
|
|
44
src/components/FloatColorPicker.module.css
Normal file
44
src/components/FloatColorPicker.module.css
Normal file
|
@ -0,0 +1,44 @@
|
|||
@layer components {
|
||||
.float_color_picker {
|
||||
position: relative;
|
||||
height: 22px;
|
||||
.preview {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: var(--spacing-xs);
|
||||
z-index: 25;
|
||||
.preview_block {
|
||||
height: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
border-radius: var(--border-radius-xxs);
|
||||
border: 1px solid var(--color-border);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
}
|
||||
.picker {
|
||||
position: absolute;
|
||||
top: calc(100% + 4px);
|
||||
padding: var(--spacing-s) var(--spacing-s);
|
||||
border-radius: var(--border-radius-xxs);
|
||||
border: 1px solid var(--color-border);
|
||||
background-color: var(--color-bg);
|
||||
box-shadow: 2px 0 8px oklch(from var(--color-black) l c h / 65%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: var(--spacing-s);
|
||||
z-index: 260;
|
||||
.btns {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
gap: var(--spacing-xs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
56
src/components/FloatColorPicker.tsx
Normal file
56
src/components/FloatColorPicker.tsx
Normal file
|
@ -0,0 +1,56 @@
|
|||
import { isEqual, isNil } from 'lodash-es';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { ActionIcon } from './ActionIcon';
|
||||
import { ColorPicker } from './ColorPicker';
|
||||
import styles from './FloatColorPicker.module.css';
|
||||
|
||||
type FloatColorPickerProps = {
|
||||
name?: string;
|
||||
color?: string;
|
||||
onPick?: (color: string | null | undefined) => void;
|
||||
};
|
||||
|
||||
export function FloatColorPicker({ name, color, onPick }: FloatColorPickerProps) {
|
||||
const [pickedColor, setPicked] = useState<string | null>(color ?? null);
|
||||
const [showPicker, setPickerShow] = useState(false);
|
||||
const handlePickAction = useCallback(
|
||||
(value: string) => {
|
||||
setPicked(value);
|
||||
onPick?.(value);
|
||||
},
|
||||
[onPick],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isEqual(pickedColor, color)) {
|
||||
setPicked(color);
|
||||
}
|
||||
}, [color]);
|
||||
|
||||
return (
|
||||
<div className={styles.float_color_picker}>
|
||||
<div className={styles.preview}>
|
||||
<div
|
||||
className={styles.preview_block}
|
||||
onClick={() => setPickerShow(true)}
|
||||
style={{
|
||||
backgroundColor: isNil(pickedColor) ? 'rgba(0, 0, 0, 0)' : `#${pickedColor}`,
|
||||
}}>
|
||||
{isNil(pickedColor) && <span>N/A</span>}
|
||||
</div>
|
||||
<ActionIcon icon="tabler:x" onClick={() => handlePickAction(null)} />
|
||||
</div>
|
||||
{showPicker && (
|
||||
<div className={styles.picker}>
|
||||
<ColorPicker color={pickedColor ?? null} onSelect={handlePickAction} />
|
||||
<div className={styles.btns}>
|
||||
<button type="button" className="primary" onClick={() => setPickerShow(false)}>
|
||||
Done
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{!isNil(name) && <input type="hidden" name={name} value={pickedColor ?? ''} />}
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -31,4 +31,7 @@ export type MaterialDesign2SchemeSource = {
|
|||
export type MaterialDesign2SchemeStorage = {
|
||||
source?: MaterialDesign2SchemeSource;
|
||||
scheme?: MaterialDesign2Scheme;
|
||||
cssVariables?: string;
|
||||
scssVariables?: string;
|
||||
jsVariables?: string;
|
||||
};
|
||||
|
|
|
@ -54,4 +54,7 @@ export type MaterialDesign3SchemeSource = {
|
|||
export type MaterialDesign3SchemeStorage = {
|
||||
source?: MaterialDesign3SchemeSource;
|
||||
scheme?: MaterialDesign3Scheme;
|
||||
cssVariables?: string;
|
||||
scssVariables?: string;
|
||||
jsVariables?: string;
|
||||
};
|
||||
|
|
37
src/page-components/scheme/q-scheme/Builder.module.css
Normal file
37
src/page-components/scheme/q-scheme/Builder.module.css
Normal file
|
@ -0,0 +1,37 @@
|
|||
@layer pages {
|
||||
.builder_layout {
|
||||
padding: var(--spacing-s) var(--spacing-m);
|
||||
font-size: var(--font-size-s);
|
||||
line-height: 1.3em;
|
||||
display: grid;
|
||||
grid-template-columns: 200px 200px 200px;
|
||||
gap: var(--spacing-xs);
|
||||
.label {
|
||||
max-width: 200px;
|
||||
grid-column: 1;
|
||||
padding-inline-end: var(--spacing-m);
|
||||
text-align: right;
|
||||
}
|
||||
.color_picker_row {
|
||||
grid-column: 2 / span 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-s);
|
||||
.error_msg {
|
||||
color: var(--color-danger);
|
||||
font-size: var(--font-size-xs);
|
||||
}
|
||||
}
|
||||
.segment_title {
|
||||
grid-column: 1 / span 2;
|
||||
text-align: center;
|
||||
}
|
||||
.parameter_input {
|
||||
max-width: 8em;
|
||||
}
|
||||
h5 {
|
||||
font-size: var(--font-size-m);
|
||||
line-height: 1.7em;
|
||||
}
|
||||
}
|
||||
}
|
378
src/page-components/scheme/q-scheme/Builder.tsx
Normal file
378
src/page-components/scheme/q-scheme/Builder.tsx
Normal file
|
@ -0,0 +1,378 @@
|
|||
import { every, isEmpty, isNil } from 'lodash-es';
|
||||
import { useActionState, useMemo } from 'react';
|
||||
import {
|
||||
ColorExpand,
|
||||
ColorShifting,
|
||||
SchemeSetting,
|
||||
WACGSetting,
|
||||
} from '../../../color_functions/color_module';
|
||||
import { useColorFunction } from '../../../ColorFunctionContext';
|
||||
import { FloatColorPicker } from '../../../components/FloatcolorPicker';
|
||||
import { ScrollArea } from '../../../components/ScrollArea';
|
||||
import { VSegmentedControl } from '../../../components/VSegmentedControl';
|
||||
import { SchemeContent } from '../../../models';
|
||||
import { QSchemeSource, QSchemeStorage } from '../../../q-scheme';
|
||||
import { useUpdateScheme } from '../../../stores/schemes';
|
||||
import { defaultEmptyFormData } from '../../../utls';
|
||||
import styles from './Builder.module.css';
|
||||
|
||||
type QSchemeBuilderProps = {
|
||||
scheme: SchemeContent<QSchemeStorage>;
|
||||
};
|
||||
|
||||
export function QSchemeBuilder({ scheme }: QSchemeBuilderProps) {
|
||||
const { colorFn } = useColorFunction();
|
||||
const updateScheme = useUpdateScheme(scheme.id);
|
||||
const defaultSetting = useMemo(() => {
|
||||
try {
|
||||
if (!colorFn) throw 'Web Assembly functions is not available';
|
||||
const defaultValues = colorFn.q_scheme_default_settings();
|
||||
if (!scheme.schemeStorage.source?.setting)
|
||||
return {
|
||||
hover: {
|
||||
chroma:
|
||||
scheme.schemeStorage.source?.setting?.hover.chroma ?? defaultValues.hover.chroma,
|
||||
lightness:
|
||||
scheme.schemeStorage.source?.setting?.hover.lightness ??
|
||||
defaultValues.hover.lightness,
|
||||
},
|
||||
active: {
|
||||
chroma:
|
||||
scheme.schemeStorage.source?.setting?.active.chroma ?? defaultValues.active.chroma,
|
||||
lightness:
|
||||
scheme.schemeStorage.source?.setting?.active.lightness ??
|
||||
defaultValues.active.lightness,
|
||||
},
|
||||
focus: {
|
||||
chroma:
|
||||
scheme.schemeStorage.source?.setting?.focus.chroma ?? defaultValues.focus.chroma,
|
||||
lightness:
|
||||
scheme.schemeStorage.source?.setting?.focus.lightness ??
|
||||
defaultValues.focus.lightness,
|
||||
},
|
||||
disabled: {
|
||||
chroma:
|
||||
scheme.schemeStorage.source?.setting?.disabled.chroma ??
|
||||
defaultValues.disabled.chroma,
|
||||
lightness:
|
||||
scheme.schemeStorage.source?.setting?.disabled.lightness ??
|
||||
defaultValues.disabled.lightness,
|
||||
},
|
||||
dark_convert: {
|
||||
chroma:
|
||||
scheme.schemeStorage.source?.setting?.dark_convert.chroma ??
|
||||
defaultValues.dark_convert.chroma,
|
||||
lightness:
|
||||
scheme.schemeStorage.source?.setting?.dark_convert.lightness ??
|
||||
defaultValues.dark_convert.lightness,
|
||||
},
|
||||
expand_method:
|
||||
scheme.schemeStorage.source?.setting?.expand_method ?? defaultValues.expand_method,
|
||||
wacg_follows:
|
||||
scheme.schemeStorage.source?.setting?.wacg_follows ?? defaultValues.wacg_follows,
|
||||
} as SchemeSetting;
|
||||
return defaultValues;
|
||||
} catch (e) {
|
||||
console.error('[Q scheme builder]', e);
|
||||
}
|
||||
return null;
|
||||
}, [scheme]);
|
||||
const expandingMethods = useMemo(() => {
|
||||
try {
|
||||
if (!colorFn) throw 'Web Assembly functions is not available';
|
||||
return colorFn.q_scheme_color_expanding_methods();
|
||||
} catch (e) {
|
||||
console.error('[Q scheme builder]', e);
|
||||
}
|
||||
return [];
|
||||
}, []);
|
||||
const wacgFollowStrategies = useMemo(() => {
|
||||
try {
|
||||
if (!colorFn) throw 'Web Assembly functions is not available';
|
||||
return colorFn.q_scheme_wacg_settings();
|
||||
} catch (e) {
|
||||
console.error('[Q scheme builder]', e);
|
||||
}
|
||||
return [];
|
||||
}, []);
|
||||
|
||||
const [errMsg, handleSubmitAction] = useActionState((state, formData) => {
|
||||
const errMsg = new Map<string, string>();
|
||||
const requiredFields = [
|
||||
'primary',
|
||||
'danger',
|
||||
'success',
|
||||
'warn',
|
||||
'info',
|
||||
'foreground',
|
||||
'background',
|
||||
];
|
||||
for (const field of requiredFields) {
|
||||
if (!formData.get(field)) {
|
||||
errMsg.set(field, 'This color is required for scheme generating.');
|
||||
}
|
||||
}
|
||||
if (!isEmpty(errMsg)) return errMsg;
|
||||
try {
|
||||
const schemeSetting = new SchemeSetting(
|
||||
new ColorShifting(
|
||||
Number(formData.get('hover_chroma')) / 100,
|
||||
Number(formData.get('hover_lightness')) / 100,
|
||||
),
|
||||
new ColorShifting(
|
||||
Number(formData.get('active_chroma')) / 100,
|
||||
Number(formData.get('active_lightness')) / 100,
|
||||
),
|
||||
new ColorShifting(
|
||||
Number(formData.get('focus_chroma')) / 100,
|
||||
Number(formData.get('focus_lightness')) / 100,
|
||||
),
|
||||
new ColorShifting(
|
||||
Number(formData.get('disabled_chroma')) / 100,
|
||||
Number(formData.get('disabled_lightness')) / 100,
|
||||
),
|
||||
new ColorShifting(
|
||||
Number(formData.get('dark_chroma')) / 100,
|
||||
Number(formData.get('dark_lightness')) / 100,
|
||||
),
|
||||
Number(formData.get('expanding')) as ColorExpand,
|
||||
Number(formData.get('wacg')) as WACGSetting,
|
||||
);
|
||||
|
||||
const source: QSchemeSource = {
|
||||
primary: defaultEmptyFormData(formData, 'primary', null),
|
||||
secondary: defaultEmptyFormData(formData, 'secondary', undefined),
|
||||
tertiary: defaultEmptyFormData(formData, 'tertiary', undefined),
|
||||
accent: defaultEmptyFormData(formData, 'accent', undefined),
|
||||
danger: defaultEmptyFormData(formData, 'danger', null),
|
||||
success: defaultEmptyFormData(formData, 'success', null),
|
||||
warning: defaultEmptyFormData(formData, 'warn', null),
|
||||
info: defaultEmptyFormData(formData, 'info', null),
|
||||
foreground: defaultEmptyFormData(formData, 'foreground', null),
|
||||
background: defaultEmptyFormData(formData, 'background', null),
|
||||
setting: schemeSetting,
|
||||
};
|
||||
console.debug('[collected]', source);
|
||||
const generatedScheme = every([source.secondary, source.tertiary, source.accent], isNil)
|
||||
? colorFn?.generate_q_scheme_automatically(
|
||||
source.primary,
|
||||
source.danger,
|
||||
source.success,
|
||||
source.warning,
|
||||
source.info,
|
||||
source.foreground,
|
||||
source.background,
|
||||
source.setting,
|
||||
)
|
||||
: colorFn?.generate_q_scheme_manually(
|
||||
source.primary,
|
||||
source.secondary ?? undefined,
|
||||
source.tertiary ?? undefined,
|
||||
source.accent ?? undefined,
|
||||
source.danger,
|
||||
source.success,
|
||||
source.warning,
|
||||
source.info,
|
||||
source.foreground,
|
||||
source.background,
|
||||
source.setting,
|
||||
);
|
||||
updateScheme((prev) => {
|
||||
prev.schemeStorage.source = source;
|
||||
prev.schemeStorage.scheme = generatedScheme[0];
|
||||
prev.schemeStorage.cssVariables = generatedScheme[1];
|
||||
prev.schemeStorage.scssVariables = generatedScheme[2];
|
||||
prev.schemeStorage.jsVariables = generatedScheme[3];
|
||||
return prev;
|
||||
});
|
||||
console.debug('[generated]', generatedScheme);
|
||||
} catch (e) {
|
||||
console.error('[build q scheme]', e);
|
||||
}
|
||||
|
||||
return errMsg;
|
||||
}, new Map<string, string>());
|
||||
|
||||
return (
|
||||
<ScrollArea enableY>
|
||||
<form action={handleSubmitAction} className={styles.builder_layout}>
|
||||
<h5 className={styles.segment_title}>Original Colors</h5>
|
||||
<label className={styles.label}>Primary Color*</label>
|
||||
<div className={styles.color_picker_row}>
|
||||
<FloatColorPicker name="primary" color={scheme.schemeStorage.source?.primary} />
|
||||
{errMsg.has('primary') && (
|
||||
<span className={styles.error_msg}>{errMsg.get('primary')}</span>
|
||||
)}
|
||||
</div>
|
||||
<label className={styles.label}>Secondary Color</label>
|
||||
<div className={styles.color_picker_row}>
|
||||
<FloatColorPicker name="secondary" color={scheme.schemeStorage.source?.secondary} />
|
||||
</div>
|
||||
<label className={styles.label}>Tertiary Color</label>
|
||||
<div className={styles.color_picker_row}>
|
||||
<FloatColorPicker name="tertiary" color={scheme.schemeStorage.source?.tertiary} />
|
||||
</div>
|
||||
<label className={styles.label}>Accent Color</label>
|
||||
<div className={styles.color_picker_row}>
|
||||
<FloatColorPicker name="accent" color={scheme.schemeStorage.source?.accent} />
|
||||
</div>
|
||||
<label className={styles.label}>Danger Color*</label>
|
||||
<div className={styles.color_picker_row}>
|
||||
<FloatColorPicker name="danger" color={scheme.schemeStorage.source?.danger} />
|
||||
{errMsg.has('danger') && <span className={styles.error_msg}>{errMsg.get('danger')}</span>}
|
||||
</div>
|
||||
<label className={styles.label}>Success Color*</label>
|
||||
<div className={styles.color_picker_row}>
|
||||
<FloatColorPicker name="success" color={scheme.schemeStorage.source?.success} />
|
||||
{errMsg.has('success') && (
|
||||
<span className={styles.error_msg}>{errMsg.get('success')}</span>
|
||||
)}
|
||||
</div>
|
||||
<label className={styles.label}>Warning Color*</label>
|
||||
<div className={styles.color_picker_row}>
|
||||
<FloatColorPicker name="warn" color={scheme.schemeStorage.source?.warning} />
|
||||
{errMsg.has('warn') && <span className={styles.error_msg}>{errMsg.get('warn')}</span>}
|
||||
</div>
|
||||
<label className={styles.label}>Info Color*</label>
|
||||
<div className={styles.color_picker_row}>
|
||||
<FloatColorPicker name="info" color={scheme.schemeStorage.source?.info} />
|
||||
{errMsg.has('info') && <span className={styles.error_msg}>{errMsg.get('info')}</span>}
|
||||
</div>
|
||||
<label className={styles.label}>Foreground Color*</label>
|
||||
<div className={styles.color_picker_row}>
|
||||
<FloatColorPicker name="foreground" color={scheme.schemeStorage.source?.foreground} />
|
||||
{errMsg.has('foreground') && (
|
||||
<span className={styles.error_msg}>{errMsg.get('foreground')}</span>
|
||||
)}
|
||||
</div>
|
||||
<label className={styles.label}>Background Color*</label>
|
||||
<div className={styles.color_picker_row}>
|
||||
<FloatColorPicker name="background" color={scheme.schemeStorage.source?.background} />
|
||||
{errMsg.has('background') && (
|
||||
<span className={styles.error_msg}>{errMsg.get('background')}</span>
|
||||
)}
|
||||
</div>
|
||||
<h5 className={styles.segment_title}>Automated parameters</h5>
|
||||
<label style={{ gridColumn: 2 }}>Chroma shifting</label>
|
||||
<label style={{ gridColumn: 3 }}>Lightness shifting</label>
|
||||
<label className={styles.label}>Hover</label>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="hover_chroma"
|
||||
defaultValue={((defaultSetting?.hover.chroma ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="hover_lightness"
|
||||
defaultValue={((defaultSetting?.hover.lightness ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<label className={styles.label}>Active</label>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="active_chroma"
|
||||
defaultValue={((defaultSetting?.active.chroma ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="active_lightness"
|
||||
defaultValue={((defaultSetting?.active.lightness ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<label className={styles.label}>Focus</label>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="focus_chroma"
|
||||
defaultValue={((defaultSetting?.focus.chroma ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="focus_lightness"
|
||||
defaultValue={((defaultSetting?.focus.lightness ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<label className={styles.label}>Disabled</label>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="disabled_chroma"
|
||||
defaultValue={((defaultSetting?.disabled.chroma ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="disabled_lightness"
|
||||
defaultValue={((defaultSetting?.disabled.lightness ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<label className={styles.label}>Convert to Dark scheme</label>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="dark_chroma"
|
||||
defaultValue={((defaultSetting?.dark_convert.chroma ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<div className="input_wrapper">
|
||||
<input
|
||||
type="number"
|
||||
name="dark_lightness"
|
||||
defaultValue={((defaultSetting?.dark_convert.lightness ?? 0) * 100).toFixed(2)}
|
||||
className={styles.parameter_input}
|
||||
/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<h5 className={styles.segment_title}>Settings</h5>
|
||||
<label className={styles.label}>Color Expanding Method</label>
|
||||
<div style={{ gridColumn: '2 / span 2' }}>
|
||||
<VSegmentedControl
|
||||
options={expandingMethods}
|
||||
name="expanding"
|
||||
defaultValue={defaultSetting?.expand_method}
|
||||
/>
|
||||
</div>
|
||||
<label className={styles.label}>Follow WACG Standard</label>
|
||||
<div style={{ gridColumn: '2 / span 2' }}>
|
||||
<VSegmentedControl
|
||||
options={wacgFollowStrategies}
|
||||
name="wacg"
|
||||
defaultValue={defaultSetting?.wacg_follows}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ gridColumn: '2 / span 2' }}>
|
||||
<button type="submit" className="primary">
|
||||
Build Scheme
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</ScrollArea>
|
||||
);
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
import { SchemeSetting } from './color_functions/color_module';
|
||||
import { ColorShifting } from './models';
|
||||
|
||||
export type ColorSet = {
|
||||
|
@ -54,10 +55,13 @@ export type QSchemeSource = {
|
|||
info: string | null;
|
||||
foreground: string | null;
|
||||
background: strin | nullg;
|
||||
setting: QSchemeSetting | null;
|
||||
setting: SchemeSetting | null;
|
||||
};
|
||||
|
||||
export type QSchemeStorage = {
|
||||
source?: QSchemeSource;
|
||||
scheme?: QScheme;
|
||||
cssVariables?: string;
|
||||
scssVariables?: string;
|
||||
jsVariables?: string;
|
||||
};
|
||||
|
|
|
@ -13,4 +13,7 @@ export type SwatchSchemeSource = {
|
|||
export type SwatchSchemeStorage = {
|
||||
source?: SwatchSchemeSource;
|
||||
scheme?: SwatchScheme;
|
||||
cssVariables?: string;
|
||||
scssVariables?: string;
|
||||
jsVariables?: string;
|
||||
};
|
||||
|
|
16
src/utls.ts
Normal file
16
src/utls.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { isEmpty, isNil } from 'lodash-es';
|
||||
|
||||
export function defaultEmptyFormData<D>(formData: FormData, param: string, defaultValue: D): D {
|
||||
const value = formData.get(param);
|
||||
if (isNil(value) || isEmpty(value)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function defaultEmptyValue<T, D>(value: T, defaultValue: D): T | D {
|
||||
if (isNil(value) || isEmpty(value)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return value;
|
||||
}
|
Loading…
Reference in New Issue
Block a user