Last active
October 24, 2022 19:00
-
-
Save arielsalminen/8511d5ae8afaf088fe44672b0bf1550c to your computer and use it in GitHub Desktop.
getContrastRatio.js
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
/* | |
* Clamp util. | |
*/ | |
const clamp = (val, min, max) => { | |
return Math.min(Math.max(val, min), max) | |
} | |
export default clamp |
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
import hexToRgb from "./hexToRgb.js" | |
import parseRgb from "./parseRgb.js" | |
import isHex from "./isHex.js" | |
/*! | |
* Calculates the contrast ratio between two colors. | |
* | |
* @param {String} A RGB or HEX color value | |
* @param {String} A RGB or HEX color value | |
* @return {String} The contrast ratio | |
*/ | |
const getContrastRatio = (textColor, backgroundColor) => { | |
// Always convert to RGB for calc | |
if (isHex(backgroundColor)) { | |
backgroundColor = hexToRgb(backgroundColor) | |
} | |
if (isHex(textColor)) { | |
textColor = hexToRgb(textColor) | |
} | |
// Convert RGB strings to arrays | |
const [backgroundRed, backgroundGreen, backgroundBlue] = parseRgb(backgroundColor) | |
const [textRed, textGreen, textBlue] = parseRgb(textColor) | |
// Finally return contrast ratio | |
return contrast([backgroundRed, backgroundGreen, backgroundBlue], [textRed, textGreen, textBlue]) | |
} | |
/* | |
* Get luminance from R, G and B. | |
*/ | |
const luminance = (r, g, b) => { | |
const a = [r, g, b].map(function (v) { | |
v /= 255 | |
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4) | |
}) | |
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722 | |
} | |
/* | |
* Get contrast of two colors. | |
*/ | |
const contrast = (rgb1, rgb2) => { | |
const lum1 = luminance(rgb1[0], rgb1[1], rgb1[2]) | |
const lum2 = luminance(rgb2[0], rgb2[1], rgb2[2]) | |
const brightest = Math.max(lum1, lum2) | |
const darkest = Math.min(lum1, lum2) | |
return (brightest + 0.05) / (darkest + 0.05) | |
} | |
export default getContrastRatio |
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
/*! | |
* Convert HEX to RGB. | |
* | |
* @param {String} HEX color value | |
* @return {String} RGB color value | |
*/ | |
const hexToRgb = hex => { | |
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") | |
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i | |
hex = hex.replace(shorthandRegex, function (m, r, g, b) { | |
return r + r + g + g + b + b | |
}) | |
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) | |
const rgb = { | |
r: parseInt(result[1], 16), | |
g: parseInt(result[2], 16), | |
b: parseInt(result[3], 16), | |
} | |
return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})` | |
} | |
export default hexToRgb |
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
/* | |
* Is HEX color | |
*/ | |
const isHex = color => { | |
return color.slice(0, 1) === "#" | |
} | |
export default isHex |
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
import clamp from "./clamp.js" | |
/* | |
* Parse RGB values. | |
*/ | |
const parseRgb = color => { | |
return extractComponents(color).map(parseRgbComponent) | |
} | |
// Extract components utility | |
const extractComponents = color => { | |
const component = /-?\d+(\.\d+)?%?/g | |
return color.match(component) | |
} | |
// Parse RGB component utility | |
const parseRgbComponent = (component, i) => { | |
if (i < 3) { | |
if (component.indexOf("%") != -1) { | |
return Math.round((255 * clamp(parseInt(component, 10), 0, 100)) / 100) | |
} else { | |
return clamp(parseInt(component, 10), 0, 255) | |
} | |
} else { | |
return clamp(parseFloat(component), 0, 1) | |
} | |
} | |
export default parseRgb |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment