Created
June 29, 2023 16:44
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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