I am trying to create a module that returns the contrast ratio. The intended use is to get a color, and determine whether the contrast against white and black so that I can pick whichever one contrasts more strongly with the color.
I referred to this stack overflow question to help me with it. My version seems to work at first, but when I test it, my results seem to be way off. I compared my output to coolors contrast checker and pasted the result in the comment next to my own result so you can see how far off it is:
// Measure the relative luminance of each RGB value
const reLum = function relativeLuminance(RGB) {
let newRGB = RGB;
newRGB /= 255;
return newRGB <= 0.03928 ?
newRGB / 12.92 :
(newRGB 0.055) / 1.055 ** 2.4;
}
// Measure the luminance of the color
const lum = function luminance(r, g, b) {
const a = [r, g, b].map(reLum);
return Number(a[0] * 0.2126 a[1] * 0.7152 a[2] * 0.0722).toFixed(3);
}
// 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 (brightest 0.05) / (darkest 0.05);
}
// Contrast is 3.16 against white VS coolors 8.31
console.log(`#922626 contrast against white: ${contrast('#922626', '#FFFFFF')}`);
// Contrast is 6.18 against black VS coolors 2.53
console.log(`#922626 contrast against black: ${contrast('#922626', '#000000')}`);
// Contrast is 4.23 against white VS coolors 1.24
console.log(`#102a47 contrast against white: ${contrast('#102a47', '#FFFFFF')}`);
// Contrast is 4.61 against black VS coolors 14.54
console.log(`#102a47 contrast against black: ${contrast('#102a47', '#000000')}`);
In my second example, white is clearly supposed to have a bigger contrast with #102a47
since black is nearly indistinguishable from it, but my calculation seems to think that it contrasts equally with white & black.
Obviously, there is some kind of flaw in my calculation, but despite checking the math on W3 here and here, I can't find my mistake.
CodePudding user response:
Missing ()
for exponent in reLum
on this line:
(newRGB 0.055) / 1.055 ** 2.4;
should be
((newRGB 0.055) / 1.055) ** 2.4;
// Measure the relative luminance of each RGB value
const reLum = function relativeLuminance(RGB) {
let newRGB = RGB;
newRGB /= 255;
return newRGB <= 0.03928 ?
newRGB / 12.92 :
((newRGB 0.055) / 1.055) ** 2.4;
}
// Measure the luminance of the color
const lum = function luminance(r, g, b) {
const a = [r, g, b].map(reLum);
return Number(a[0] * 0.2126 a[1] * 0.7152 a[2] * 0.0722).toFixed(3);
}
// 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 (brightest 0.05) / (darkest 0.05);
}
// Contrast is 3.16 against white VS coolors 8.31
console.log(`#922626 contrast against white: ${contrast('#922626', '#FFFFFF')}`);
// Contrast is 6.18 against black VS coolors 2.53
console.log(`#922626 contrast against black: ${contrast('#922626', '#000000')}`);
// Contrast is 4.23 against white VS coolors 14.54
console.log(`#102a47 contrast against white: ${contrast('#102a47', '#FFFFFF')}`);
// Contrast is 4.61 against black VS coolors 1.24
console.log(`#102a47 contrast against black: ${contrast('#102a47', '#000000')}`);