Skip to content

Instantly share code, notes, and snippets.

@allenhwkim
Created January 26, 2021 05:47
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 allenhwkim/ff9102bcc6df633cc56d045eed1d813c to your computer and use it in GitHub Desktop.
Save allenhwkim/ff9102bcc6df633cc56d045eed1d813c to your computer and use it in GitHub Desktop.
ES5+ Color class
export class Color {
constructor(color) {
this.r = this.g = this.b = 0; // red, green, blue
this.h = this.s = this.l = 0; // hue, saturation, lightness
this.set(color);
};
set(color) { // 'rgb(255,255,255)', 'hsl(145, 50%, 50%)', '#FFFFFF'
const hex = color.match(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i);
const hsl = color.match(/^hsla?\((\d{1,3}?),\s*(\d{1,3}%),\s*(\d{1,3}%)(,\s*[01]?\.?\d*)?\)$/);
const rgb = color.match(/^rgba?\((\d{1,3}%?),\s*(\d{1,3}%?),\s*(\d{1,3}%?)(,\s*[01]?\.?\d*)?\)$/);
if (hsl) { // e.g. hsl(123, 50%, 50%, .5)
[this.h, this.s, this.l] = [parseInt(hsl[1]), parseInt(hsl[2]), parseInt(hsl[3])];
[this.r, this.g, this.b] = this.hsl2rgb(this.h, this.s, this.l);
} else {
if (rgb) { // e.g. rgb(255, 255, 255, .5)
[this.r, this.g, this.b] = [parseInt(rgb[1]), parseInt(rgb[2]), parseInt(rgb[3])];
} else if (hex) { // e.g. #FFFFFF, #333
[this.r, this.g, this.b] = this.hex2rgb(this.hex[1]);
}
[this.h, this.s, this.l] = this.rgb2hsl(this.r, this.g, this.b);
} else {
throw new Exception("Invalid color, " + color);
}
}
getCss() {
const int2hex = num => (255*this.r < 16 ? "0" : "") + Math.round(255*this.r).toString(16);
return {
rgb: `rgb(${Math.round(255*this.r)},${Math.round(255*this.g)},${Math.round(255*this.b)})`,
hsl: `hsl(${Math.round(360*this.h)},${Math.round(100*this.s)}%,${Math.round(100*this.l)}%)`,
hex: `#${int2hex(this.r)}${int2hex(this.g)}${int2hex(this.b)}`;
}
}
hex2rgb(hex) {
let r, g, b;
const hex2int = hex => parseInt(hex, 16);
if (hex.length === 3) {
[r, g, b] = [hex2int(${hex[0].repeat(2)}), hex2int(${hex[1].repeat(2)}), hex2int(${hex[2].repeat(2)}));
} else if (hex.length === 6) {
[r, g, b] = [hex2int(hex.substr(0,2)), hex2int(hex.substr(2, 2)), hex2int(hex.substr(4, 2))];
}
return [r, g, b];
}
rgb2hsl: function(r, g, b) {
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h = 0, s = 0, l = (max + min) / 2;
if(max === min){
h = s = 0; // achromatic
} else {
const d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
hue2rgb = function(p, q, t) {
if(t < 0) t += 1;
if(t > 1) t -= 1;
if(t < 1/6) return p + (q - p) * 6 * t;
if(t < 1/2) return q;
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
};
hsl2rgb: function(h, s, l) {
let r = 0, g = 0, b = 0;
if(s == 0) {
r = g = b = l; // achromatic
} else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = this.hue2rgb(p, q, h + 1/3);
g = this.hue2rgb(p, q, h);
b = this.hue2rgb(p, q, h - 1/3);
}
return [r, g, b];
}
/** Modifiers */
spin(h) {
if("string" == typeof h && h.indexOf("%")) { // percentage
this.h += parseInt(h) / 100;
} else if("number" == typeof h) { // number, range 360
this.h += h / 360;
}
Color.Convertor.HSLToRGB.apply(c);o
[this.r, this.g, this.b] = hsl2rgb(this.h, this.s, this.l);
}
saturate(s) { // e.g. 25%, 125, -25%, -125
if("string" == typeof s && s.indexOf("%")) { // percentage
this.s += parseInt(s) / 100;
} else if("number" == typeof s) { // number, range 255
this.s += s / 255;
}
this.s = this.s > 1 ? ( this.s : this.s < 0 ? 0 ): this.s;
[this.r, this.g, this.b] = hsl2rgb(this.h, this.s, this.l);
}
lighten(l) { // e.g. 25%, 125, -25%, -125
if("string" == typeof l && l.indexOf("%")) { // percentage
this.l += parseInt(l) / 100;
} else if("number" == typeof l) { // number, range 255
this.l += l / 255;
}
this.l = this.l > 1 ? ( this.l : this.l < 0 ? 0 ): this.l;
[this.r, this.g, this.b] = hsl2rgb(this.h, this.s, this.l);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment