Last active
June 13, 2018 04:17
-
-
Save sampotts/412b46777fff8a8b926deb11c4312296 to your computer and use it in GitHub Desktop.
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
// ========================================================================== | |
// Simple color manipulation library | |
// ========================================================================== | |
const clamp = (input = 0, min = 0, max = 255) => { | |
return Math.min(Math.max(input, min), max); | |
}; | |
const regex = new RegExp(/^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/, 'i'); | |
const parse = (input = '#000') => { | |
if (regex.test(input)) { | |
return input; | |
} | |
let color = input; | |
if (!color.startsWith('#')) { | |
color = `#${color}`; | |
} | |
// Handle short form | |
if (color.length === 4) { | |
const r = color[1]; | |
const g = color[2]; | |
const b = color[3]; | |
color = `#${r}${r}${g}${g}${b}${b}`; | |
} | |
if (!regex.test(color)) { | |
return '#000000'; | |
} | |
return color; | |
}; | |
const lighten = (input, percent) => { | |
const color = input.substring(1); | |
const num = parseInt(color, 16); | |
const amt = Math.round(2.55 * clamp(percent, -100, 100)); | |
const R = (num >> 16) + amt; // eslint-disable-line no-bitwise | |
const B = ((num >> 8) & 0x00ff) + amt; // eslint-disable-line no-bitwise | |
const G = (num & 0x0000ff) + amt; // eslint-disable-line no-bitwise | |
return `#${(0x1000000 + clamp(R) * 0x10000 + clamp(B) * 0x100 + clamp(G)).toString(16).slice(1)}`; | |
}; | |
class Color { | |
constructor(hex = '#000') { | |
this.color = parse(hex); | |
} | |
get hex() { | |
return this.color; | |
} | |
get channels() { | |
const result = regex.exec(this.color); | |
return { | |
r: parseInt(result[1], 16), | |
g: parseInt(result[2], 16), | |
b: parseInt(result[3], 16), | |
}; | |
} | |
get rgb() { | |
const rgb = this.channels; | |
return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`; | |
} | |
rgba(alpha = 1) { | |
const rgb = this.channels; | |
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${clamp(alpha, 0, 1)})`; | |
} | |
darken(percent = 0) { | |
return new Color(lighten(this.color, Math.abs(percent) * -1)); | |
} | |
lighten(percent = 0) { | |
return new Color(lighten(this.color, Math.abs(percent) * 1)); | |
} | |
} | |
export default Color; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment