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),
|
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