diff --git a/src/store/app.ts b/src/store/app.ts index abd824f..11dfd3d 100644 --- a/src/store/app.ts +++ b/src/store/app.ts @@ -1,6 +1,7 @@ import { defineStore } from 'pinia' import { getLocalStorage, setLocalStorage } from 'vue3-common/utils/storageUtil' import { useDark, useToggle } from '@vueuse/core' +import { darken, lighten } from '@/utils/colorUtils' export const useAppStore = defineStore('ipp', { state: () => ({ @@ -77,15 +78,10 @@ export const useAppStore = defineStore('ipp', { // 1. 设置主色 style.setProperty('--el-color-primary', color) - // 2. 设置浅色变体(light-*) - style.setProperty('--el-color-primary-light-3', `color-mix(in srgb, ${color} 70%, white)`) - style.setProperty('--el-color-primary-light-5', `color-mix(in srgb, ${color} 50%, white)`) - style.setProperty('--el-color-primary-light-7', `color-mix(in srgb, ${color} 30%, white)`) - style.setProperty('--el-color-primary-light-8', `color-mix(in srgb, ${color} 20%, white)`) - style.setProperty('--el-color-primary-light-9', `color-mix(in srgb, ${color} 10%, white)`) - - // 3. 设置深色变体(dark-*) - style.setProperty('--el-color-primary-dark-2', `color-mix(in srgb, ${color} 80%, black)`) + for (let i = 1; i <= 9; i++) { + style.setProperty(`--el-color-primary-light-${i}`, lighten(color, i / 10)) + style.setProperty(`--el-color-primary-dark-${i}`, darken(color, i / 10)) + } setLocalStorage('theme-color', color) } diff --git a/src/utils/colorUtils.ts b/src/utils/colorUtils.ts new file mode 100644 index 0000000..0b7e86b --- /dev/null +++ b/src/utils/colorUtils.ts @@ -0,0 +1,69 @@ +/** + * 将十六进制颜色转换为RGB数组 + * @param color 十六进制颜色字符串(如:#FF0000 或 FFFFFF) + * @returns RGB数值数组 [r, g, b] + */ +export const hex2Rgb = (color: string): [number, number, number] => { + const cleanColor = color.replace('#', '') + const result = cleanColor.match(/../g)?.map((val) => parseInt(val, 16)) ?? [0, 0, 0] + + // 确保结果长度为3,并处理无效输入 + if (result.length !== 3) { + throw new Error('Invalid hex color format') + } + + return [result[0], result[1], result[2]] +} + +/** + * 将RGB颜色转换为十六进制字符串 + * @param r 红色值 (0-255) + * @param g 绿色值 (0-255) + * @param b 蓝色值 (0-255) + * @returns 十六进制颜色字符串(如:#FF0000) + */ +export const rgb2Hex = (r: number, g: number, b: number): string => { + const validateComponent = (val: number) => Math.max(0, Math.min(255, Math.round(val))) + + const hexs = [ + validateComponent(r).toString(16).padStart(2, '0'), + validateComponent(g).toString(16).padStart(2, '0'), + validateComponent(b).toString(16).padStart(2, '0') + ] + + return `#${hexs.join('')}` +} + +/** + * 调亮颜色 + * @param color 十六进制颜色字符串 + * @param level 亮度调整级别 (0-1) + * @returns 调亮后的十六进制颜色 + */ +export const lighten = (color: string, level: number): string => { + const [r, g, b] = hex2Rgb(color) + const validateLevel = Math.max(0, Math.min(1, level)) + + const newR = Math.floor((255 - r) * validateLevel + r) + const newG = Math.floor((255 - g) * validateLevel + g) + const newB = Math.floor((255 - b) * validateLevel + b) + + return rgb2Hex(newR, newG, newB) +} + +/** + * 调暗颜色 + * @param color 十六进制颜色字符串 + * @param level 暗度调整级别 (0-1) + * @returns 调暗后的十六进制颜色 + */ +export const darken = (color: string, level: number): string => { + const [r, g, b] = hex2Rgb(color) + const validateLevel = Math.max(0, Math.min(1, level)) + + const newR = Math.floor(r * (1 - validateLevel)) + const newG = Math.floor(g * (1 - validateLevel)) + const newB = Math.floor(b * (1 - validateLevel)) + + return rgb2Hex(newR, newG, newB) +}