Files
novalon-website/src/lib/color-contrast.ts
T
张翔 6d92024b63 feat: 修复测试套件问题并添加Woodpecker CI配置
- 修复API测试认证问题:创建全局认证设置,更新Playwright配置
- 优化回归测试稳定性:增加超时时间到15秒,修复定位器
- 创建Woodpecker CI工作流:CI、部署和质量门禁配置
- 添加Jest配置和测试脚本
- 移除登录页面的默认账号密码显示(安全问题修复)
2026-03-09 10:26:02 +08:00

61 lines
1.6 KiB
TypeScript

interface ColorRGB {
r: number;
g: number;
b: number;
}
interface ContrastResult {
passes: boolean;
ratio: number;
requiredRatio: number;
}
function hexToRgb(hex: string): ColorRGB {
const cleanHex = hex.replace('#', '');
const r = parseInt(cleanHex.substring(0, 2), 16);
const g = parseInt(cleanHex.substring(2, 4), 16);
const b = parseInt(cleanHex.substring(4, 6), 16);
return { r, g, b };
}
function getLuminance(rgb: ColorRGB): number {
const { r, g, b } = rgb;
const values = [r, g, b].map(v => {
const normalized = v / 255;
return normalized <= 0.03928 ? normalized / 12.92 : Math.pow((normalized + 0.055) / 1.055, 2.4);
});
return values[0]! * 0.2126 + values[1]! * 0.7152 + values[2]! * 0.0722;
}
export function calculateContrastRatio(foreground: string, background: string): number {
const fgRgb = hexToRgb(foreground);
const bgRgb = hexToRgb(background);
const fgLuminance = getLuminance(fgRgb);
const bgLuminance = getLuminance(bgRgb);
const lighter = Math.max(fgLuminance, bgLuminance);
const darker = Math.min(fgLuminance, bgLuminance);
return (lighter + 0.05) / (darker + 0.05);
}
export function meetsWCAGStandard(
foreground: string,
background: string,
level: 'AA' | 'AAA' = 'AA',
textSize: 'normal' | 'large' = 'normal'
): ContrastResult {
const ratio = calculateContrastRatio(foreground, background);
const requiredRatio = level === 'AAA'
? (textSize === 'large' ? 4.5 : 7)
: (textSize === 'large' ? 3 : 4.5);
return {
passes: ratio >= requiredRatio,
ratio,
requiredRatio,
};
}