Files
color-q/src/pages/Mixer.tsx
2025-02-10 14:28:34 +08:00

82 lines
2.7 KiB
TypeScript

import cx from 'clsx';
import { useMemo, useState } from 'react';
import { useColorFunction } from '../ColorFunctionContext';
import { ColorPicker } from '../components/ColorPicker';
import { FlexColorStand } from '../components/FlexColorStand';
import { HSegmentedControl } from '../components/HSegmentedControl';
import { LabeledPicker } from '../components/LabeledPicker';
import { ScrollArea } from '../components/ScrollArea';
import styles from './Mixer.module.css';
type ColorModes = 'hex' | 'rgb' | 'hsl' | 'lab' | 'oklch';
export function Mixer() {
const { colorFn } = useColorFunction();
const [basicColor, setBasicColor] = useState('000000');
const [mixColor, setMixColor] = useState('000000');
const [mixRatio, setMixRatio] = useState(0);
const [mode, setMode] = useState<ColorModes>('hex');
const mixedColor = useMemo(() => {
try {
if (!colorFn) {
return '000000';
}
const mixed = colorFn.mix(basicColor, mixColor, mixRatio / 100);
return mixed;
} catch (e) {
console.error('[Mix Color]', e);
}
return '000000';
}, [basicColor, mixColor, mixRatio]);
return (
<div className={cx('workspace', styles.mixer_workspace)}>
<header>
<h3>Color Mixer</h3>
<p>Make a new color by mixing two colors.</p>
</header>
<ScrollArea enableY>
<div className={styles.mixer_content}>
<div className={styles.mixer_column}>
<h5>Basic Color</h5>
<ColorPicker color={basicColor} onSelect={setBasicColor} />
</div>
<div className={styles.mixer_column}>
<h5>Mix Color</h5>
<ColorPicker color={mixColor} onSelect={setMixColor} />
<LabeledPicker
title="Mix Ratio"
value={mixRatio}
onChange={setMixRatio}
min={0}
max={100}
step={1}
unit="%"
/>
</div>
<div className={styles.mixer_column}>
<h5>Mix Result</h5>
<div className={styles.colors_booth}>
<FlexColorStand color={mixedColor} valueMode={mode} />
</div>
<div className={styles.color_value_mode}>
<label>Copy color value in</label>
<HSegmentedControl
options={[
{ label: 'HEX', value: 'hex' },
{ label: 'RGB', value: 'rgb' },
{ label: 'HSL', value: 'hsl' },
{ label: 'LAB', value: 'lab' },
{ label: 'OKLCH', value: 'oklch' },
]}
value={mode}
onChange={(v) => setMode(v as ColorModes)}
/>
</div>
</div>
</div>
</ScrollArea>
</div>
);
}