构建自动色板功能的基本页面结构。
This commit is contained in:
		| @@ -10,6 +10,7 @@ import { LightenDarken } from './pages/LightenDarken'; | ||||
| import { MainLayout } from './pages/MainLayout'; | ||||
| import { Mixer } from './pages/Mixer'; | ||||
| import { NewScheme } from './pages/NewScheme'; | ||||
| import { AutomaticPalette } from './pages/Palette'; | ||||
| import { SchemeDetail } from './pages/SchemeDetail'; | ||||
| import { SchemeNotFound } from './pages/SchemeNotFound'; | ||||
| import { Schemes } from './pages/Schemes'; | ||||
| @@ -39,6 +40,7 @@ const routes = createBrowserRouter([ | ||||
|       { path: 'tints-shades', element: <TintsShades /> }, | ||||
|       { path: 'lighten-darken', element: <LightenDarken /> }, | ||||
|       { path: 'mixer', element: <Mixer /> }, | ||||
|       { path: 'palette', element: <AutomaticPalette /> }, | ||||
|       { path: 'wacg', element: <WACGCheck /> }, | ||||
|       { path: 'compare', element: <ColorCompare /> }, | ||||
|       { | ||||
|   | ||||
							
								
								
									
										47
									
								
								src/pages/Palette.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/pages/Palette.module.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| @layer pages { | ||||
|   .palette_workspace { | ||||
|     flex-direction: column; | ||||
|   } | ||||
|   .palette_section { | ||||
|     width: 100%; | ||||
|     flex: 1; | ||||
|     display: flex; | ||||
|     flex-direction: row; | ||||
|     align-items: stretch; | ||||
|     gap: var(--spacing-m); | ||||
|   } | ||||
|   .function_side { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     gap: var(--spacing-m); | ||||
|     font-size: var(--font-size-s); | ||||
|     .mode_navigation { | ||||
|       display: flex; | ||||
|       flex-direction: column; | ||||
|       align-items: stretch; | ||||
|       gap: var(--spacing-s); | ||||
|     } | ||||
|     h5 { | ||||
|       padding-block: var(--spacing-m); | ||||
|       font-size: var(--font-size-m); | ||||
|     } | ||||
|   } | ||||
|   .palette_content { | ||||
|     flex: 1; | ||||
|     padding: 0 var(--spacing-m); | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     gap: var(--spacing-s); | ||||
|     h5 { | ||||
|       padding-block: var(--spacing-m); | ||||
|       font-size: var(--font-size-m); | ||||
|     } | ||||
|     .color_value_mode { | ||||
|       display: flex; | ||||
|       flex-direction: row; | ||||
|       align-items: center; | ||||
|       gap: var(--spacing-s); | ||||
|       font-size: var(--font-size-s); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										111
									
								
								src/pages/Palette.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/pages/Palette.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | ||||
| import cx from 'clsx'; | ||||
| import { useAtom } from 'jotai'; | ||||
| import { useEffect, useMemo, useState } from 'react'; | ||||
| import { ColorPicker } from '../components/ColorPicker'; | ||||
| import { HSegmentedControl } from '../components/HSegmentedControl'; | ||||
| import { Labeled } from '../components/Labeled'; | ||||
| import { LabeledPicker } from '../components/LabeledPicker'; | ||||
| import { ScrollArea } from '../components/ScrollArea'; | ||||
| import { Switch } from '../components/Switch'; | ||||
| import { currentPickedColor } from '../stores/colors'; | ||||
| import styles from './Palette.module.css'; | ||||
|  | ||||
| export function AutomaticPalette() { | ||||
|   const [selectedColor, setSelectedColor] = useAtom(currentPickedColor); | ||||
|   const [useReferenceColor, setUseReferenceColor] = useState(false); | ||||
|   const [swatchAmount, setSwatchAmount] = useState(5); | ||||
|   const maxBias = useMemo( | ||||
|     () => (swatchAmount > 3 ? Math.floor(swatchAmount / 2) - 1 : 0), | ||||
|     [swatchAmount], | ||||
|   ); | ||||
|   const [referenceBias, setReferenceBias] = useState(0); | ||||
|   const [minLightness, setMinLightness] = useState(10); | ||||
|   const [maxLightness, setMaxLightness] = useState(90); | ||||
|   const [mode, setMode] = useState<'hex' | 'rgb' | 'hsl' | 'lab' | 'oklch'>('hex'); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     if (useReferenceColor) { | ||||
|       setReferenceBias(0); | ||||
|     } | ||||
|   }, [swatchAmount, useReferenceColor]); | ||||
|  | ||||
|   return ( | ||||
|     <div className={cx('workspace', styles.palette_workspace)}> | ||||
|       <header> | ||||
|         <h3>Automatic Palette</h3> | ||||
|         <p> | ||||
|           Automatically generate a color palette suitable for UI color matching according to the | ||||
|           given color algorithm. | ||||
|         </p> | ||||
|       </header> | ||||
|       <ScrollArea enableY> | ||||
|         <section className={styles.palette_section}> | ||||
|           <aside className={styles.function_side}> | ||||
|             <div> | ||||
|               <h5>Reference Color</h5> | ||||
|               <ColorPicker color={selectedColor} onSelect={(color) => setSelectedColor(color)} /> | ||||
|             </div> | ||||
|             <div> | ||||
|               <h5>Palette Setting</h5> | ||||
|               <Labeled label="Use Reference Color" inline> | ||||
|                 <Switch checked={useReferenceColor} onChange={setUseReferenceColor} /> | ||||
|               </Labeled> | ||||
|               <LabeledPicker | ||||
|                 title="Swatch Amount" | ||||
|                 min={3} | ||||
|                 max={15} | ||||
|                 step={1} | ||||
|                 value={swatchAmount} | ||||
|                 onChange={(value) => setSwatchAmount(value)} | ||||
|               /> | ||||
|               <LabeledPicker | ||||
|                 title="Reference Bias" | ||||
|                 min={0} | ||||
|                 max={maxBias} | ||||
|                 step={1} | ||||
|                 value={referenceBias} | ||||
|                 onChange={setReferenceBias} | ||||
|                 disabled={!useReferenceColor || maxBias < 2} | ||||
|               /> | ||||
|               <LabeledPicker | ||||
|                 title="Min Lightness" | ||||
|                 min={0} | ||||
|                 max={100} | ||||
|                 step={1} | ||||
|                 value={minLightness} | ||||
|                 onChange={setMinLightness} | ||||
|                 unit="%" | ||||
|               /> | ||||
|               <LabeledPicker | ||||
|                 title="Max Lightness" | ||||
|                 min={0} | ||||
|                 max={100} | ||||
|                 step={1} | ||||
|                 value={maxLightness} | ||||
|                 onChange={setMaxLightness} | ||||
|                 unit="%" | ||||
|               /> | ||||
|             </div> | ||||
|           </aside> | ||||
|           <div className={styles.palette_content}> | ||||
|             <h5>Generated Palette</h5> | ||||
|             <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' }, | ||||
|                 ]} | ||||
|                 valu={mode} | ||||
|                 onChange={setMode} | ||||
|               /> | ||||
|             </div> | ||||
|           </div> | ||||
|         </section> | ||||
|       </ScrollArea> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user