hsl to rgba not as effect but immediately, so all components have the correct theme applied at once
This commit is contained in:
		
							parent
							
								
									40bb1ec28a
								
							
						
					
					
						commit
						4960df370c
					
				
					 1 changed files with 26 additions and 27 deletions
				
			
		|  | @ -1,5 +1,5 @@ | |||
| import {useStoredObjectState} from './useStoredState.ts'; | ||||
| import {createContext, ReactNode, useContext, useEffect, useRef, useState} from 'react'; | ||||
| import {createContext, ReactNode, useContext, useMemo, useRef, useState} from 'react'; | ||||
| 
 | ||||
| type HSL = { | ||||
|     h: number; | ||||
|  | @ -14,6 +14,15 @@ export type HslTheme = { | |||
|     tertiary: HSL; | ||||
| } | ||||
| 
 | ||||
| type Rgba = Uint8ClampedArray; | ||||
| 
 | ||||
| export type RgbaTheme = { | ||||
|     primary: Rgba; | ||||
|     secondary: Rgba; | ||||
|     background: Rgba; | ||||
|     tertiary: Rgba; | ||||
| } | ||||
| 
 | ||||
| // @ts-ignore
 | ||||
| const rootStyle = document.querySelector(':root')?.style; | ||||
| 
 | ||||
|  | @ -76,22 +85,6 @@ export function getRandomTheme(): HslTheme { | |||
|     return {background, primary, secondary, tertiary}; | ||||
| } | ||||
| 
 | ||||
| function applyTheme(theme: HslTheme) { | ||||
|     console.log('apply theme', theme); | ||||
|     rootStyle.setProperty('--color-primary', hslToString(theme.primary)); | ||||
|     rootStyle.setProperty('--color-secondary', hslToString(theme.secondary)); | ||||
|     rootStyle.setProperty('--color-background', hslToString(theme.background)); | ||||
| } | ||||
| 
 | ||||
| type Rgba = Uint8ClampedArray; | ||||
| 
 | ||||
| export type RgbaTheme = { | ||||
|     primary: Rgba; | ||||
|     secondary: Rgba; | ||||
|     background: Rgba; | ||||
|     tertiary: Rgba; | ||||
| } | ||||
| 
 | ||||
| const dummyRgbaTheme: RgbaTheme = { | ||||
|     primary: new Uint8ClampedArray([0, 0, 0, 0]), | ||||
|     secondary: new Uint8ClampedArray([0, 0, 0, 0]), | ||||
|  | @ -105,7 +98,6 @@ function hslToRgba(context: CanvasRenderingContext2D, color: HSL) { | |||
|     return context.getImageData(0, 0, 1, 1).data; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| const HslThemeContext = createContext<null | { | ||||
|     hslTheme: HslTheme, | ||||
|     setHslTheme: (mutator: (oldState: HslTheme) => HslTheme) => void | ||||
|  | @ -128,34 +120,41 @@ export function useHslTheme() { | |||
| export function ThemeProvider({children}: { | ||||
|     children?: ReactNode; | ||||
| }) { | ||||
|     const [rgbaTheme, setRgbaTheme] = useState<RgbaTheme | null>(null); | ||||
| 
 | ||||
|     function applyTheme(theme: HslTheme) { | ||||
|         console.log('apply theme', theme); | ||||
|         rootStyle.setProperty('--color-primary', hslToString(theme.primary)); | ||||
|         rootStyle.setProperty('--color-secondary', hslToString(theme.secondary)); | ||||
|         rootStyle.setProperty('--color-background', hslToString(theme.background)); | ||||
|     } | ||||
| 
 | ||||
|     const [hslTheme, setHslTheme] = useStoredObjectState<HslTheme>('theme', getRandomTheme, { | ||||
|         load: applyTheme, | ||||
|         save: applyTheme | ||||
|     }); | ||||
| 
 | ||||
|     const [rgbaTheme, setRgbaTheme] = useState<RgbaTheme | null>(null); | ||||
|     const canvasRef = useRef<HTMLCanvasElement>(null); | ||||
| 
 | ||||
|     useEffect(() => { | ||||
|         const canvas = canvasRef.current; | ||||
|         if (canvas === null) | ||||
|             throw new Error('canvas null'); | ||||
|     const canvas = canvasRef.current; | ||||
| 
 | ||||
|     useMemo(() => { | ||||
|         if (!canvas) | ||||
|             return; | ||||
| 
 | ||||
|         const drawContext = canvas.getContext('2d', { | ||||
|             alpha: true, | ||||
|             alpha: false, | ||||
|             colorSpace: 'srgb', | ||||
|             willReadFrequently: true | ||||
|         }); | ||||
|         if (!drawContext) | ||||
|             throw new Error('could not get draw context'); | ||||
| 
 | ||||
|         setRgbaTheme({ | ||||
|             background: hslToRgba(drawContext, hslTheme.background), | ||||
|             primary: hslToRgba(drawContext, hslTheme.primary), | ||||
|             secondary: hslToRgba(drawContext, hslTheme.secondary), | ||||
|             tertiary: hslToRgba(drawContext, hslTheme.tertiary), | ||||
|         }); | ||||
|     }, [hslTheme, canvasRef.current]); | ||||
|     }, [hslTheme, canvas]); | ||||
| 
 | ||||
|     return <HslThemeContext.Provider value={{hslTheme, setHslTheme}}> | ||||
|         <RgbaThemeContext.Provider value={rgbaTheme || dummyRgbaTheme}> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter