增加颜色对比功能。

This commit is contained in:
徐涛
2025-01-13 17:08:33 +08:00
parent 0eb00122c8
commit 1edc74daaf
9 changed files with 396 additions and 0 deletions

View File

@@ -0,0 +1,25 @@
@layer pages {
.elements {
display: flex;
flex-direction: row;
align-items: stretch;
gap: var(--spacing-m);
.element {
display: flex;
flex-direction: row;
align-items: center;
gap: var(--spacing-xs);
.element_name {
font-size: var(--font-size-xxl);
font-weight: bold;
}
.element_values {
display: flex;
flex-direction: column;
gap: var(--spacing-xs);
font-size: var(--font-size-xs);
line-height: var(--font-size-xs);
}
}
}
}

View File

@@ -0,0 +1,74 @@
import { useMemo } from 'react';
import { HctDiffference } from '../../color_functions/color_module';
import { useColorFunction } from '../../ColorFunctionContext';
import styles from './CompareLayout.module.css';
import { CompareMethodProps } from './share-props';
const defaultCompareResult: HctDiffference = {
hue: {
delta: 0,
percent: 0,
},
chroma: {
delta: 0,
percent: 0,
},
lightness: {
delta: 0,
percent: 0,
},
};
export function HCTCompare({ basic = '000000', compare = '000000' }: CompareMethodProps) {
const { colorFn } = useColorFunction();
const differ = useMemo(() => {
if (!colorFn) {
return defaultCompareResult;
}
try {
const diff = colorFn.differ_in_hct(basic, compare);
return diff;
} catch (e) {
console.error('[Compare in HCT]', e);
}
return defaultCompareResult;
}, [basic, compare]);
return (
<div>
<h6>Compare in HCT Space</h6>
<div className={styles.elements}>
<div className={styles.element}>
<div className={styles.element_name}>H</div>
<div className={styles.element_values}>
<span>{differ.hue.delta.toFixed(2)}</span>
<span>
{isNaN(differ.hue.percent) ? '0.00' : (differ.hue.percent * 100).toFixed(2)}%
</span>
</div>
</div>
<div className={styles.element}>
<div className={styles.element_name}>C</div>
<div className={styles.element_values}>
<span>{differ.chroma.delta.toFixed(2)}</span>
<span>
{isNaN(differ.chroma.percent) ? '0.00' : (differ.chroma.percent * 100).toFixed(2)}%
</span>
</div>
</div>
<div className={styles.element}>
<div className={styles.element_name}>T</div>
<div className={styles.element_values}>
<span>{differ.lightness.delta.toFixed(2)}</span>
<span>
{isNaN(differ.lightness.percent)
? '0.00'
: (differ.lightness.percent * 100).toFixed(2)}
%
</span>
</div>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,77 @@
import { useMemo } from 'react';
import { HSLDifference } from '../../color_functions/color_module';
import { useColorFunction } from '../../ColorFunctionContext';
import styles from './CompareLayout.module.css';
import { CompareMethodProps } from './share-props';
const defaultCompareResult: HSLDifference = {
hue: {
delta: 0,
percent: 0,
},
saturation: {
delta: 0,
percent: 0,
},
lightness: {
delta: 0,
percent: 0,
},
};
export function HSLCompare({ basic = '000000', compare = '000000' }: CompareMethodProps) {
const { colorFn } = useColorFunction();
const differ = useMemo(() => {
if (!colorFn) {
return defaultCompareResult;
}
try {
const diff = colorFn.differ_in_hsl(basic, compare);
return diff;
} catch (e) {
console.error('[Compare in HSL]', e);
}
return defaultCompareResult;
}, [basic, compare]);
return (
<div>
<h6>Compare in HSL Space</h6>
<div className={styles.elements}>
<div className={styles.element}>
<div className={styles.element_name}>H</div>
<div className={styles.element_values}>
<span>{differ.hue.delta.toFixed(2)}</span>
<span>
{isNaN(differ.hue.percent) ? '0.00' : (differ.hue.percent * 100).toFixed(2)}%
</span>
</div>
</div>
<div className={styles.element}>
<div className={styles.element_name}>S</div>
<div className={styles.element_values}>
<span>{(differ.saturation.delta * 100).toFixed(2)}%</span>
<span>
{isNaN(differ.saturation.percent)
? '0.00'
: (differ.saturation.percent * 100).toFixed(2)}
%
</span>
</div>
</div>
<div className={styles.element}>
<div className={styles.element_name}>L</div>
<div className={styles.element_values}>
<span>{(differ.lightness.delta * 100).toFixed(2)}%</span>
<span>
{isNaN(differ.lightness.percent)
? '0.00'
: (differ.lightness.percent * 100).toFixed(2)}
%
</span>
</div>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,74 @@
import { useMemo } from 'react';
import { OklchDifference } from '../../color_functions/color_module';
import { useColorFunction } from '../../ColorFunctionContext';
import styles from './CompareLayout.module.css';
import { CompareMethodProps } from './share-props';
const defaultCompareResult: OklchDifference = {
hue: {
delta: 0,
percent: 0,
},
chroma: {
delta: 0,
percent: 0,
},
lightness: {
delta: 0,
percent: 0,
},
};
export function OklchCompare({ basic = '000000', compare = '000000' }: CompareMethodProps) {
const { colorFn } = useColorFunction();
const differ = useMemo(() => {
if (!colorFn) {
return defaultCompareResult;
}
try {
const diff = colorFn.differ_in_oklch(basic, compare);
return diff;
} catch (e) {
console.error('[Compare in Oklch]', e);
}
return defaultCompareResult;
}, [basic, compare]);
return (
<div>
<h6>Compare in Oklch Space</h6>
<div className={styles.elements}>
<div className={styles.element}>
<div className={styles.element_name}>L</div>
<div className={styles.element_values}>
<span>{(differ.lightness.delta * 100).toFixed(2)}%</span>
<span>
{isNaN(differ.lightness.percent)
? '0.0000'
: (differ.lightness.percent * 100).toFixed(2)}
%
</span>
</div>
</div>
<div className={styles.element}>
<div className={styles.element_name}>C</div>
<div className={styles.element_values}>
<span>{differ.chroma.delta.toFixed(4)}</span>
<span>
{isNaN(differ.chroma.percent) ? '0.0000' : (differ.chroma.percent * 100).toFixed(2)}%
</span>
</div>
</div>
<div className={styles.element}>
<div className={styles.element_name}>H</div>
<div className={styles.element_values}>
<span>{differ.hue.delta.toFixed(2)}</span>
<span>
{isNaN(differ.hue.percent) ? '0.00' : (differ.hue.percent * 100).toFixed(2)}%
</span>
</div>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,78 @@
import { useMemo } from 'react';
import { RGBDifference } from '../../color_functions/color_module';
import { useColorFunction } from '../../ColorFunctionContext';
import styles from './CompareLayout.module.css';
import { CompareMethodProps } from './share-props';
const defaultCompareResult: RGBDifference = {
r: {
delta: 0,
percent: 0,
},
g: {
delta: 0,
percent: 0,
},
b: {
delta: 0,
percent: 0,
},
};
export function RGBCompare({ basic = '000000', compare = '000000' }: CompareMethodProps) {
const { colorFn } = useColorFunction();
const differ = useMemo(() => {
if (!colorFn) {
return defaultCompareResult;
}
try {
const diff = colorFn?.differ_in_rgb(basic, compare);
return {
r: {
delta: Math.round(diff.r.delta * 255),
percent: diff.r.percent,
},
g: {
delta: Math.round(diff.g.delta * 255),
percent: diff.g.percent,
},
b: {
delta: Math.round(diff.b.delta * 255),
percent: diff.b.percent,
},
} as RGBDifference;
} catch (e) {
console.error('[Compare in RGB]', e);
}
return defaultCompareResult;
}, [basic, compare]);
return (
<div>
<h6>Compare in RGB Space</h6>
<div className={styles.elements}>
<div className={styles.element}>
<div className={styles.element_name}>R</div>
<div className={styles.element_values}>
<span>{differ.r.delta}</span>
<span>{isNaN(differ.r.percent) ? '0.00' : (differ.r.percent * 100).toFixed(2)}%</span>
</div>
</div>
<div className={styles.element}>
<div className={styles.element_name}>G</div>
<div className={styles.element_values}>
<span>{differ.g.delta}</span>
<span>{isNaN(differ.g.percent) ? '0.00' : (differ.g.percent * 100).toFixed(2)}%</span>
</div>
</div>
<div className={styles.element}>
<div className={styles.element_name}>B</div>
<div className={styles.element_values}>
<span>{differ.b.delta}</span>
<span>{isNaN(differ.b.percent) ? '0.00' : (differ.b.percent * 100).toFixed(2)}%</span>
</div>
</div>
</div>
</div>
);
}

View File

@@ -0,0 +1,4 @@
export type CompareMethodProps = {
basic?: string;
compare?: string;
};