Compare commits
2 Commits
b126858d8e
...
c9626f3b8e
Author | SHA1 | Date | |
---|---|---|---|
|
c9626f3b8e | ||
|
b3cdb517a5 |
|
@ -15,6 +15,7 @@ use wasm_bindgen::prelude::*;
|
|||
mod color_card;
|
||||
mod color_differ;
|
||||
mod errors;
|
||||
mod palettes;
|
||||
mod reversing;
|
||||
|
||||
#[wasm_bindgen]
|
||||
|
|
94
color-module/src/palettes/auto_palette.rs
Normal file
94
color-module/src/palettes/auto_palette.rs
Normal file
|
@ -0,0 +1,94 @@
|
|||
use palette::{FromColor, Oklch, Srgb};
|
||||
use std::str::FromStr;
|
||||
use wasm_bindgen::prelude::wasm_bindgen;
|
||||
|
||||
use crate::errors;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn generate_palette_from_color(
|
||||
reference_color: &str,
|
||||
swatch_amount: i16,
|
||||
minimum_lightness: f32,
|
||||
maximum_lightness: f32,
|
||||
use_reference_color: Option<bool>,
|
||||
reference_color_bias: Option<i16>,
|
||||
) -> Result<Vec<String>, errors::ColorError> {
|
||||
let reference_color_bias = reference_color_bias.unwrap_or(0);
|
||||
let original_color = Oklch::from_color(
|
||||
Srgb::from_str(reference_color)
|
||||
.map_err(|_| errors::ColorError::UnrecogniazedRGB(reference_color.to_string()))?
|
||||
.into_format::<f32>(),
|
||||
);
|
||||
match use_reference_color {
|
||||
Some(true) => Ok(generate_incontinuous_palette(
|
||||
&original_color,
|
||||
swatch_amount,
|
||||
minimum_lightness,
|
||||
maximum_lightness,
|
||||
reference_color_bias,
|
||||
)),
|
||||
Some(false) | None => Ok(generate_continuous_palette(
|
||||
&original_color,
|
||||
swatch_amount,
|
||||
minimum_lightness,
|
||||
maximum_lightness,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_continuous_palette(
|
||||
original_color: &Oklch,
|
||||
swatch_amount: i16,
|
||||
minimum_lightness: f32,
|
||||
maximum_lightness: f32,
|
||||
) -> Vec<String> {
|
||||
let mut palette = Vec::new();
|
||||
|
||||
let step = (maximum_lightness - minimum_lightness) / (swatch_amount - 1) as f32;
|
||||
for i in 0..swatch_amount {
|
||||
let lightness = minimum_lightness + step * i as f32;
|
||||
let color = Oklch {
|
||||
l: lightness,
|
||||
..*original_color
|
||||
};
|
||||
palette.push(format!("{:x}", Srgb::from_color(color).into_format::<u8>()));
|
||||
}
|
||||
|
||||
palette
|
||||
}
|
||||
|
||||
fn generate_incontinuous_palette(
|
||||
original_color: &Oklch,
|
||||
swatch_amount: i16,
|
||||
minimum_lightness: f32,
|
||||
maximum_lightness: f32,
|
||||
original_place: i16,
|
||||
) -> Vec<String> {
|
||||
let mut palette = Vec::new();
|
||||
|
||||
let midpoint = swatch_amount / 2;
|
||||
let dark_side_amount = midpoint + original_place;
|
||||
|
||||
let step = (original_color.l - minimum_lightness) / dark_side_amount as f32;
|
||||
for i in 0..dark_side_amount {
|
||||
let lightness = minimum_lightness + step * i as f32;
|
||||
let color = Oklch {
|
||||
l: lightness,
|
||||
..*original_color
|
||||
};
|
||||
palette.push(format!("{:x}", Srgb::from_color(color).into_format::<u8>()));
|
||||
}
|
||||
|
||||
let light_side_amount = swatch_amount - dark_side_amount;
|
||||
let step = (maximum_lightness - original_color.l) / (light_side_amount - 1) as f32;
|
||||
for i in 0..light_side_amount {
|
||||
let lightness = original_color.l + step * i as f32;
|
||||
let color = Oklch {
|
||||
l: lightness,
|
||||
..*original_color
|
||||
};
|
||||
palette.push(format!("{:x}", Srgb::from_color(color).into_format::<u8>()));
|
||||
}
|
||||
|
||||
palette
|
||||
}
|
1
color-module/src/palettes/mod.rs
Normal file
1
color-module/src/palettes/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod auto_palette;
|
44
src/color_functions/color_module.d.ts
vendored
44
src/color_functions/color_module.d.ts
vendored
|
@ -40,6 +40,7 @@ export function differ_in_oklch(color: string, other: string): OklchDifference;
|
|||
export function relative_differ_in_oklch(color: string, other: string): OklchDifference;
|
||||
export function tint_scale(basic_color: string, mixed_color: string): MixReversing;
|
||||
export function shade_scale(basic_color: string, mixed_color: string): MixReversing;
|
||||
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 class Differ {
|
||||
private constructor();
|
||||
free(): void;
|
||||
|
@ -132,6 +133,20 @@ export interface InitOutput {
|
|||
readonly __wbg_set_differ_delta: (a: number, b: number) => void;
|
||||
readonly __wbg_get_differ_percent: (a: number) => number;
|
||||
readonly __wbg_set_differ_percent: (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_oklchdifference_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_oklchdifference_hue: (a: number) => number;
|
||||
readonly __wbg_set_oklchdifference_hue: (a: number, b: number) => void;
|
||||
readonly __wbg_get_oklchdifference_chroma: (a: number) => number;
|
||||
readonly __wbg_set_oklchdifference_chroma: (a: number, b: number) => void;
|
||||
readonly __wbg_get_oklchdifference_lightness: (a: number) => number;
|
||||
readonly __wbg_set_oklchdifference_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;
|
||||
|
@ -141,27 +156,6 @@ export interface InitOutput {
|
|||
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_oklchdifference_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_oklchdifference_hue: (a: number) => number;
|
||||
readonly __wbg_set_oklchdifference_hue: (a: number, b: number) => void;
|
||||
readonly __wbg_get_oklchdifference_chroma: (a: number) => number;
|
||||
readonly __wbg_set_oklchdifference_chroma: (a: number, b: number) => void;
|
||||
readonly __wbg_get_oklchdifference_lightness: (a: number) => number;
|
||||
readonly __wbg_set_oklchdifference_lightness: (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_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_hctdiffference_free: (a: number, b: number) => void;
|
||||
readonly __wbg_get_hctdiffference_hue: (a: number) => number;
|
||||
readonly __wbg_set_hctdiffference_hue: (a: number, b: number) => void;
|
||||
|
@ -169,6 +163,14 @@ 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_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 generate_palette_from_color: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number, number, number];
|
||||
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
||||
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
||||
readonly __wbindgen_export_2: WebAssembly.Table;
|
||||
|
|
|
@ -914,6 +914,26 @@ function _assertClass(instance, klass) {
|
|||
throw new Error(`expected instance of ${klass.name}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param {string} reference_color
|
||||
* @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)[]}
|
||||
*/
|
||||
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);
|
||||
const len0 = WASM_VECTOR_LEN;
|
||||
const ret = wasm.generate_palette_from_color(ptr0, len0, swatch_amount, minimum_lightness, maximum_lightness, isLikeNone(use_reference_color) ? 0xFFFFFF : use_reference_color ? 1 : 0, isLikeNone(reference_color_bias) ? 0xFFFFFF : reference_color_bias);
|
||||
if (ret[3]) {
|
||||
throw takeFromExternrefTable0(ret[2]);
|
||||
}
|
||||
var v2 = getArrayJsValueFromWasm0(ret[0], ret[1]).slice();
|
||||
wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
|
||||
return v2;
|
||||
}
|
||||
|
||||
const DifferFinalization = (typeof FinalizationRegistry === 'undefined')
|
||||
? { register: () => {}, unregister: () => {} }
|
||||
|
|
Binary file not shown.
43
src/color_functions/color_module_bg.wasm.d.ts
vendored
43
src/color_functions/color_module_bg.wasm.d.ts
vendored
|
@ -46,6 +46,20 @@ export const __wbg_get_differ_delta: (a: number) => number;
|
|||
export const __wbg_set_differ_delta: (a: number, b: number) => void;
|
||||
export const __wbg_get_differ_percent: (a: number) => number;
|
||||
export const __wbg_set_differ_percent: (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_oklchdifference_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_oklchdifference_hue: (a: number) => number;
|
||||
export const __wbg_set_oklchdifference_hue: (a: number, b: number) => void;
|
||||
export const __wbg_get_oklchdifference_chroma: (a: number) => number;
|
||||
export const __wbg_set_oklchdifference_chroma: (a: number, b: number) => void;
|
||||
export const __wbg_get_oklchdifference_lightness: (a: number) => number;
|
||||
export const __wbg_set_oklchdifference_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;
|
||||
|
@ -55,27 +69,6 @@ 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_oklchdifference_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_oklchdifference_hue: (a: number) => number;
|
||||
export const __wbg_set_oklchdifference_hue: (a: number, b: number) => void;
|
||||
export const __wbg_get_oklchdifference_chroma: (a: number) => number;
|
||||
export const __wbg_set_oklchdifference_chroma: (a: number, b: number) => void;
|
||||
export const __wbg_get_oklchdifference_lightness: (a: number) => number;
|
||||
export const __wbg_set_oklchdifference_lightness: (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_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_hctdiffference_free: (a: number, b: number) => void;
|
||||
export const __wbg_get_hctdiffference_hue: (a: number) => number;
|
||||
export const __wbg_set_hctdiffference_hue: (a: number, b: number) => void;
|
||||
|
@ -83,6 +76,14 @@ 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_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 generate_palette_from_color: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number, number, number];
|
||||
export const __wbindgen_malloc: (a: number, b: number) => number;
|
||||
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
||||
export const __wbindgen_export_2: WebAssembly.Table;
|
||||
|
|
55
src/page-components/auto-palette/PaletteColors.tsx
Normal file
55
src/page-components/auto-palette/PaletteColors.tsx
Normal file
|
@ -0,0 +1,55 @@
|
|||
import { useMemo } from 'react';
|
||||
import { useColorFunction } from '../../ColorFunctionContext';
|
||||
import { FlexColorStand } from '../../components/FlexColorStand';
|
||||
|
||||
type PaletteColorsProps = {
|
||||
color: string;
|
||||
swatchAmount: number;
|
||||
referenceBias: number;
|
||||
useReference: boolean;
|
||||
min: number;
|
||||
max: number;
|
||||
copyMode: 'hex' | 'rgb' | 'hsl' | 'lab' | 'oklch';
|
||||
};
|
||||
|
||||
export function PaletteColors({
|
||||
color = '000000',
|
||||
swatchAmount,
|
||||
referenceBias,
|
||||
useReference,
|
||||
min,
|
||||
max,
|
||||
copyMode,
|
||||
}: PaletteColorsProps) {
|
||||
const { colorFn } = useColorFunction();
|
||||
const colors = useMemo(() => {
|
||||
if (!colorFn) {
|
||||
return Array.from({ length: swatchAmount }, () => color);
|
||||
}
|
||||
try {
|
||||
if (!useReference) {
|
||||
return colorFn.generate_palette_from_color(color, swatchAmount, min, max);
|
||||
} else {
|
||||
return colorFn.generate_palette_from_color(
|
||||
color,
|
||||
swatchAmount,
|
||||
min,
|
||||
max,
|
||||
useReference,
|
||||
referenceBias,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[Generate Auto Palette]', e);
|
||||
}
|
||||
return Array.from({ length: swatchAmount }, () => color);
|
||||
}, [color, swatchAmount, referenceBias, useReference, min, max]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{colors.map((c, index) => (
|
||||
<FlexColorStand key={`${c}-${index}`} color={c} valueMode={copyMode} />
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -43,5 +43,13 @@
|
|||
gap: var(--spacing-s);
|
||||
font-size: var(--font-size-s);
|
||||
}
|
||||
.colors_booth {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
gap: var(--spacing-xs);
|
||||
min-height: 12em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import { Labeled } from '../components/Labeled';
|
|||
import { LabeledPicker } from '../components/LabeledPicker';
|
||||
import { ScrollArea } from '../components/ScrollArea';
|
||||
import { Switch } from '../components/Switch';
|
||||
import { PaletteColors } from '../page-components/auto-palette/PaletteColors';
|
||||
import { currentPickedColor } from '../stores/colors';
|
||||
import styles from './Palette.module.css';
|
||||
|
||||
|
@ -53,14 +54,14 @@ export function AutomaticPalette() {
|
|||
<LabeledPicker
|
||||
title="Swatch Amount"
|
||||
min={3}
|
||||
max={15}
|
||||
max={12}
|
||||
step={1}
|
||||
value={swatchAmount}
|
||||
onChange={(value) => setSwatchAmount(value)}
|
||||
/>
|
||||
<LabeledPicker
|
||||
title="Reference Bias"
|
||||
min={0}
|
||||
min={-maxBias}
|
||||
max={maxBias}
|
||||
step={1}
|
||||
value={referenceBias}
|
||||
|
@ -89,6 +90,17 @@ export function AutomaticPalette() {
|
|||
</aside>
|
||||
<div className={styles.palette_content}>
|
||||
<h5>Generated Palette</h5>
|
||||
<div className={styles.colors_booth}>
|
||||
<PaletteColors
|
||||
color={selectedColor}
|
||||
swatchAmount={swatchAmount}
|
||||
min={minLightness / 100}
|
||||
max={maxLightness / 100}
|
||||
useReference={useReferenceColor}
|
||||
referenceBias={referenceBias}
|
||||
copyMode={mode}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.color_value_mode}>
|
||||
<label>Copy color value in</label>
|
||||
<HSegmentedControl
|
||||
|
|
Loading…
Reference in New Issue
Block a user