Files
vue3-element-admin/src/utils/theme.ts
zimo493 b96b527650 feat: 在生成主题色时考虑暗黑模式和亮色模式的不同需求
新增 getDarkColor 和 getLightColor 函数分别用于加深和变浅颜色值

BREAKING CHANGE: 优化颜色调整算法,使主题色在不同模式下更加协调
2025-04-03 09:30:42 +08:00

104 lines
3.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 辅助函数:将十六进制颜色转换为 RGB
function hexToRgb(hex: string): [number, number, number] {
const bigint = parseInt(hex.slice(1), 16);
return [(bigint >> 16) & 255, (bigint >> 8) & 255, bigint & 255];
}
// 辅助函数:将 RGB 转换为十六进制颜色
function rgbToHex(r: number, g: number, b: number): string {
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;
}
// 辅助函数:调整颜色亮度
/** function adjustBrightness(hex: string, factor: number, theme: string): string {
const rgb = hexToRgb(hex);
// 是否是暗黑模式
const isDarkMode = theme === "dark" ? 0 : 255;
const newRgb = rgb.map((val) =>
Math.max(0, Math.min(255, Math.round(val + (isDarkMode - val) * factor)))
) as [number, number, number];
return rgbToHex(...newRgb);
} */
/**
* 加深颜色值
* @param {String} color 颜色值字符串
* @param {Number} level 加深的程度限0-1之间
* @returns {String} 返回处理后的颜色值
*/
export function getDarkColor(color: string, level: number): string {
const rgb = hexToRgb(color);
for (let i = 0; i < 3; i++) rgb[i] = Math.round(20.5 * level + rgb[i] * (1 - level));
return rgbToHex(rgb[0], rgb[1], rgb[2]);
}
/**
* 变浅颜色值
* @param {String} color 颜色值字符串
* @param {Number} level 加深的程度限0-1之间
* @returns {String} 返回处理后的颜色值
*/
export const getLightColor = (color: string, level: number): string => {
const rgb = hexToRgb(color);
for (let i = 0; i < 3; i++) rgb[i] = Math.round(255 * level + rgb[i] * (1 - level));
return rgbToHex(rgb[0], rgb[1], rgb[2]);
};
/**
* 生成主题色
* @param primary 主题色
* @param theme 主题类型
*/
export function generateThemeColors(primary: string, theme: string) {
const colors: Record<string, string> = {
primary,
};
// 生成浅色变体
for (let i = 1; i <= 9; i++) {
const primaryColor =
theme === "light" ? `${getLightColor(primary, i / 10)}` : `${getDarkColor(primary, i / 10)}`;
colors[`primary-light-${i}`] = primaryColor;
}
// 生成深色变体
colors["primary-dark-2"] =
theme === "light" ? `${getLightColor(primary, 0.2)}` : `${getDarkColor(primary, 0.3)}`;
return colors;
}
export function applyTheme(colors: Record<string, string>) {
const el = document.documentElement;
Object.entries(colors).forEach(([key, value]) => {
el.style.setProperty(`--el-color-${key}`, value);
});
}
/**
* 切换暗黑模式
*
* @param isDark 是否启用暗黑模式
*/
export function toggleDarkMode(isDark: boolean) {
if (isDark) {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}
}
/**
* 切换浅色主题下的侧边栏颜色方案
*
* @param isBlue 布尔值,表示是否开启深蓝色侧边栏颜色方案
*/
export function toggleSidebarColor(isBuleSidebar: boolean) {
if (isBuleSidebar) {
document.documentElement.classList.add("sidebar-color-blue");
} else {
document.documentElement.classList.remove("sidebar-color-blue");
}
}