Spaces:
Sleeping
Sleeping
| /** | |
| * Tiny shared helpers used across modules. Keeping these here (rather than scattered) | |
| * avoids circular imports — every other module can lean on `utils` without dragging | |
| * in colors / webgl / etc. | |
| */ | |
| /** A 2D point in normalized landmark space (0..1). */ | |
| export type Vec2 = { x: number; y: number }; | |
| export function clamp01(x: number): number { | |
| return Math.max(0, Math.min(1, x)); | |
| } | |
| /** Parse a `#RRGGBB` (or `#RGB`) hex string into a `[r,g,b]` triple in 0..1, matching the float space the shaders expect. */ | |
| export function hexToRgb01(hex: string): [number, number, number] { | |
| let h = hex.trim().replace(/^#/, ''); | |
| if (h.length === 3) h = h.split('').map((c) => c + c).join(''); | |
| const n = parseInt(h, 16); | |
| return [((n >> 16) & 0xff) / 255, ((n >> 8) & 0xff) / 255, (n & 0xff) / 255]; | |
| } | |
| /** `[r,g,b]` in 0..1 → `#RRGGBB` for HUD `--c` and saved looks. */ | |
| export function rgb01ToHex(r: number, g: number, b: number): string { | |
| const byte = (x: number) => Math.round(clamp01(x) * 255); | |
| const rr = byte(r).toString(16).padStart(2, '0'); | |
| const gg = byte(g).toString(16).padStart(2, '0'); | |
| const bb = byte(b).toString(16).padStart(2, '0'); | |
| return `#${rr}${gg}${bb}`.toUpperCase(); | |
| } | |