Add color adaptation functions for theme-based palette adjustments
- Implement rgbToHsl and hslToRgb functions for color space conversions. - Introduce adaptPalette function to adjust colors based on dark/light themes, enhancing visual consistency. - Add isDarkTheme function to determine the current theme state, improving theme handling across visual components.
This commit is contained in:
@@ -60,3 +60,69 @@ export function readPalette(el: Element): Palette {
|
||||
rose: parseHex(s.getPropertyValue("--gradient-rose"), FALLBACK.rose),
|
||||
};
|
||||
}
|
||||
|
||||
function rgbToHsl({ r, g, b }: RGB): [number, number, number] {
|
||||
const rn = r / 255;
|
||||
const gn = g / 255;
|
||||
const bn = b / 255;
|
||||
const max = Math.max(rn, gn, bn);
|
||||
const min = Math.min(rn, gn, bn);
|
||||
const l = (max + min) / 2;
|
||||
if (max === min) return [0, 0, l];
|
||||
const d = max - min;
|
||||
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||||
let h: number;
|
||||
if (max === rn) h = (gn - bn) / d + (gn < bn ? 6 : 0);
|
||||
else if (max === gn) h = (bn - rn) / d + 2;
|
||||
else h = (rn - gn) / d + 4;
|
||||
return [h / 6, s, l];
|
||||
}
|
||||
|
||||
function hue2rgb(p: number, q: number, t: number) {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
||||
if (t < 1 / 2) return q;
|
||||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
||||
return p;
|
||||
}
|
||||
|
||||
function hslToRgb(h: number, s: number, l: number): RGB {
|
||||
if (s === 0) {
|
||||
const v = Math.round(l * 255);
|
||||
return { r: v, g: v, b: v };
|
||||
}
|
||||
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
const p = 2 * l - q;
|
||||
return {
|
||||
r: Math.round(hue2rgb(p, q, h + 1 / 3) * 255),
|
||||
g: Math.round(hue2rgb(p, q, h) * 255),
|
||||
b: Math.round(hue2rgb(p, q, h - 1 / 3) * 255),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 按主题为「发光画面」调整调色板:
|
||||
* 暗色提亮提饱和让辉光透亮;亮色加深加饱和,避免粉彩色在白底上发灰。
|
||||
*/
|
||||
export function adaptPalette(palette: Palette, dark: boolean): Palette {
|
||||
const tune = (c: RGB): RGB => {
|
||||
const [h, s, l] = rgbToHsl(c);
|
||||
return dark
|
||||
? hslToRgb(h, Math.min(1, s * 1.25), Math.min(0.78, l * 1.15))
|
||||
: hslToRgb(h, Math.min(1, s * 1.55), Math.max(0.36, l * 0.6));
|
||||
};
|
||||
return {
|
||||
sky: tune(palette.sky),
|
||||
lav: tune(palette.lav),
|
||||
rose: tune(palette.rose),
|
||||
};
|
||||
}
|
||||
|
||||
/** 当前是否处于暗色主题(与 ThemeToggle 在 <html> 上切换的 .dark 一致) */
|
||||
export function isDarkTheme(): boolean {
|
||||
return (
|
||||
typeof document !== "undefined" &&
|
||||
document.documentElement.classList.contains("dark")
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user