Reputation: 2313
I have some color swatches that should show the rgb value of the color displayed, with the background being the actual color. Then, if the color in question is light-ish, the text should be black, and if the color in question is dark-ish, the text color should be white.
How can I detect if the RGB value is light-ish or dark-ish??
<style>
#preview {
display: block;
height: 40px;
line-height: 40px;
font-size: 20px;
vertical-align: middle;
width: 150px;
text-align: center;
}
</style>
<!-- html -->
<button id="new_color">Try Random Color</button>
<p id="preview">Click the button!</p>
<script>
const getRandNum = () => Math.floor(Math.random() * 256);
const get_random_color = () => (`rgb(${getRandNum()}, ${getRandNum()}, ${getRandNum()})`);
const checkColor = (color) => {
// color = 'rgb(x, y, z)';
// check color is light
// or color is dark
return true;
}
$('#new_color').click(function(){
const p = $('#preview');
const bg_color = get_random_color();
const color_is_light = checkColor( bg_color );
const text_color = color_is_light ? 'black' : 'white';
p.css({
color: text_color,
backgroundColor: bg_color
})
});
</script>
I only found solutions for #hex colors, but not for rgb. Any help is very much appreciated.
Upvotes: 3
Views: 2433
Reputation: 5586
You have to check if(red + green + blue >= 255 * 1.5)
for a light color as said by the second answer in this post
const checkColor = (color) => {
// extract values of red, green and blue from color
let clrarr = color.match(/\d+/g).map(num => +num);
if(clrarr[0] + clrarr[1] + clrarr[2] >= 255 * 3 / 2)
return true; // color is light
return false; // color is dark
}
Upvotes: 0
Reputation: 140032
If you're looking for relative luminance, a quick formula you can use is:
Y = 0.2126R + 0.7152G + 0.0722B
Source: https://en.wikipedia.org/wiki/Relative_luminance
To be able to use the coefficients above directly, you'll have to either normalize your RGB components to 1. Or divide by 255 first. The Y value you'll get is between 0-1, so you can probably then do:
const color_is_light = y > 0.5;
I'd do something like:
const getRandomRgb = () => [
Math.random(),
Math.random(),
Math.random()
];
const getRelativeLuminance = (rgb) =>
0.2126 * rgb[0]
+ 0.7152 * rgb[1]
+ 0.0722 * rgb[2];
const getCssColor = (rgb) => `rgb(${rgb.map((c) => c * 255)}`;
Though, there'll literally be a "gray area" where you will not get enough contrast with either white or black text against a mid-gray background.
You may want to change your get_random_color
function to return the individual components, do the math above, and then construct the CSS color value afterwards.
Upvotes: 4
Reputation: 801
So if you have answers for hex, adapt those for RGB because the hex values are just the base 16 numbers of the rgb base 10 values. Looking for a way to convert between bases now.
EDIT: If your r value in hex is "5a", the way to get that r value in base 10 for rgb() is parseInt("5a",16)
EDIT2: To get the hex value from decimal, this works: const hex = d => Number(d).toString(16).padStart(2, '0')
~ taken from How to convert decimal to hex in JavaScript?
Upvotes: 0