Skip to content

Instantly share code, notes, and snippets.

@dimdenGD
Created June 29, 2023 16:44
Show Gist options
  • Save dimdenGD/dfbfe3203689a33b59610f39e39284fc to your computer and use it in GitHub Desktop.
Save dimdenGD/dfbfe3203689a33b59610f39e39284fc to your computer and use it in GitHub Desktop.
Function to input color and background color that will change lightness of color to make it more seeable if contrast is too low
const RED = 0.2126;
const GREEN = 0.7152;
const BLUE = 0.0722;
const GAMMA = 2.4;
function luminance(r, g, b) {
const a = [r, g, b].map(v => {
v /= 255;
return v <= 0.03928
? v / 12.92
: Math.pow((v + 0.055) / 1.055, GAMMA);
});
return a[0] * RED + a[1] * GREEN + a[2] * BLUE;
}
function contrast(rgb1, rgb2) {
const lum1 = luminance(...rgb1);
const lum2 = luminance(...rgb2);
const brightest = Math.max(lum1, lum2);
const darkest = Math.min(lum1, lum2);
return (brightest + 0.05) / (darkest + 0.05);
}
function hex2rgb(hex) {
if(!hex.startsWith('#')) hex = `#${hex}`;
const r = parseInt(hex.slice(1, 3), 16)
const g = parseInt(hex.slice(3, 5), 16)
const b = parseInt(hex.slice(5, 7), 16)
return [r, g, b];
}
function rgb2hex(r, g, b) {
return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
}
function rgbToHsl(r, g, b) {
r /= 255; g /= 255; b /= 255;
let max = Math.max(r, g, b);
let min = Math.min(r, g, b);
let d = max - min;
let h;
if (d === 0) h = 0;
else if (max === r) h = ((((g - b) / d) % 6)+6)%6;
else if (max === g) h = (b - r) / d + 2;
else if (max === b) h = (r - g) / d + 4;
let l = (min + max) / 2;
let s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
return [h * 60, s, l];
}
function hslToRgb(h, s, l) {
let c = (1 - Math.abs(2 * l - 1)) * s;
let hp = h / 60.0;
let x = c * (1 - Math.abs((hp % 2) - 1));
let rgb1;
if (isNaN(h)) rgb1 = [0, 0, 0];
else if (hp <= 1) rgb1 = [c, x, 0];
else if (hp <= 2) rgb1 = [x, c, 0];
else if (hp <= 3) rgb1 = [0, c, x];
else if (hp <= 4) rgb1 = [0, x, c];
else if (hp <= 5) rgb1 = [x, 0, c];
else if (hp <= 6) rgb1 = [c, 0, x];
let m = l - c * 0.5;
return [
Math.round(255 * (rgb1[0] + m)),
Math.round(255 * (rgb1[1] + m)),
Math.round(255 * (rgb1[2] + m))
];
}
// hex, hex -> hex
function makeSeeableColor(color, bg_color) {
let bg_rgb = hex2rgb(bg_color);
let rgb = hex2rgb(color);
let c = contrast(bg_rgb, rgb);
let hsl = rgbToHsl(...rgb);
let bg_hsl = rgbToHsl(...bg_rgb);
if(c < 4.5) {
if(bg_hsl[2] > 0.7) {
if(hsl[2] > 0.7) {
hsl[2] = 0.4;
if(hsl[1] >= 0.1) hsl[1] -= 0.1;
}
}
if(bg_hsl[2] < 0.4) {
if(hsl[2] < 0.45) {
hsl[2] = 0.6;
if(hsl[1] >= 0.1) hsl[1] -= 0.1;
}
}
}
return rgb2hex(...hslToRgb(...hsl));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment