/** * 主题色工具:根据取色器选中的主色,计算 hover/light 并写入 :root CSS 变量 * 用于导航栏、侧边菜单、按钮等公共颜色统一切换 */ const STORAGE_KEY = 'app-theme-color'; export function getStoredThemeColor(): string | null { try { return localStorage.getItem(STORAGE_KEY); } catch { return null; } } export function setStoredThemeColor(hex: string): void { try { localStorage.setItem(STORAGE_KEY, hex); } catch { // ignore } } /** 将 hex 转为 r,g,b (0-255) */ function hexToRgb(hex: string): { r: number; g: number; b: number } | null { const m = hex.replace(/^#/, '').match(/^([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i); if (!m) return null; return { r: parseInt(m[1], 16), g: parseInt(m[2], 16), b: parseInt(m[3], 16), }; } /** 将 r,g,b 转为 #rrggbb */ function rgbToHex(r: number, g: number, b: number): string { return '#' + [r, g, b].map((x) => Math.round(Math.max(0, Math.min(255, x))).toString(16).padStart(2, '0')).join(''); } /** 在 hex 颜色基础上按比例变暗(用于 hover) */ function darkenHex(hex: string, ratio: number): string { const rgb = hexToRgb(hex); if (!rgb) return hex; return rgbToHex(rgb.r * (1 - ratio), rgb.g * (1 - ratio), rgb.b * (1 - ratio)); } /** 生成浅色背景(用于 menu hover 等) */ function lightenHex(hex: string, mixWhite = 0.92): string { const rgb = hexToRgb(hex); if (!rgb) return hex; const r = Math.round(rgb.r * (1 - mixWhite) + 255 * mixWhite); const g = Math.round(rgb.g * (1 - mixWhite) + 255 * mixWhite); const b = Math.round(rgb.b * (1 - mixWhite) + 255 * mixWhite); return rgbToHex(r, g, b); } /** * 将主题色应用到页面:设置 :root 上的 CSS 变量 * @param primaryHex 主色,如 #2D8C8C */ export function applyThemeColor(primaryHex: string): void { const hex = primaryHex.startsWith('#') ? primaryHex : `#${primaryHex}`; const root = document.documentElement; const primary = hex; const primaryHover = darkenHex(hex, 0.05); const primaryLight = lightenHex(hex, 0.92); root.style.setProperty('--app-primary-color', primary); root.style.setProperty('--app-primary-color-hover', primaryHover); root.style.setProperty('--app-primary-color-light', primaryLight); root.style.setProperty('--app-navbar-bg', primary); root.style.setProperty('--app-sidebar-bg', primary); }