130 lines
3.9 KiB
TypeScript
130 lines
3.9 KiB
TypeScript
/**
|
||
* 調整顏色亮度
|
||
* @param hex 原始顏色的 HEX 值(例如 "#01ab83")
|
||
* @param percent 調整百分比,正值變亮,負值變暗
|
||
* @returns 調整後的 HEX 色碼
|
||
*/
|
||
export function adjustBrightness(hex: string, percent: number): string {
|
||
// 移除 # 符號
|
||
const cleanHex = hex.replace('#', '');
|
||
|
||
// 解析 RGB
|
||
const num = parseInt(cleanHex, 16);
|
||
const r = (num >> 16) & 0xFF;
|
||
const g = (num >> 8) & 0xFF;
|
||
const b = num & 0xFF;
|
||
|
||
// 計算調整後的 RGB(確保在 0-255 範圍內)
|
||
const newR = Math.min(255, Math.max(0, r + percent * 2.55));
|
||
const newG = Math.min(255, Math.max(0, g + percent * 2.55));
|
||
const newB = Math.min(255, Math.max(0, b + percent * 2.55));
|
||
|
||
// 轉回 HEX
|
||
const result = ((Math.round(newR) << 16) | (Math.round(newG) << 8) | Math.round(newB))
|
||
.toString(16)
|
||
.padStart(6, '0');
|
||
|
||
return `#${result}`;
|
||
}
|
||
|
||
/**
|
||
* 生成非常淺的背景色(類似原本的 primary-lightest: #e6f7f3)
|
||
* 這個函式會保留原色的色調,但大幅提高亮度和降低飽和度
|
||
* @param hex 原始顏色的 HEX 值
|
||
* @returns 淺色背景的 HEX 色碼
|
||
*/
|
||
export function generateLightestColor(hex: string): string {
|
||
const cleanHex = hex.replace('#', '');
|
||
const num = parseInt(cleanHex, 16);
|
||
const r = (num >> 16) & 0xFF;
|
||
const g = (num >> 8) & 0xFF;
|
||
const b = num & 0xFF;
|
||
|
||
// 混合白色來創造非常淺的色調(90% 白色 + 10% 原色)
|
||
const mixRatio = 0.1;
|
||
const newR = Math.round(255 * (1 - mixRatio) + r * mixRatio);
|
||
const newG = Math.round(255 * (1 - mixRatio) + g * mixRatio);
|
||
const newB = Math.round(255 * (1 - mixRatio) + b * mixRatio);
|
||
|
||
const result = ((newR << 16) | (newG << 8) | newB)
|
||
.toString(16)
|
||
.padStart(6, '0');
|
||
|
||
return `#${result}`;
|
||
}
|
||
|
||
/**
|
||
* 生成淺色(類似原本的 primary-light: #33bc9a)
|
||
* @param hex 原始顏色的 HEX 值
|
||
* @returns 淺色的 HEX 色碼
|
||
*/
|
||
export function generateLightColor(hex: string): string {
|
||
const cleanHex = hex.replace('#', '');
|
||
const num = parseInt(cleanHex, 16);
|
||
const r = (num >> 16) & 0xFF;
|
||
const g = (num >> 8) & 0xFF;
|
||
const b = num & 0xFF;
|
||
|
||
// 混合白色(70% 原色 + 30% 白色)
|
||
const mixRatio = 0.7;
|
||
const newR = Math.round(r * mixRatio + 255 * (1 - mixRatio));
|
||
const newG = Math.round(g * mixRatio + 255 * (1 - mixRatio));
|
||
const newB = Math.round(b * mixRatio + 255 * (1 - mixRatio));
|
||
|
||
const result = ((newR << 16) | (newG << 8) | newB)
|
||
.toString(16)
|
||
.padStart(6, '0');
|
||
|
||
return `#${result}`;
|
||
}
|
||
|
||
/**
|
||
* 生成深色(類似原本的 primary-dark: #018a6a)
|
||
* @param hex 原始顏色的 HEX 值
|
||
* @returns 深色的 HEX 色碼
|
||
*/
|
||
export function generateDarkColor(hex: string): string {
|
||
const cleanHex = hex.replace('#', '');
|
||
const num = parseInt(cleanHex, 16);
|
||
const r = (num >> 16) & 0xFF;
|
||
const g = (num >> 8) & 0xFF;
|
||
const b = num & 0xFF;
|
||
|
||
// 降低亮度(80% 原色)
|
||
const factor = 0.8;
|
||
const newR = Math.round(r * factor);
|
||
const newG = Math.round(g * factor);
|
||
const newB = Math.round(b * factor);
|
||
|
||
const result = ((newR << 16) | (newG << 8) | newB)
|
||
.toString(16)
|
||
.padStart(6, '0');
|
||
|
||
return `#${result}`;
|
||
}
|
||
|
||
/**
|
||
* 生成按鈕 active 狀態的顏色(比 dark 更深,約 60% 原色)
|
||
* @param hex 原始顏色的 HEX 值
|
||
* @returns 更深色的 HEX 色碼
|
||
*/
|
||
export function generateActiveColor(hex: string): string {
|
||
const cleanHex = hex.replace('#', '');
|
||
const num = parseInt(cleanHex, 16);
|
||
const r = (num >> 16) & 0xFF;
|
||
const g = (num >> 8) & 0xFF;
|
||
const b = num & 0xFF;
|
||
|
||
// 降低亮度(60% 原色)
|
||
const factor = 0.6;
|
||
const newR = Math.round(r * factor);
|
||
const newG = Math.round(g * factor);
|
||
const newB = Math.round(b * factor);
|
||
|
||
const result = ((newR << 16) | (newG << 8) | newB)
|
||
.toString(16)
|
||
.padStart(6, '0');
|
||
|
||
return `#${result}`;
|
||
}
|