Created
March 29, 2019 15:59
-
-
Save rynbyjn/0208126b4afc3d0728f72ff69bc97d3a to your computer and use it in GitHub Desktop.
Some helper functions for color manipulation and compliance in javascript
This file contains 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
export const fullHex = (hex: string): string => { | |
let h: string = hex.replace(/[^a-f\d]/gi, '') | |
if (h.length < 6) { | |
h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2] | |
} | |
return h | |
} | |
export const updateHexLuminance = (hex: string, lum: number = 0): string => { | |
const h: string = fullHex(hex) | |
let newHex: string = '#' | |
for (let i = 0; i < 3; i++) { | |
const c: number = parseInt(h.substr(i * 2, 2), 16) | |
const s: string = Math.round( | |
Math.min(Math.max(0, c + c * lum), 255), | |
).toString(16) | |
newHex += ('00' + s).substr(s.length) | |
} | |
return newHex | |
} | |
export const luminance = (rgb: number[]): number => { | |
const a: number[] = rgb.map(v => { | |
const l = v / 255 | |
return l <= 0.03928 ? l / 12.92 : Math.pow((l + 0.055) / 1.055, 2.4) | |
}) | |
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722 | |
} | |
export const hexToRGB = (hex: string): number[] => { | |
const h: string = fullHex(hex) | |
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(h) | |
if (!result) { | |
return [] | |
} | |
return [ | |
parseInt(result[1], 16), | |
parseInt(result[2], 16), | |
parseInt(result[3], 16), | |
] | |
} | |
export const contrast = (fg: string, bg: string): number => { | |
const fgRGB: number[] = hexToRGB(fg) | |
const bgRGB: number[] = hexToRGB(bg) | |
const fgL: number = luminance(fgRGB) | |
const bgL: number = luminance(bgRGB) | |
return (Math.max(fgL, bgL) + 0.05) / (Math.min(fgL, bgL) + 0.05) | |
} | |
export const compliant = ( | |
fg: string, | |
bg: string, | |
): [boolean, number, string] => { | |
const c: number = contrast(fg, bg) | |
if (c >= 7) { | |
return [true, c, 'AAA'] | |
} else if (c >= 4.5) { | |
return [true, c, 'AA && big AAA (>= 18px font)'] | |
} else if (c >= 3) { | |
return [true, c, 'big AA (>= 18px font)'] | |
} | |
return [false, c, 'not compliant'] | |
} | |
export default compliant |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment