Skip to content

Instantly share code, notes, and snippets.

@westc
Last active March 30, 2019 04:50
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 westc/e2830febf6f2bc31ac16aa3a2cc39023 to your computer and use it in GitHub Desktop.
Save westc/e2830febf6f2bc31ac16aa3a2cc39023 to your computer and use it in GitHub Desktop.
Color JS library
/**
* @preserve CWest-Color.js - Manipulate colors easily!
* https://gist.github.com/westc/e2830febf6f2bc31ac16aa3a2cc39023
*
* Copyright (c) 2018-2019 Christopher West
* Licensed under the MIT license.
*/
(function (global, Math, names, namedColors, strColors) {
(function (factory) {
if (typeof define === "function" && define.amd) {
define(["exports"], factory);
}
else if (typeof exports !== "undefined") {
factory(exports);
}
else {
var mod = { exports: {} };
factory(mod.exports);
global.Color = mod.exports.Color;
}
})(
function (exports) {
strColors.replace(
/((?:[A-Z][a-z]+)+)((?:[A-F0-9]{3}){1,2})/g,
function (_, name, hex) {
namedColors.push([name.toUpperCase(), hex]);
names.push(name);
}
);
function implodePct(array, opt_pctArray) {
return array.slice().map(function(v, isPct) {
isPct = !opt_pctArray || opt_pctArray[isPct];
return Math.round(v * (isPct ? 100 : 1)) / (isPct < 0 ? 100 : 1) + (isPct > 0 ? '%' : '');
}).join(', ');
}
function hue2rgb(p, q, t) {
t += t < 0 ? 1 : t > 1 ? -1 : 0;
return t < 1 / 6
? p + (q - p) * 6 * t
: t < 1 / 2
? q
: t < 2 / 3
? p + (q - p) * (2 / 3 - t) * 6
: p;
}
function hsl2rgb(h, s, l) {
var r, g, b;
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;
h = ((h / 360) % 1 + 1) % 1;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
function cmyk2rgb(c, m, y, k) {
return [
Math.round(255 * (1 - c) * (1 - k)),
Math.round(255 * (1 - m) * (1 - k)),
Math.round(255 * (1 - y) * (1 - k))
];
}
function parseRGBA(colorName) {
colorName = (colorName || '').replace(/\s|#/g, '').toUpperCase();
var rgb, parts = /^HSLA?\(([\d\.]+),([\d\.]+)(%)?,([\d\.]+)(%)?(?:,([\d\.]+)(%)?)?\)$/i.exec(colorName);
if (parts) {
rgb = hsl2rgb(+parts[1], +parts[2] / (parts[3] ? 100 : 1), +parts[4] / (parts[5] ? 100 : 1));
return [rgb[0], rgb[1], rgb[2], parts[6] ? +parts[6] / (parts[7] ? 100 : 1) : 1];
}
parts = /^CMYKA?\(([\d\.]+)(%)?,([\d\.]+)(%)?,([\d\.]+)(%)?,([\d\.]+)(%)?(?:,([\d\.]+)(%)?)?\)/.exec(colorName);
if (parts) {
rgb = cmyk2rgb(
+parts[1] / (parts[2] ? 100 : 1),
+parts[3] / (parts[4] ? 100 : 1),
+parts[5] / (parts[6] ? 100 : 1),
+parts[7] / (parts[8] ? 100 : 1)
);
return [rgb[0], rgb[1], rgb[2], parts[9] ? +parts[9] / (parts[10] ? 100 : 1) : 1];
}
parts = /^RGBA?\(([\d\.]+),([\d\.]+),([\d\.]+)(?:,([\d\.]+)(%)?)?\)$/.exec(colorName);
if (parts) {
return [
+parts[1],
+parts[2],
+parts[3],
parts[4] ? +parts[4] / (parts[5] ? 100 : 1) : 1
];
}
parts = /^(?=(?:[A-F0-9]{3,4}){1,2}$)(.)(.)?(.)(.)?(.)(.)?(?:(.)(.)?)?$/.exec(colorName);
if (parts) {
return [
parseInt(parts[1] + parts[parts[2] ? 2 : 1], 16),
parseInt(parts[3] + parts[parts[4] ? 4 : 3], 16),
parseInt(parts[5] + parts[parts[6] ? 6 : 5], 16),
parts[7] ? parseInt(parts[7] + parts[parts[8] ? 8 : 7], 16) / 100 : 1
];
}
for (var namedColor, i = namedColors.length; namedColor = namedColors[--i];) {
if (namedColor[0] === colorName) {
return parseRGBA(namedColor[1]);
}
}
}
function Color(input) {
return this instanceof Color ? this.set(input) : new Color(input);
}
var proto = Color.prototype = {
constructor: Color,
set: function (input) {
if (input instanceof Color) {
this._ = input._.slice();
}
else {
var rgbahslcmyk = this._ = parseRGBA(input) || [0, 0, 0, 0];
var r = rgbahslcmyk[0],
g = rgbahslcmyk[1],
b = rgbahslcmyk[2],
r1 = r / 255,
g1 = g / 255,
b1 = b / 255,
cMax = Math.max(r1, g1, b1),
cMin = Math.min(r1, g1, b1),
delta = cMax - cMin,
h = cMax !== cMin
? Math.round(
60 * (
cMax === r1
? (((g1 - b1) / delta) % 6 + 6) % 6
: cMax === g1
? ((b1 - r1) / delta) + 2
: ((r1 - g1) / delta) + 4
)
)
: 0,
l = (cMax + cMin) / 2,
s = delta ? delta / 1 - Math.abs(2 * l - 1) : 0,
k = 1 - cMax,
c = (1 - r1 - k) / (1 - k),
m = (1 - g1 - k) / (1 - k),
y = (1 - b1 - k) / (1 - k);
rgbahslcmyk.push(h, s, l, c, m, y, k);
}
return this;
},
brightness: function () {
var rgbahslcmyk = this._;
return (rgbahslcmyk[0] * 299 + rgbahslcmyk[1] * 587 + rgbahslcmyk[2] * 114) / 1e3;
},
hex: function (opt_allow3Digits) {
return this.hexAlpha(opt_allow3Digits).replace(/(.(..?){3})..?/, '$1');
},
hexAlpha: function (opt_allow4Digits) {
var rgbahslcmyk = this._;
rgbahslcmyk = (
'#'
+ rgbahslcmyk.slice(0, 3).concat(rgbahslcmyk[3] * 255).map(function(x) {
return ',0' + Math.round(x).toString(16).toUpperCase();
}).join('')
)
.replace(/,0?(\w\w)/g, '$1');
return opt_allow4Digits ? rgbahslcmyk.replace(/(.)\1(.)\2(.)\3(.)\4/, '$1$2$3$4') : rgbahslcmyk;
},
toString: function () {
return this.rgba().replace(/rgba(.+), 1\)/, 'rgb$1)');
}
};
'-Alpha'.replace(/^|.+/g, function (suffix) {
proto['mix' + suffix] = function (color2, opt_pct2OrColor3) {
var rgba1, rgba2, pct1 = 0.5, args = arguments, argc = args.length;
if (argc < 2) {
opt_pct2OrColor3 = pct1;
}
rgba1 = this._.slice(0, 4);
if ('number' === typeof opt_pct2OrColor3) {
rgba2 = parseRGBA(color2);
opt_pct2OrColor3 = Math.min(Math.max(0, opt_pct2OrColor3), 1);
pct1 = 1 - opt_pct2OrColor3;
rgba1 = this
.r(Math.round(rgba1[0] * pct1 + rgba2[0] * opt_pct2OrColor3))
.g(Math.round(rgba1[1] * pct1 + rgba2[1] * opt_pct2OrColor3))
.b(Math.round(rgba1[2] * pct1 + rgba2[2] * opt_pct2OrColor3));
return suffix ? rgba1.a(rgba1[3] * pct1 + rgba2[3] * opt_pct2OrColor3) : rgba1;
}
var r = rgba1[0];
var g = rgba1[1];
var b = rgba1[2];
var a = rgba1[3];
for (var i = argc, denom = argc + 1; i--;) {
rgba2 = parseRGBA(arguments[i]);
r += rgba2[0];
g += rgba2[1];
b += rgba2[2];
a += rgba2[3];
}
this.r(Math.round(r / denom)).g(Math.round(g / denom)).b(Math.round(b / denom));
return suffix ? this.a(Math.round(a / denom)) : this;
};
});
// Adds:
// - Color.prototype.rgb()
// - Color.prototype.rgba()
// - Color.prototype.hsl()
// - Color.prototype.hsla()
// - Color.prototype.cmyk()
// - Color.prototype.cmyka()
Function(
"p,i,a",
"rgb 0,3),[];rgba 0,4),[0,0,0,-1];cmyk 7);cmyka 7).concat(this._[3]),[1,1,1,1,-1];hsl 4,7),[0,1,1];hsla 4,7).concat(this._[3]),[0,1,1,-1]"
.replace(/(\w+) ([^;]+)/g, function (params, name, code, l) {
params = name.split("").join(",");
l = name.length;
return "p.%=function(#){return arguments.length?this.set('%('+a.slice.call(arguments,0,~).join(',')+')'):'%('+i(this._.slice(@)+')'}"
.replace(/%/g, name)
.replace(/#/g, params)
.replace(/~/g, l)
.replace(/@/g, code);
})
)(proto, implodePct, namedColors);
// Adds:
// - Color.prototype.r()
// - Color.prototype.g()
// - Color.prototype.b()
// - Color.prototype.a()
// - Color.prototype.h()
// - Color.prototype.s()
// - Color.prototype.l()
// - Color.prototype.c()
// - Color.prototype.m()
// - Color.prototype.y()
// - Color.prototype.k()
'rgbahslcmyk'.replace(/./g, function (part, index) {
proto[part] = function (opt_newValue) {
var _ = this._;
if (opt_newValue !== undefined) {
if (_) {
var offset,
slice = _.slice.bind(_),
modGroup = index < 4 ? slice(offset = 0, 4) : index < 7 ? slice(offset = 4, 7) : slice(offset = 7),
modGroupName = index < 4 ? 'rgba' : index < 7 ? 'hsl' : 'cmyk';
modGroup[index - offset] = 'function' === typeof opt_newValue
? opt_newValue(modGroup[index - offset])
: opt_newValue;
this.set(modGroupName + '(' + modGroup.join(', ') + ')');
}
return this;
}
else {
return _[index];
}
};
});
Object.keys(proto).forEach(function (key) {
if (/^(rgb|hsl|cmyk)a?$/.test(key)) {
Color[key] = function(arg0) {
var args = namedColors.slice.call(arguments);
var isGetter = args.length === 1;
var color = Color(isGetter ? arg0 : 'black');
return isGetter ? color[key]() : color[key].apply(color, args);
}
}
else if (!/^(constructor|set)$/.test(key)) {
Color[key] = function (arg1) {
return proto[key].apply(new Color(arg1), namedColors.slice.call(arguments, 1));
};
}
});
Color.names = function() { return names.slice(); };
// expose Color to other modules
exports.Color = Color;
}
);
})(this, Math, [], [], "IndianRedCD5C5CLightCoralF08080SalmonFA8072DarkSalmonE9967ACrimsonDC143CRedF00FireBrickB22222DarkRed8B0000PinkFFC0CBLightPinkFFB6C1HotPinkFF69B4DeepPinkFF1493MediumVioletRedC71585PaleVioletRedDB7093LightSalmonFFA07ACoralFF7F50TomatoFF6347OrangeRedFF4500DarkOrangeFF8C00OrangeFFA500GoldFFD700YellowFF0LightYellowFFFFE0LemonChiffonFFFACDLightGoldenrodYellowFAFAD2PapayaWhipFFEFD5MoccasinFFE4B5PeachPuffFFDAB9PaleGoldenrodEEE8AAKhakiF0E68CDarkKhakiBDB76BLavenderE6E6FAThistleD8BFD8PlumDDA0DDVioletEE82EEOrchidDA70D6FuchsiaF0FMagentaF0FMediumOrchidBA55D3MediumPurple9370DBRebeccaPurple639BlueViolet8A2BE2DarkViolet9400D3DarkOrchid9932CCDarkMagenta8B008BPurple800080Indigo4B0082SlateBlue6A5ACDDarkSlateBlue483D8BGreenYellowADFF2FChartreuse7FFF00LawnGreen7CFC00Lime0F0LimeGreen32CD32PaleGreen98FB98LightGreen90EE90MediumSpringGreen00FA9ASpringGreen00FF7FMediumSeaGreen3CB371SeaGreen2E8B57ForestGreen228B22Green008000DarkGreen006400YellowGreen9ACD32OliveDrab6B8E23Olive808000DarkOliveGreen556B2FMediumAquamarine66CDAADarkSeaGreen8FBC8BLightSeaGreen20B2AADarkCyan008B8BTeal008080Aqua0FFCyan0FFLightCyanE0FFFFPaleTurquoiseAFEEEEAquamarine7FFFD4Turquoise40E0D0MediumTurquoise48D1CCDarkTurquoise00CED1CadetBlue5F9EA0SteelBlue4682B4LightSteelBlueB0C4DEPowderBlueB0E0E6LightBlueADD8E6SkyBlue87CEEBLightSkyBlue87CEFADeepSkyBlue00BFFFDodgerBlue1E90FFCornflowerBlue6495EDMediumSlateBlue7B68EERoyalBlue4169E1Blue00FMediumBlue0000CDDarkBlue00008BNavy000080MidnightBlue191970CornsilkFFF8DCBlanchedAlmondFFEBCDBisqueFFE4C4NavajoWhiteFFDEADWheatF5DEB3BurlyWoodDEB887TanD2B48CRosyBrownBC8F8FSandyBrownF4A460GoldenrodDAA520DarkGoldenrodB8860BPeruCD853FChocolateD2691ESaddleBrown8B4513SiennaA0522DBrownA52A2AMaroon800000WhiteFFFSnowFFFAFAHoneyDewF0FFF0MintCreamF5FFFAAzureF0FFFFAliceBlueF0F8FFGhostWhiteF8F8FFWhiteSmokeF5F5F5SeaShellFFF5EEBeigeF5F5DCOldLaceFDF5E6FloralWhiteFFFAF0IvoryFFFFF0AntiqueWhiteFAEBD7LinenFAF0E6LavenderBlushFFF0F5MistyRoseFFE4E1GainsboroDCDCDCLightGrayD3D3D3LightGreyD3D3D3SilverC0C0C0DarkGrayA9A9A9DarkGreyA9A9A9Gray808080Grey808080DimGray696969DimGrey696969LightSlateGray789LightSlateGrey789SlateGray708090SlateGrey708090DarkSlateGray2F4F4FDarkSlateGrey2F4F4FBlack000");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment