feat: admit complete Qoder surfaces into numbered HoloLake

This commit is contained in:
冰朔 2026-08-19 07:07:25 +08:00
commit fb8607f248
14 changed files with 1016 additions and 31 deletions

View file

@ -0,0 +1,44 @@
import type { FinishId } from './TraditionalSurface'
interface Rgb { r: number; g: number; b: number }
interface FinishProfile { background: string; foreground: string; tone: 'dark' | 'light' }
export const FINISH_PROFILES: Record<FinishId, FinishProfile> = {
aurora: { background: '#0a0e1f', foreground: '#eef1ff', tone: 'dark' },
nebula: { background: '#170b20', foreground: '#fdeef7', tone: 'dark' },
abyss: { background: '#04101c', foreground: '#e8f6ff', tone: 'dark' },
jade: { background: '#071410', foreground: '#eafaf2', tone: 'dark' },
cinnabar: { background: '#150a0a', foreground: '#fdf0ec', tone: 'dark' },
champagne: { background: '#141008', foreground: '#fdf4e6', tone: 'dark' },
porcelain: { background: '#e8edf6', foreground: '#1b2340', tone: 'light' },
snow: { background: '#e9f1f7', foreground: '#17273f', tone: 'light' },
}
function parseHex(value: string): Rgb {
const normalized = value.replace('#', '')
return { r: parseInt(normalized.slice(0, 2), 16), g: parseInt(normalized.slice(2, 4), 16), b: parseInt(normalized.slice(4, 6), 16) }
}
function luminance({ r, g, b }: Rgb) {
const channel = (value: number) => {
const normalized = value / 255
return normalized <= .03928 ? normalized / 12.92 : Math.pow((normalized + .055) / 1.055, 2.4)
}
return .2126 * channel(r) + .7152 * channel(g) + .0722 * channel(b)
}
export function contrastRatio(foreground: string, background: string) {
const a = luminance(parseHex(foreground))
const b = luminance(parseHex(background))
return (Math.max(a, b) + .05) / (Math.min(a, b) + .05)
}
export function resolveVisualBalance(finish: FinishId, phase?: string, weather?: string) {
const profile = FINISH_PROFILES[finish]
return {
tone: profile.tone,
contrast: contrastRatio(profile.foreground, profile.background),
phase: phase?.toLowerCase() || 'time-pending',
weather: weather?.toLowerCase() || 'unavailable',
}
}