Skip to content

Instantly share code, notes, and snippets.

@sampotts
Last active June 13, 2018 04:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sampotts/412b46777fff8a8b926deb11c4312296 to your computer and use it in GitHub Desktop.
Save sampotts/412b46777fff8a8b926deb11c4312296 to your computer and use it in GitHub Desktop.
// ==========================================================================
// 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