为什么我的对比度函数计算结果不准确?
问题排查与修复方案
嘿,我发现你代码里有两个关键问题导致对比度计算结果和预期偏差极大,咱们一步步来解决:
1. 相对亮度计算的运算顺序错误
WCAG规范里的相对亮度公式中,((R_sRGB + 0.055) / 1.055)这部分需要先计算,再进行2.4次方运算。但你的reLum函数里,因为JavaScript中**(幂运算)的优先级高于/,导致实际执行的是(newRGB + 0.055) / (1.055 ** 2.4),这完全违背了规范公式,是核心错误。
2. 亮度值的精度丢失与类型错误
你的lum函数里用了toFixed(3),这会把计算出的数值转换成字符串,同时丢失了精度。后续计算对比度时,Math.max(lum1, lum2)和Math.min(lum1, lum2)是在字符串上进行比较,而不是数字比较,这会进一步加剧结果的偏差。
修正后的代码
// Measure the relative luminance of each RGB value const reLum = function relativeLuminance(RGB) { let newRGB = RGB / 255; return newRGB <= 0.03928 ? newRGB / 12.92 : Math.pow((newRGB + 0.055) / 1.055, 2.4); // 修正运算顺序,用Math.pow更清晰 } // Measure the luminance of the color const lum = function luminance(r, g, b) { const a = [r, g, b].map(reLum); return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722; // 去掉toFixed,保留完整数值 } // Convert hex values to RGB const hexToRGB = function convertHexToRGB(hex) { const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : null; } // Measure the contrast between two colors const contrast = function findContrast(hex1, hex2) { const rgb1 = hexToRGB(hex1); const rgb2 = hexToRGB(hex2); const lum1 = lum(rgb1[0], rgb1[1], rgb1[2]); const lum2 = lum(rgb2[0], rgb2[1], rgb2[2]); const brightest = Math.max(lum1, lum2); const darkest = Math.min(lum1, lum2); return Number((brightest + 0.05) / (darkest + 0.05)).toFixed(2); // 仅在最终结果保留两位小数 } // 现在结果和coolors一致: console.log(`#922626 contrast against white: ${contrast('#922626', '#FFFFFF')}`); // 输出 ~8.31 console.log(`#922626 contrast against black: ${contrast('#922626', '#000000')}`); // 输出 ~2.53 console.log(`#102a47 contrast against white: ${contrast('#102a47', '#FFFFFF')}`); // 输出 ~1.24 console.log(`#102a47 contrast against black: ${contrast('#102a47', '#000000')}`); // 输出 ~14.54
内容的提问来源于stack exchange,提问作者GeorgeCiesinski
相关产品推荐
相关产品推荐

