Skip to content

Instantly share code, notes, and snippets.

@hoqqanen
Last active February 20, 2018 04:07
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 hoqqanen/a67ea4a98c8abd311cfb61f2f5ae0185 to your computer and use it in GitHub Desktop.
Save hoqqanen/a67ea4a98c8abd311cfb61f2f5ae0185 to your computer and use it in GitHub Desktop.
javascript color utilities
/*
CONTENTS:
- color converters
- randomness helpers
- Color class
- palette generators
*/
// Courtesy of https://stackoverflow.com/questions/17242144/javascript-convert-hsb-hsv-color-to-rgb-accurately
function HSVtoRGBA(h, s, v) {
var r, g, b, i, f, p, q, t;
if (arguments.length === 1) {
s = h.s, v = h.v, h = h.h;
}
i = Math.floor(h * 6);
f = h * 6 - i;
p = v * (1 - s);
q = v * (1 - f * s);
t = v * (1 - (1 - f) * s);
switch (i % 6) {
case 0: r = v, g = t, b = p; break;
case 1: r = q, g = v, b = p; break;
case 2: r = p, g = v, b = t; break;
case 3: r = p, g = q, b = v; break;
case 4: r = t, g = p, b = v; break;
case 5: r = v, g = p, b = q; break;
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), 255];
}
function RGBtoHSV(r, g, b) {
if (arguments.length === 1) {
g = r.g, b = r.b, r = r.r;
}
var max = Math.max(r, g, b), min = Math.min(r, g, b),
d = max - min,
h,
s = (max === 0 ? 0 : d / max),
v = max / 255;
switch (max) {
case min: h = 0; break;
case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break;
case g: h = (b - r) + d * 2; h /= 6 * d; break;
case b: h = (r - g) + d * 4; h /= 6 * d; break;
}
return [h, s, v];
}
function uint() {
return Math.floor(Math.random()*256);
}
function randGray(low, high) {
var u = Math.floor(low + Math.random()*(high-low));
return [u,u,u,255]
}
function randRGBA() {
return [uint(),uint(),uint(),255];
}
class Color {
constructor(rgba) {
this.rgba = rgba;
}
toString() {
var rgba = this.rgba;
return "rgba("+rgba[0]+","+rgba[1]+","+rgba[2]+","+rgba[3]+")";
}
rotate(deg) {
var hsv = RGBtoHSV(...this.rgba);
var h = hsv[0] + deg/360;
h = h - Math.floor(h);
return new Color(HSVtoRGBA(h, hsv[1], hsv[2]));
}
}
/*
PALETTE GENERATORS
*/
function randomPalette(num) {
return Array(num).fill(0).map(_ => new Color(randRGBA()))
}
// Goes from black to bright hue, with optional saturation level.
function valueGradientPalette(hue, num, sat = 1) {
var colors = [];
for (var i = 0; i < num; i++) {
var rgba = HSVtoRGBA(hue, sat, i/(num-1));
colors.push(new Color(rgba))
}
return colors;
}
// Evenly spaced around the color wheel, set saturation and value.
function evenlySpacedHuesPalette(hueStart, num, sat = 1, val = 1) {
var colors = [];
return Array(num).fill(0).map((_, i) => {
var rgba = HSVtoRGBA((hueStart + i/num) % 1, sat, val);
return new Color(rgba);
});
}
// Courtesy https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
function goldenAngleHuesPalette(num, hue = 0, sat = 1, val = 1) {
var phi_conj = 0.618033988749895;
return Array(num).fill(0).map((_, i) => {
var rgba = HSVtoRGBA((i * phi_conj) % 1, sat, val);
return new Color(rgba);
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment