Improve text color on CO2 color rectangle
See original GitHub issueHi,
Two years ago, I proposed you to use a background based color text for CO2 color rectangle. (#1886)
You accepted my proposition, and I was kind of proud of it. But, after some new tests, I realized it was not the best solution.
I said you to use the YIQ contrast method, what you did. But in some cases, when background color is brown, it doesn’t produce a good result, especially on mobile with very low luminosity.
Instead of YIQ method, I tested the W3CAG method more in depth. With the default settings, result is close to the YIQ method and it doesn’t solve the problem for these colors. So I modified it a bit. The idea is to switch to white text earlier on the color ramp. The switch should, in my opinion, starts around 400g/kWh.
You can play with this CodePen to see the difference between YIQ, W3CAG standard and my modified version : https://codepen.io/phiphou/pen/YBeMxw
You can find more informations about W3CAG color contrast here : https://www.w3.org/TR/WCAG20-TECHS/G17.html
It is not standard, but it meets the needs well.
Here is how to implement my solution in web/src/components/carbonintensitysquare.js :
const getTextColor = rgbColor=> {
const colors = rgbColor.replace(/[^\d,.]/g, '').split(',');
const r = parseInt(colors[0], 10);
const g = parseInt(colors[1], 10);
const b = parseInt(colors[2], 10)
const rgbArr = [r, g, b];
const computedArr = rgbArr.map (c => {
const s = c / 255;
return s <= 0.03928 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
})
const luminosity = 0.2126 * computedArr[0] + 0.7152 * computedArr[1] + 0.0722 * computedArr[2];
// Here is the modification, I changed (1.05 * 0.05) whith (1.05 * 0.16)
// Math.sqrt(1.05 * 0.16) - 0.05 is a constant, it can be replaced with it's
// approached value (0.35987803063838397) to avoid useless computations
return luminosity > Math.sqrt(1.05 * 0.16) - 0.05 ? "black" : "white";
};
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:7 (7 by maintainers)
I will try to do it this weekend (it will be my first PR ever 😉)
Here is a sample :
I think the modified version on the right is better that the actual version on the left.
Notice the difference is more visible in small elements, like the color rectangle, than in my previous CodePen, because the colored area is bigger and our brain see a less contrasted image. I modified my CodePen to show the things in small rectangles like on the map.
It’s more visible on mobile devices, especially with low luminosity. From 400g/kWh, background start becoming quite dark, and the contrast between the background and the black text seems not big enough to me. Setting a white text make the rectangle more readable.
Notice that W3CAG contrast ratio is given bigger on left image (5.7:1) than in the right image (3.68:1). But I think it’s visible that perceived contrast is bigger on right image.
I understand it’s not a major improvement. Maybe we can let this issue open and ask people to use my CodePen to determine at what value they think the switch to white should happen.