UNPKG

chroma-js

Version:

JavaScript library for color conversions

1,736 lines (1,423 loc) 99.3 kB
/** * chroma.js - JavaScript library for color conversions * * Copyright (c) 2011-2019, Gregor Aisch * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The name Gregor Aisch may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ------------------------------------------------------- * * chroma.js includes colors from colorbrewer2.org, which are released under * the following license: * * Copyright (c) 2002 Cynthia Brewer, Mark Harrower, * and The Pennsylvania State University. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific * language governing permissions and limitations under the License. * * ------------------------------------------------------ * * Named colors are taken from X11 Color Names. * http://www.w3.org/TR/css3-color/#svg-color * * @preserve */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.chroma = factory()); }(this, (function () { 'use strict'; var limit = function (x, min, max) { if ( min === void 0 ) min=0; if ( max === void 0 ) max=1; return x < min ? min : x > max ? max : x; }; var clip_rgb = function (rgb) { rgb._clipped = false; rgb._unclipped = rgb.slice(0); for (var i=0; i<=3; i++) { if (i < 3) { if (rgb[i] < 0 || rgb[i] > 255) { rgb._clipped = true; } rgb[i] = limit(rgb[i], 0, 255); } else if (i === 3) { rgb[i] = limit(rgb[i], 0, 1); } } return rgb; }; // ported from jQuery's $.type var classToType = {}; for (var i = 0, list = ['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Undefined', 'Null']; i < list.length; i += 1) { var name = list[i]; classToType[("[object " + name + "]")] = name.toLowerCase(); } var type = function(obj) { return classToType[Object.prototype.toString.call(obj)] || "object"; }; var unpack = function (args, keyOrder) { if ( keyOrder === void 0 ) keyOrder=null; // if called with more than 3 arguments, we return the arguments if (args.length >= 3) { return Array.prototype.slice.call(args); } // with less than 3 args we check if first arg is object // and use the keyOrder string to extract and sort properties if (type(args[0]) == 'object' && keyOrder) { return keyOrder.split('') .filter(function (k) { return args[0][k] !== undefined; }) .map(function (k) { return args[0][k]; }); } // otherwise we just return the first argument // (which we suppose is an array of args) return args[0]; }; var last = function (args) { if (args.length < 2) { return null; } var l = args.length-1; if (type(args[l]) == 'string') { return args[l].toLowerCase(); } return null; }; var PI = Math.PI; var utils = { clip_rgb: clip_rgb, limit: limit, type: type, unpack: unpack, last: last, PI: PI, TWOPI: PI*2, PITHIRD: PI/3, DEG2RAD: PI / 180, RAD2DEG: 180 / PI }; var input = { format: {}, autodetect: [] }; var last$1 = utils.last; var clip_rgb$1 = utils.clip_rgb; var type$1 = utils.type; var Color = function Color() { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var me = this; if (type$1(args[0]) === 'object' && args[0].constructor && args[0].constructor === this.constructor) { // the argument is already a Color instance return args[0]; } // last argument could be the mode var mode = last$1(args); var autodetect = false; if (!mode) { autodetect = true; if (!input.sorted) { input.autodetect = input.autodetect.sort(function (a,b) { return b.p - a.p; }); input.sorted = true; } // auto-detect format for (var i = 0, list = input.autodetect; i < list.length; i += 1) { var chk = list[i]; mode = chk.test.apply(chk, args); if (mode) { break; } } } if (input.format[mode]) { var rgb = input.format[mode].apply(null, autodetect ? args : args.slice(0,-1)); me._rgb = clip_rgb$1(rgb); } else { throw new Error('unknown format: '+args); } // add alpha channel if (me._rgb.length === 3) { me._rgb.push(1); } }; Color.prototype.toString = function toString () { if (type$1(this.hex) == 'function') { return this.hex(); } return ("[" + (this._rgb.join(',')) + "]"); }; var Color_1 = Color; var chroma = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( chroma.Color, [ null ].concat( args) )); }; chroma.Color = Color_1; chroma.version = '2.0.6'; var chroma_1 = chroma; var unpack$1 = utils.unpack; var max = Math.max; var rgb2cmyk = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var ref = unpack$1(args, 'rgb'); var r = ref[0]; var g = ref[1]; var b = ref[2]; r = r / 255; g = g / 255; b = b / 255; var k = 1 - max(r,max(g,b)); var f = k < 1 ? 1 / (1-k) : 0; var c = (1-r-k) * f; var m = (1-g-k) * f; var y = (1-b-k) * f; return [c,m,y,k]; }; var rgb2cmyk_1 = rgb2cmyk; var unpack$2 = utils.unpack; var cmyk2rgb = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$2(args, 'cmyk'); var c = args[0]; var m = args[1]; var y = args[2]; var k = args[3]; var alpha = args.length > 4 ? args[4] : 1; if (k === 1) { return [0,0,0,alpha]; } return [ c >= 1 ? 0 : 255 * (1-c) * (1-k), // r m >= 1 ? 0 : 255 * (1-m) * (1-k), // g y >= 1 ? 0 : 255 * (1-y) * (1-k), // b alpha ]; }; var cmyk2rgb_1 = cmyk2rgb; var unpack$3 = utils.unpack; var type$2 = utils.type; Color_1.prototype.cmyk = function() { return rgb2cmyk_1(this._rgb); }; chroma_1.cmyk = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['cmyk']) )); }; input.format.cmyk = cmyk2rgb_1; input.autodetect.push({ p: 2, test: function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$3(args, 'cmyk'); if (type$2(args) === 'array' && args.length === 4) { return 'cmyk'; } } }); var unpack$4 = utils.unpack; var last$2 = utils.last; var rnd = function (a) { return Math.round(a*100)/100; }; /* * supported arguments: * - hsl2css(h,s,l) * - hsl2css(h,s,l,a) * - hsl2css([h,s,l], mode) * - hsl2css([h,s,l,a], mode) * - hsl2css({h,s,l,a}, mode) */ var hsl2css = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var hsla = unpack$4(args, 'hsla'); var mode = last$2(args) || 'lsa'; hsla[0] = rnd(hsla[0] || 0); hsla[1] = rnd(hsla[1]*100) + '%'; hsla[2] = rnd(hsla[2]*100) + '%'; if (mode === 'hsla' || (hsla.length > 3 && hsla[3]<1)) { hsla[3] = hsla.length > 3 ? hsla[3] : 1; mode = 'hsla'; } else { hsla.length = 3; } return (mode + "(" + (hsla.join(',')) + ")"); }; var hsl2css_1 = hsl2css; var unpack$5 = utils.unpack; /* * supported arguments: * - rgb2hsl(r,g,b) * - rgb2hsl(r,g,b,a) * - rgb2hsl([r,g,b]) * - rgb2hsl([r,g,b,a]) * - rgb2hsl({r,g,b,a}) */ var rgb2hsl = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$5(args, 'rgba'); var r = args[0]; var g = args[1]; var b = args[2]; r /= 255; g /= 255; b /= 255; var min = Math.min(r, g, b); var max = Math.max(r, g, b); var l = (max + min) / 2; var s, h; if (max === min){ s = 0; h = Number.NaN; } else { s = l < 0.5 ? (max - min) / (max + min) : (max - min) / (2 - max - min); } if (r == max) { h = (g - b) / (max - min); } else if (g == max) { h = 2 + (b - r) / (max - min); } else if (b == max) { h = 4 + (r - g) / (max - min); } h *= 60; if (h < 0) { h += 360; } if (args.length>3 && args[3]!==undefined) { return [h,s,l,args[3]]; } return [h,s,l]; }; var rgb2hsl_1 = rgb2hsl; var unpack$6 = utils.unpack; var last$3 = utils.last; var round = Math.round; /* * supported arguments: * - rgb2css(r,g,b) * - rgb2css(r,g,b,a) * - rgb2css([r,g,b], mode) * - rgb2css([r,g,b,a], mode) * - rgb2css({r,g,b,a}, mode) */ var rgb2css = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var rgba = unpack$6(args, 'rgba'); var mode = last$3(args) || 'rgb'; if (mode.substr(0,3) == 'hsl') { return hsl2css_1(rgb2hsl_1(rgba), mode); } rgba[0] = round(rgba[0]); rgba[1] = round(rgba[1]); rgba[2] = round(rgba[2]); if (mode === 'rgba' || (rgba.length > 3 && rgba[3]<1)) { rgba[3] = rgba.length > 3 ? rgba[3] : 1; mode = 'rgba'; } return (mode + "(" + (rgba.slice(0,mode==='rgb'?3:4).join(',')) + ")"); }; var rgb2css_1 = rgb2css; var unpack$7 = utils.unpack; var round$1 = Math.round; var hsl2rgb = function () { var assign; var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$7(args, 'hsl'); var h = args[0]; var s = args[1]; var l = args[2]; var r,g,b; if (s === 0) { r = g = b = l*255; } else { var t3 = [0,0,0]; var c = [0,0,0]; var t2 = l < 0.5 ? l * (1+s) : l+s-l*s; var t1 = 2 * l - t2; var h_ = h / 360; t3[0] = h_ + 1/3; t3[1] = h_; t3[2] = h_ - 1/3; for (var i=0; i<3; i++) { if (t3[i] < 0) { t3[i] += 1; } if (t3[i] > 1) { t3[i] -= 1; } if (6 * t3[i] < 1) { c[i] = t1 + (t2 - t1) * 6 * t3[i]; } else if (2 * t3[i] < 1) { c[i] = t2; } else if (3 * t3[i] < 2) { c[i] = t1 + (t2 - t1) * ((2 / 3) - t3[i]) * 6; } else { c[i] = t1; } } (assign = [round$1(c[0]*255),round$1(c[1]*255),round$1(c[2]*255)], r = assign[0], g = assign[1], b = assign[2]); } if (args.length > 3) { // keep alpha channel return [r,g,b,args[3]]; } return [r,g,b,1]; }; var hsl2rgb_1 = hsl2rgb; var RE_RGB = /^rgb\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*\)$/; var RE_RGBA = /^rgba\(\s*(-?\d+),\s*(-?\d+)\s*,\s*(-?\d+)\s*,\s*([01]|[01]?\.\d+)\)$/; var RE_RGB_PCT = /^rgb\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/; var RE_RGBA_PCT = /^rgba\(\s*(-?\d+(?:\.\d+)?)%,\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/; var RE_HSL = /^hsl\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*\)$/; var RE_HSLA = /^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/; var round$2 = Math.round; var css2rgb = function (css) { css = css.toLowerCase().trim(); var m; if (input.format.named) { try { return input.format.named(css); } catch (e) { // eslint-disable-next-line } } // rgb(250,20,0) if ((m = css.match(RE_RGB))) { var rgb = m.slice(1,4); for (var i=0; i<3; i++) { rgb[i] = +rgb[i]; } rgb[3] = 1; // default alpha return rgb; } // rgba(250,20,0,0.4) if ((m = css.match(RE_RGBA))) { var rgb$1 = m.slice(1,5); for (var i$1=0; i$1<4; i$1++) { rgb$1[i$1] = +rgb$1[i$1]; } return rgb$1; } // rgb(100%,0%,0%) if ((m = css.match(RE_RGB_PCT))) { var rgb$2 = m.slice(1,4); for (var i$2=0; i$2<3; i$2++) { rgb$2[i$2] = round$2(rgb$2[i$2] * 2.55); } rgb$2[3] = 1; // default alpha return rgb$2; } // rgba(100%,0%,0%,0.4) if ((m = css.match(RE_RGBA_PCT))) { var rgb$3 = m.slice(1,5); for (var i$3=0; i$3<3; i$3++) { rgb$3[i$3] = round$2(rgb$3[i$3] * 2.55); } rgb$3[3] = +rgb$3[3]; return rgb$3; } // hsl(0,100%,50%) if ((m = css.match(RE_HSL))) { var hsl = m.slice(1,4); hsl[1] *= 0.01; hsl[2] *= 0.01; var rgb$4 = hsl2rgb_1(hsl); rgb$4[3] = 1; return rgb$4; } // hsla(0,100%,50%,0.5) if ((m = css.match(RE_HSLA))) { var hsl$1 = m.slice(1,4); hsl$1[1] *= 0.01; hsl$1[2] *= 0.01; var rgb$5 = hsl2rgb_1(hsl$1); rgb$5[3] = +m[4]; // default alpha = 1 return rgb$5; } }; css2rgb.test = function (s) { return RE_RGB.test(s) || RE_RGBA.test(s) || RE_RGB_PCT.test(s) || RE_RGBA_PCT.test(s) || RE_HSL.test(s) || RE_HSLA.test(s); }; var css2rgb_1 = css2rgb; var type$3 = utils.type; Color_1.prototype.css = function(mode) { return rgb2css_1(this._rgb, mode); }; chroma_1.css = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['css']) )); }; input.format.css = css2rgb_1; input.autodetect.push({ p: 5, test: function (h) { var rest = [], len = arguments.length - 1; while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ]; if (!rest.length && type$3(h) === 'string' && css2rgb_1.test(h)) { return 'css'; } } }); var unpack$8 = utils.unpack; input.format.gl = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var rgb = unpack$8(args, 'rgba'); rgb[0] *= 255; rgb[1] *= 255; rgb[2] *= 255; return rgb; }; chroma_1.gl = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['gl']) )); }; Color_1.prototype.gl = function() { var rgb = this._rgb; return [rgb[0]/255, rgb[1]/255, rgb[2]/255, rgb[3]]; }; var unpack$9 = utils.unpack; var rgb2hcg = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var ref = unpack$9(args, 'rgb'); var r = ref[0]; var g = ref[1]; var b = ref[2]; var min = Math.min(r, g, b); var max = Math.max(r, g, b); var delta = max - min; var c = delta * 100 / 255; var _g = min / (255 - delta) * 100; var h; if (delta === 0) { h = Number.NaN; } else { if (r === max) { h = (g - b) / delta; } if (g === max) { h = 2+(b - r) / delta; } if (b === max) { h = 4+(r - g) / delta; } h *= 60; if (h < 0) { h += 360; } } return [h, c, _g]; }; var rgb2hcg_1 = rgb2hcg; var unpack$a = utils.unpack; var floor = Math.floor; /* * this is basically just HSV with some minor tweaks * * hue.. [0..360] * chroma .. [0..1] * grayness .. [0..1] */ var hcg2rgb = function () { var assign, assign$1, assign$2, assign$3, assign$4, assign$5; var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$a(args, 'hcg'); var h = args[0]; var c = args[1]; var _g = args[2]; var r,g,b; _g = _g * 255; var _c = c * 255; if (c === 0) { r = g = b = _g; } else { if (h === 360) { h = 0; } if (h > 360) { h -= 360; } if (h < 0) { h += 360; } h /= 60; var i = floor(h); var f = h - i; var p = _g * (1 - c); var q = p + _c * (1 - f); var t = p + _c * f; var v = p + _c; switch (i) { case 0: (assign = [v, t, p], r = assign[0], g = assign[1], b = assign[2]); break case 1: (assign$1 = [q, v, p], r = assign$1[0], g = assign$1[1], b = assign$1[2]); break case 2: (assign$2 = [p, v, t], r = assign$2[0], g = assign$2[1], b = assign$2[2]); break case 3: (assign$3 = [p, q, v], r = assign$3[0], g = assign$3[1], b = assign$3[2]); break case 4: (assign$4 = [t, p, v], r = assign$4[0], g = assign$4[1], b = assign$4[2]); break case 5: (assign$5 = [v, p, q], r = assign$5[0], g = assign$5[1], b = assign$5[2]); break } } return [r, g, b, args.length > 3 ? args[3] : 1]; }; var hcg2rgb_1 = hcg2rgb; var unpack$b = utils.unpack; var type$4 = utils.type; Color_1.prototype.hcg = function() { return rgb2hcg_1(this._rgb); }; chroma_1.hcg = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hcg']) )); }; input.format.hcg = hcg2rgb_1; input.autodetect.push({ p: 1, test: function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$b(args, 'hcg'); if (type$4(args) === 'array' && args.length === 3) { return 'hcg'; } } }); var unpack$c = utils.unpack; var last$4 = utils.last; var round$3 = Math.round; var rgb2hex = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var ref = unpack$c(args, 'rgba'); var r = ref[0]; var g = ref[1]; var b = ref[2]; var a = ref[3]; var mode = last$4(args) || 'auto'; if (a === undefined) { a = 1; } if (mode === 'auto') { mode = a < 1 ? 'rgba' : 'rgb'; } r = round$3(r); g = round$3(g); b = round$3(b); var u = r << 16 | g << 8 | b; var str = "000000" + u.toString(16); //#.toUpperCase(); str = str.substr(str.length - 6); var hxa = '0' + round$3(a * 255).toString(16); hxa = hxa.substr(hxa.length - 2); switch (mode.toLowerCase()) { case 'rgba': return ("#" + str + hxa); case 'argb': return ("#" + hxa + str); default: return ("#" + str); } }; var rgb2hex_1 = rgb2hex; var RE_HEX = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; var RE_HEXA = /^#?([A-Fa-f0-9]{8})$/; var hex2rgb = function (hex) { if (hex.match(RE_HEX)) { // remove optional leading # if (hex.length === 4 || hex.length === 7) { hex = hex.substr(1); } // expand short-notation to full six-digit if (hex.length === 3) { hex = hex.split(''); hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2]; } var u = parseInt(hex, 16); var r = u >> 16; var g = u >> 8 & 0xFF; var b = u & 0xFF; return [r,g,b,1]; } // match rgba hex format, eg #FF000077 if (hex.match(RE_HEXA)) { if (hex.length === 9) { // remove optional leading # hex = hex.substr(1); } var u$1 = parseInt(hex, 16); var r$1 = u$1 >> 24 & 0xFF; var g$1 = u$1 >> 16 & 0xFF; var b$1 = u$1 >> 8 & 0xFF; var a = Math.round((u$1 & 0xFF) / 0xFF * 100) / 100; return [r$1,g$1,b$1,a]; } // we used to check for css colors here // if _input.css? and rgb = _input.css hex // return rgb throw new Error(("unknown hex color: " + hex)); }; var hex2rgb_1 = hex2rgb; var type$5 = utils.type; Color_1.prototype.hex = function(mode) { return rgb2hex_1(this._rgb, mode); }; chroma_1.hex = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hex']) )); }; input.format.hex = hex2rgb_1; input.autodetect.push({ p: 4, test: function (h) { var rest = [], len = arguments.length - 1; while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ]; if (!rest.length && type$5(h) === 'string' && [3,4,6,7,8,9].includes(h.length)) { return 'hex'; } } }); var unpack$d = utils.unpack; var TWOPI = utils.TWOPI; var min = Math.min; var sqrt = Math.sqrt; var acos = Math.acos; var rgb2hsi = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; /* borrowed from here: http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/rgb2hsi.cpp */ var ref = unpack$d(args, 'rgb'); var r = ref[0]; var g = ref[1]; var b = ref[2]; r /= 255; g /= 255; b /= 255; var h; var min_ = min(r,g,b); var i = (r+g+b) / 3; var s = i > 0 ? 1 - min_/i : 0; if (s === 0) { h = NaN; } else { h = ((r-g)+(r-b)) / 2; h /= sqrt((r-g)*(r-g) + (r-b)*(g-b)); h = acos(h); if (b > g) { h = TWOPI - h; } h /= TWOPI; } return [h*360,s,i]; }; var rgb2hsi_1 = rgb2hsi; var unpack$e = utils.unpack; var limit$1 = utils.limit; var TWOPI$1 = utils.TWOPI; var PITHIRD = utils.PITHIRD; var cos = Math.cos; /* * hue [0..360] * saturation [0..1] * intensity [0..1] */ var hsi2rgb = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; /* borrowed from here: http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/hsi2rgb.cpp */ args = unpack$e(args, 'hsi'); var h = args[0]; var s = args[1]; var i = args[2]; var r,g,b; if (isNaN(h)) { h = 0; } if (isNaN(s)) { s = 0; } // normalize hue if (h > 360) { h -= 360; } if (h < 0) { h += 360; } h /= 360; if (h < 1/3) { b = (1-s)/3; r = (1+s*cos(TWOPI$1*h)/cos(PITHIRD-TWOPI$1*h))/3; g = 1 - (b+r); } else if (h < 2/3) { h -= 1/3; r = (1-s)/3; g = (1+s*cos(TWOPI$1*h)/cos(PITHIRD-TWOPI$1*h))/3; b = 1 - (r+g); } else { h -= 2/3; g = (1-s)/3; b = (1+s*cos(TWOPI$1*h)/cos(PITHIRD-TWOPI$1*h))/3; r = 1 - (g+b); } r = limit$1(i*r*3); g = limit$1(i*g*3); b = limit$1(i*b*3); return [r*255, g*255, b*255, args.length > 3 ? args[3] : 1]; }; var hsi2rgb_1 = hsi2rgb; var unpack$f = utils.unpack; var type$6 = utils.type; Color_1.prototype.hsi = function() { return rgb2hsi_1(this._rgb); }; chroma_1.hsi = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hsi']) )); }; input.format.hsi = hsi2rgb_1; input.autodetect.push({ p: 2, test: function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$f(args, 'hsi'); if (type$6(args) === 'array' && args.length === 3) { return 'hsi'; } } }); var unpack$g = utils.unpack; var type$7 = utils.type; Color_1.prototype.hsl = function() { return rgb2hsl_1(this._rgb); }; chroma_1.hsl = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hsl']) )); }; input.format.hsl = hsl2rgb_1; input.autodetect.push({ p: 2, test: function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$g(args, 'hsl'); if (type$7(args) === 'array' && args.length === 3) { return 'hsl'; } } }); var unpack$h = utils.unpack; var min$1 = Math.min; var max$1 = Math.max; /* * supported arguments: * - rgb2hsv(r,g,b) * - rgb2hsv([r,g,b]) * - rgb2hsv({r,g,b}) */ var rgb2hsl$1 = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$h(args, 'rgb'); var r = args[0]; var g = args[1]; var b = args[2]; var min_ = min$1(r, g, b); var max_ = max$1(r, g, b); var delta = max_ - min_; var h,s,v; v = max_ / 255.0; if (max_ === 0) { h = Number.NaN; s = 0; } else { s = delta / max_; if (r === max_) { h = (g - b) / delta; } if (g === max_) { h = 2+(b - r) / delta; } if (b === max_) { h = 4+(r - g) / delta; } h *= 60; if (h < 0) { h += 360; } } return [h, s, v] }; var rgb2hsv = rgb2hsl$1; var unpack$i = utils.unpack; var floor$1 = Math.floor; var hsv2rgb = function () { var assign, assign$1, assign$2, assign$3, assign$4, assign$5; var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$i(args, 'hsv'); var h = args[0]; var s = args[1]; var v = args[2]; var r,g,b; v *= 255; if (s === 0) { r = g = b = v; } else { if (h === 360) { h = 0; } if (h > 360) { h -= 360; } if (h < 0) { h += 360; } h /= 60; var i = floor$1(h); var f = h - i; var p = v * (1 - s); var q = v * (1 - s * f); var t = v * (1 - s * (1 - f)); switch (i) { case 0: (assign = [v, t, p], r = assign[0], g = assign[1], b = assign[2]); break case 1: (assign$1 = [q, v, p], r = assign$1[0], g = assign$1[1], b = assign$1[2]); break case 2: (assign$2 = [p, v, t], r = assign$2[0], g = assign$2[1], b = assign$2[2]); break case 3: (assign$3 = [p, q, v], r = assign$3[0], g = assign$3[1], b = assign$3[2]); break case 4: (assign$4 = [t, p, v], r = assign$4[0], g = assign$4[1], b = assign$4[2]); break case 5: (assign$5 = [v, p, q], r = assign$5[0], g = assign$5[1], b = assign$5[2]); break } } return [r,g,b,args.length > 3?args[3]:1]; }; var hsv2rgb_1 = hsv2rgb; var unpack$j = utils.unpack; var type$8 = utils.type; Color_1.prototype.hsv = function() { return rgb2hsv(this._rgb); }; chroma_1.hsv = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hsv']) )); }; input.format.hsv = hsv2rgb_1; input.autodetect.push({ p: 2, test: function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$j(args, 'hsv'); if (type$8(args) === 'array' && args.length === 3) { return 'hsv'; } } }); var labConstants = { // Corresponds roughly to RGB brighter/darker Kn: 18, // D65 standard referent Xn: 0.950470, Yn: 1, Zn: 1.088830, t0: 0.137931034, // 4 / 29 t1: 0.206896552, // 6 / 29 t2: 0.12841855, // 3 * t1 * t1 t3: 0.008856452, // t1 * t1 * t1 }; var unpack$k = utils.unpack; var pow = Math.pow; var rgb2lab = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var ref = unpack$k(args, 'rgb'); var r = ref[0]; var g = ref[1]; var b = ref[2]; var ref$1 = rgb2xyz(r,g,b); var x = ref$1[0]; var y = ref$1[1]; var z = ref$1[2]; var l = 116 * y - 16; return [l < 0 ? 0 : l, 500 * (x - y), 200 * (y - z)]; }; var rgb_xyz = function (r) { if ((r /= 255) <= 0.04045) { return r / 12.92; } return pow((r + 0.055) / 1.055, 2.4); }; var xyz_lab = function (t) { if (t > labConstants.t3) { return pow(t, 1 / 3); } return t / labConstants.t2 + labConstants.t0; }; var rgb2xyz = function (r,g,b) { r = rgb_xyz(r); g = rgb_xyz(g); b = rgb_xyz(b); var x = xyz_lab((0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / labConstants.Xn); var y = xyz_lab((0.2126729 * r + 0.7151522 * g + 0.0721750 * b) / labConstants.Yn); var z = xyz_lab((0.0193339 * r + 0.1191920 * g + 0.9503041 * b) / labConstants.Zn); return [x,y,z]; }; var rgb2lab_1 = rgb2lab; var unpack$l = utils.unpack; var pow$1 = Math.pow; /* * L* [0..100] * a [-100..100] * b [-100..100] */ var lab2rgb = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$l(args, 'lab'); var l = args[0]; var a = args[1]; var b = args[2]; var x,y,z, r,g,b_; y = (l + 16) / 116; x = isNaN(a) ? y : y + a / 500; z = isNaN(b) ? y : y - b / 200; y = labConstants.Yn * lab_xyz(y); x = labConstants.Xn * lab_xyz(x); z = labConstants.Zn * lab_xyz(z); r = xyz_rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z); // D65 -> sRGB g = xyz_rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z); b_ = xyz_rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z); return [r,g,b_,args.length > 3 ? args[3] : 1]; }; var xyz_rgb = function (r) { return 255 * (r <= 0.00304 ? 12.92 * r : 1.055 * pow$1(r, 1 / 2.4) - 0.055) }; var lab_xyz = function (t) { return t > labConstants.t1 ? t * t * t : labConstants.t2 * (t - labConstants.t0) }; var lab2rgb_1 = lab2rgb; var unpack$m = utils.unpack; var type$9 = utils.type; Color_1.prototype.lab = function() { return rgb2lab_1(this._rgb); }; chroma_1.lab = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['lab']) )); }; input.format.lab = lab2rgb_1; input.autodetect.push({ p: 2, test: function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$m(args, 'lab'); if (type$9(args) === 'array' && args.length === 3) { return 'lab'; } } }); var unpack$n = utils.unpack; var RAD2DEG = utils.RAD2DEG; var sqrt$1 = Math.sqrt; var atan2 = Math.atan2; var round$4 = Math.round; var lab2lch = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var ref = unpack$n(args, 'lab'); var l = ref[0]; var a = ref[1]; var b = ref[2]; var c = sqrt$1(a * a + b * b); var h = (atan2(b, a) * RAD2DEG + 360) % 360; if (round$4(c*10000) === 0) { h = Number.NaN; } return [l, c, h]; }; var lab2lch_1 = lab2lch; var unpack$o = utils.unpack; var rgb2lch = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var ref = unpack$o(args, 'rgb'); var r = ref[0]; var g = ref[1]; var b = ref[2]; var ref$1 = rgb2lab_1(r,g,b); var l = ref$1[0]; var a = ref$1[1]; var b_ = ref$1[2]; return lab2lch_1(l,a,b_); }; var rgb2lch_1 = rgb2lch; var unpack$p = utils.unpack; var DEG2RAD = utils.DEG2RAD; var sin = Math.sin; var cos$1 = Math.cos; var lch2lab = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; /* Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel. These formulas were invented by David Dalrymple to obtain maximum contrast without going out of gamut if the parameters are in the range 0-1. A saturation multiplier was added by Gregor Aisch */ var ref = unpack$p(args, 'lch'); var l = ref[0]; var c = ref[1]; var h = ref[2]; if (isNaN(h)) { h = 0; } h = h * DEG2RAD; return [l, cos$1(h) * c, sin(h) * c] }; var lch2lab_1 = lch2lab; var unpack$q = utils.unpack; var lch2rgb = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$q(args, 'lch'); var l = args[0]; var c = args[1]; var h = args[2]; var ref = lch2lab_1 (l,c,h); var L = ref[0]; var a = ref[1]; var b_ = ref[2]; var ref$1 = lab2rgb_1 (L,a,b_); var r = ref$1[0]; var g = ref$1[1]; var b = ref$1[2]; return [r, g, b, args.length > 3 ? args[3] : 1]; }; var lch2rgb_1 = lch2rgb; var unpack$r = utils.unpack; var hcl2rgb = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var hcl = unpack$r(args, 'hcl').reverse(); return lch2rgb_1.apply(void 0, hcl); }; var hcl2rgb_1 = hcl2rgb; var unpack$s = utils.unpack; var type$a = utils.type; Color_1.prototype.lch = function() { return rgb2lch_1(this._rgb); }; Color_1.prototype.hcl = function() { return rgb2lch_1(this._rgb).reverse(); }; chroma_1.lch = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['lch']) )); }; chroma_1.hcl = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['hcl']) )); }; input.format.lch = lch2rgb_1; input.format.hcl = hcl2rgb_1; ['lch','hcl'].forEach(function (m) { return input.autodetect.push({ p: 2, test: function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$s(args, m); if (type$a(args) === 'array' && args.length === 3) { return m; } } }); }); /** X11 color names http://www.w3.org/TR/css3-color/#svg-color */ var w3cx11 = { aliceblue: '#f0f8ff', antiquewhite: '#faebd7', aqua: '#00ffff', aquamarine: '#7fffd4', azure: '#f0ffff', beige: '#f5f5dc', bisque: '#ffe4c4', black: '#000000', blanchedalmond: '#ffebcd', blue: '#0000ff', blueviolet: '#8a2be2', brown: '#a52a2a', burlywood: '#deb887', cadetblue: '#5f9ea0', chartreuse: '#7fff00', chocolate: '#d2691e', coral: '#ff7f50', cornflower: '#6495ed', cornflowerblue: '#6495ed', cornsilk: '#fff8dc', crimson: '#dc143c', cyan: '#00ffff', darkblue: '#00008b', darkcyan: '#008b8b', darkgoldenrod: '#b8860b', darkgray: '#a9a9a9', darkgreen: '#006400', darkgrey: '#a9a9a9', darkkhaki: '#bdb76b', darkmagenta: '#8b008b', darkolivegreen: '#556b2f', darkorange: '#ff8c00', darkorchid: '#9932cc', darkred: '#8b0000', darksalmon: '#e9967a', darkseagreen: '#8fbc8f', darkslateblue: '#483d8b', darkslategray: '#2f4f4f', darkslategrey: '#2f4f4f', darkturquoise: '#00ced1', darkviolet: '#9400d3', deeppink: '#ff1493', deepskyblue: '#00bfff', dimgray: '#696969', dimgrey: '#696969', dodgerblue: '#1e90ff', firebrick: '#b22222', floralwhite: '#fffaf0', forestgreen: '#228b22', fuchsia: '#ff00ff', gainsboro: '#dcdcdc', ghostwhite: '#f8f8ff', gold: '#ffd700', goldenrod: '#daa520', gray: '#808080', green: '#008000', greenyellow: '#adff2f', grey: '#808080', honeydew: '#f0fff0', hotpink: '#ff69b4', indianred: '#cd5c5c', indigo: '#4b0082', ivory: '#fffff0', khaki: '#f0e68c', laserlemon: '#ffff54', lavender: '#e6e6fa', lavenderblush: '#fff0f5', lawngreen: '#7cfc00', lemonchiffon: '#fffacd', lightblue: '#add8e6', lightcoral: '#f08080', lightcyan: '#e0ffff', lightgoldenrod: '#fafad2', lightgoldenrodyellow: '#fafad2', lightgray: '#d3d3d3', lightgreen: '#90ee90', lightgrey: '#d3d3d3', lightpink: '#ffb6c1', lightsalmon: '#ffa07a', lightseagreen: '#20b2aa', lightskyblue: '#87cefa', lightslategray: '#778899', lightslategrey: '#778899', lightsteelblue: '#b0c4de', lightyellow: '#ffffe0', lime: '#00ff00', limegreen: '#32cd32', linen: '#faf0e6', magenta: '#ff00ff', maroon: '#800000', maroon2: '#7f0000', maroon3: '#b03060', mediumaquamarine: '#66cdaa', mediumblue: '#0000cd', mediumorchid: '#ba55d3', mediumpurple: '#9370db', mediumseagreen: '#3cb371', mediumslateblue: '#7b68ee', mediumspringgreen: '#00fa9a', mediumturquoise: '#48d1cc', mediumvioletred: '#c71585', midnightblue: '#191970', mintcream: '#f5fffa', mistyrose: '#ffe4e1', moccasin: '#ffe4b5', navajowhite: '#ffdead', navy: '#000080', oldlace: '#fdf5e6', olive: '#808000', olivedrab: '#6b8e23', orange: '#ffa500', orangered: '#ff4500', orchid: '#da70d6', palegoldenrod: '#eee8aa', palegreen: '#98fb98', paleturquoise: '#afeeee', palevioletred: '#db7093', papayawhip: '#ffefd5', peachpuff: '#ffdab9', peru: '#cd853f', pink: '#ffc0cb', plum: '#dda0dd', powderblue: '#b0e0e6', purple: '#800080', purple2: '#7f007f', purple3: '#a020f0', rebeccapurple: '#663399', red: '#ff0000', rosybrown: '#bc8f8f', royalblue: '#4169e1', saddlebrown: '#8b4513', salmon: '#fa8072', sandybrown: '#f4a460', seagreen: '#2e8b57', seashell: '#fff5ee', sienna: '#a0522d', silver: '#c0c0c0', skyblue: '#87ceeb', slateblue: '#6a5acd', slategray: '#708090', slategrey: '#708090', snow: '#fffafa', springgreen: '#00ff7f', steelblue: '#4682b4', tan: '#d2b48c', teal: '#008080', thistle: '#d8bfd8', tomato: '#ff6347', turquoise: '#40e0d0', violet: '#ee82ee', wheat: '#f5deb3', white: '#ffffff', whitesmoke: '#f5f5f5', yellow: '#ffff00', yellowgreen: '#9acd32' }; var w3cx11_1 = w3cx11; var type$b = utils.type; Color_1.prototype.name = function() { var hex = rgb2hex_1(this._rgb, 'rgb'); for (var i = 0, list = Object.keys(w3cx11_1); i < list.length; i += 1) { var n = list[i]; if (w3cx11_1[n] === hex) { return n.toLowerCase(); } } return hex; }; input.format.named = function (name) { name = name.toLowerCase(); if (w3cx11_1[name]) { return hex2rgb_1(w3cx11_1[name]); } throw new Error('unknown color name: '+name); }; input.autodetect.push({ p: 5, test: function (h) { var rest = [], len = arguments.length - 1; while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ]; if (!rest.length && type$b(h) === 'string' && w3cx11_1[h.toLowerCase()]) { return 'named'; } } }); var unpack$t = utils.unpack; var rgb2num = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var ref = unpack$t(args, 'rgb'); var r = ref[0]; var g = ref[1]; var b = ref[2]; return (r << 16) + (g << 8) + b; }; var rgb2num_1 = rgb2num; var type$c = utils.type; var num2rgb = function (num) { if (type$c(num) == "number" && num >= 0 && num <= 0xFFFFFF) { var r = num >> 16; var g = (num >> 8) & 0xFF; var b = num & 0xFF; return [r,g,b,1]; } throw new Error("unknown num color: "+num); }; var num2rgb_1 = num2rgb; var type$d = utils.type; Color_1.prototype.num = function() { return rgb2num_1(this._rgb); }; chroma_1.num = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['num']) )); }; input.format.num = num2rgb_1; input.autodetect.push({ p: 5, test: function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; if (args.length === 1 && type$d(args[0]) === 'number' && args[0] >= 0 && args[0] <= 0xFFFFFF) { return 'num'; } } }); var unpack$u = utils.unpack; var type$e = utils.type; var round$5 = Math.round; Color_1.prototype.rgb = function(rnd) { if ( rnd === void 0 ) rnd=true; if (rnd === false) { return this._rgb.slice(0,3); } return this._rgb.slice(0,3).map(round$5); }; Color_1.prototype.rgba = function(rnd) { if ( rnd === void 0 ) rnd=true; return this._rgb.slice(0,4).map(function (v,i) { return i<3 ? (rnd === false ? v : round$5(v)) : v; }); }; chroma_1.rgb = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; return new (Function.prototype.bind.apply( Color_1, [ null ].concat( args, ['rgb']) )); }; input.format.rgb = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var rgba = unpack$u(args, 'rgba'); if (rgba[3] === undefined) { rgba[3] = 1; } return rgba; }; input.autodetect.push({ p: 3, test: function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; args = unpack$u(args, 'rgba'); if (type$e(args) === 'array' && (args.length === 3 || args.length === 4 && type$e(args[3]) == 'number' && args[3] >= 0 && args[3] <= 1)) { return 'rgb'; } } }); /* * Based on implementation by Neil Bartlett * https://github.com/neilbartlett/color-temperature */ var log = Math.log; var temperature2rgb = function (kelvin) { var temp = kelvin / 100; var r,g,b; if (temp < 66) { r = 255; g = -155.25485562709179 - 0.44596950469579133 * (g = temp-2) + 104.49216199393888 * log(g); b = temp < 20 ? 0 : -254.76935184120902 + 0.8274096064007395 * (b = temp-10) + 115.67994401066147 * log(b); } else { r = 351.97690566805693 + 0.114206453784165 * (r = temp-55) - 40.25366309332127 * log(r); g = 325.4494125711974 + 0.07943456536662342 * (g = temp-50) - 28.0852963507957 * log(g); b = 255; } return [r,g,b,1]; }; var temperature2rgb_1 = temperature2rgb; /* * Based on implementation by Neil Bartlett * https://github.com/neilbartlett/color-temperature **/ var unpack$v = utils.unpack; var round$6 = Math.round; var rgb2temperature = function () { var args = [], len = arguments.length; while ( len-- ) args[ len ] = arguments[ len ]; var rgb = unpack$v(args, 'rgb'); var r = rgb[0], b = rgb[2]; var minTemp = 1000; var maxTemp = 40000; var eps = 0.4; var temp; while (maxTemp - minTemp > eps) { temp = (maxTemp + minTemp) * 0.5; var rgb$1 = temperature2rgb_1(temp); if ((rgb$1[2] / rgb$1[0]) >= (b / r)) { maxTemp = temp; } else { minTemp = temp; } } return round$6(temp); }; var rgb2temper