I'm trying to add a gradient to every element to each page, for now, I've achieved it but I've run into a problem.
If the gradient is too light my text is not visible, is there any way to check if the gradient color is too light and then change the text to black?
Here is my code
This is the gradients element = https://github.com/ghosh/uiGradients/blob/master/gradients.json
const cards = document.querySelectorAll('.card');
cards.forEach((card)=>{
let i = Math.floor(Math.random() * gradients.length);
const color = gradients[i].colors;
color.forEach((color)=> {
let finalGradient = `background: linear-gradient(to right, ${color}, ${color}, ${color}) !important;`;
card.style.cssText = finalGradient;
})
})
Here a function that I use to detect if a color is light or dark. You can use it and adapt to your code:
function isLightOrDark(color) {
// Variables for red, green, blue values
var r, g, b, hsp;
// Check the format of the color, HEX or RGB?
if (color.match(/^rgb/)) {
// If HEX --> store the red, green, blue values in separate variables
color = color.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/);
r = color[1];
g = color[2];
b = color[3];
}
else {
// If RGB --> Convert it to HEX: http://gist.github.com/983661
color = +("0x" + color.slice(1).replace(
color.length < 5 && /./g, '$&$&'));
r = color >> 16;
g = color >> 8 & 255;
b = color & 255;
}
// HSP (Highly Sensitive Poo) equation from http://alienryderflex.com/hsp.html
hsp = Math.sqrt(
0.299 * (r * r) +
0.587 * (g * g) +
0.114 * (b * b)
);
// Using the HSP value, determine whether the color is light or dark
if (hsp>127.5) {
return 'light';
}
else {
return 'dark';
}
}
Related
In my #vue/cli 4.1.1 app user enter color and I have to output
color value with entered color and I wonder how can I calculate and set background color
to be sure that entered color value is good visible. I mean if user entered white color(or near)
background must be dark?
Thanks
You can give an invert color - 255-color for each of rgb
function bg(r, g, b) {return [255-r, 255-g, 255-b]}
if you get it in hex format, you can convert it to rgb, then get the invert. like so:
function invert(hex){
hex = parseInt(hex.substring(1), 16);
var r = hex >> 16;
hex -= r << 16;
var g = hex >> 8;
hex -= g << 8;
var b = hex;
return `rgb(${255-r},${255-g},${255-b})`;
}
var color1 = "#eeff00";
var color2 = "#22faef";
var color3 = "#f1f1f1";
document.querySelector('#a').style = `color:${color1};background-color:${invert(color1)}`;
document.querySelector('#b').style = `color:${color2};background-color:${invert(color2)}`;
document.querySelector('#c').style = `color:${color3};background-color:${invert(color3)}`;
div {
padding: 10px;
}
<div id="a">Hello world!</div>
<div id="b">Hello world!</div>
<div id="c">Hello world!</div>
You can determine the entered color to be light or dark on the basis of its luminance.
Here you can find a formula it's calculated on.
So, you can, for example, define the function isLight like this
function isLight(color) {
// Converting hex color to rgb
const [red, green, blue] = hexToRgb(color);
// Determine luminance
const luminance = (0.299 * red + 0.587 * green + 0.114 * blue)/255;
// Returning true if color is light
return luminance > 0.5;
}
// function for converting hex colors to rgb array format
function hexToRgb(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;
}
By using this function you can determine if the user color is light or dark and thus set the appropriate background
I have some colors in RGB24 format, for example: 1581613
How to convert it to RGB for web usage?
If I understand correctly, the format is as follows RRRGGBB.
Last code i've trying to run is:
const color = 1581613;
const red = (color >> 5) * 255 / 7;
const green = ((color >> 2) & 0x07) * 255 / 7;
const blue = (color & 0x03) * 255 / 3;
But my attempts did not lead to success.
I'm guessing a lot here, but here goes:
const color = 1581613;
const red = (color >> 16) & 255;
const green = (color >> 8) & 255;
const blue = color & 255;
const hex = red.toString(16) + green.toString(16) + blue.toString(16);
document.write(JSON.stringify({rgb: [red, green, blue], hex }, null, 2));
I'm making a color game via a course which generates 6 squares with random colours. When you click on a square which corresponds with the target color, you win the game.
Here's a link to how the game should work using RGB:
https://jsfiddle.net/jdwrgbh0/
I'm using HSL values instead.
Here's my code using HSL:
https://jsfiddle.net/fh7boykd/
(The only difference is this code for generate random colors)
function randomColor() {
var h = Math.floor(Math.random() * 361);
var s = Math.floor(Math.random() * 101);
var l = Math.floor(Math.random() * 101);
return "hsl(" + h + ', ' + s + '%' + ', ' + l + '%' + ")";
}
Even though I used the function above to generate HSL values, the background-color of the squares still shows RGB values instead of HSL values and as such, I can't win the game because the target color is never shown. I want the color of the squares to display background-color in HSL and not RGB. The above randomColor function seems fine and testing it in the console, it does seem to generate a random color after it's invoked each time.
Here's an image of the console when I run the code. The background-color is in RGB and not HSL.
I think the problem may be related to this function:
function changeColors(color){
//loop through all squares
for(var i = 0; i < squares.length; i++){
//change each color to match given color
squares[i].style.background = color;
}
}
This code changes the color of each square. When I look at the browser console, it shows RGB values instead of HSL values. How do I force squares[i].style.background = color; to use HSL instead of RGB?
The browser will convert your HSL back to RGB colors. From what I see in your question, you are using HSL just so you can generate random colors. You can also use this piece of code to generate random hex color code
var generateRandomHexColor = () => {
var allPossibleLetters = '0123456789ABCDEF';
var HexCode = '';
for (var i = 0; i < 6; i++) {
HexCode += allPossibleLetters[Math.floor(Math.random() * 16)];
}
return '#' + HexCode;
}
console.log(generateRandomHexColor())
I believe your question is that you want to be able to convert RGB to HSL and then understand that HSL value. This is entirely possible. I have found some js script off of github, from user mjackson.
/**
* Converts an RGB color value to HSL. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes r, g, and b are contained in the set [0, 255] and
* returns h, s, and l in the set [0, 1].
*
* #param Number r The red color value
* #param Number g The green color value
* #param Number b The blue color value
* #return Array The HSL representation
*/
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [ h, s, l ];
}
You may be able to adapt this to the way that you wish. I hope this helped.
Cheers!
if you want to set as hsl, just like this format:
divElement.style.backgroundColor = "hsl(155,100%,30%)";
but you want to got the style, that must be rgb or rgba string. so you must change it to hsl by your self.
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??
JS FIDDLE
<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.
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.
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?
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
}
JSFiddle
This question already has answers here:
Programmatically Lighten or Darken a hex color (or rgb, and blend colors)
(21 answers)
Closed 9 years ago.
I want to have the user be able to enter a random hex color and my javascript code would print out a lighter version of that color (some sort of algorithm so to speak)
A quick example of how I want the colors to change.
What the user inputs: #2AC0A3
What it spits out: #C6EEE6
Thanks so much to anyone who can help!
An easy way to lighten up a color is linear interpolation with white. In the same way, a color can be darkened by interpolating with black.
Here's a function that takes a color string and changes the brightness indicated by light:
function hex2(c) {
c = Math.round(c);
if (c < 0) c = 0;
if (c > 255) c = 255;
var s = c.toString(16);
if (s.length < 2) s = "0" + s;
return s;
}
function color(r, g, b) {
return "#" + hex2(r) + hex2(g) + hex2(b);
}
function shade(col, light) {
// TODO: Assert that col is good and that -1 < light < 1
var r = parseInt(col.substr(1, 2), 16);
var g = parseInt(col.substr(3, 2), 16);
var b = parseInt(col.substr(5, 2), 16);
if (light < 0) {
r = (1 + light) * r;
g = (1 + light) * g;
b = (1 + light) * b;
} else {
r = (1 - light) * r + light * 255;
g = (1 - light) * g + light * 255;
b = (1 - light) * b + light * 255;
}
return color(r, g, b);
}
When light is negative, the color is darkened; -1 always yields black. When light is positive, the color is lightened, 1always yields white. Finally, 0 always yields the original color:
alert(shade("#2ac0a3", 0.731));