├── .babelrc ├── .codecov.yml ├── .gitattributes ├── .gitignore ├── .travis.yml ├── README.md ├── build ├── webpack.config.js ├── webpack.docs.config.js ├── webpack.docs.dist.config.js └── webpack.prod.config.js ├── docs ├── bundle.js ├── index.html ├── index.js └── index.vue ├── package.json └── src ├── components ├── ColorLocator2d │ ├── ColorLocator2d.vue │ ├── Locator2d.vue │ └── index.js ├── ColorSlider │ ├── Slider.vue │ └── index.js ├── NumberInput │ ├── NumberInput.vue │ └── index.js └── Picker │ ├── Picker.vue │ └── index.js ├── index.js └── utils ├── _test └── index.test.js ├── calcEventPosition.js ├── chroma.js ├── contains.js ├── getBackground2d.js ├── getTransparentBackground.js ├── hexToNumber.js ├── materialColors.js ├── numberTohex.js └── padStart.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-2"] 3 | } -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | branch: master -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | lib 4 | dist 5 | TODOs.md 6 | npm-debug.log 7 | 8 | 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | 5 | script: 6 | - npm run coverage -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Vue Color Picker 3 | 4 | [![NPM downloads](https://img.shields.io/npm/v/vue-color-picker.svg)](https://www.npmjs.com/package/vue-color-picker) 5 | [![NPM downloads](https://img.shields.io/npm/l/vue-color-picker.svg)](https://www.npmjs.com/package/vue-color-picker) 6 | 7 | 8 | ## Install 9 | 10 | ```js 11 | npm install vue-color-picker 12 | ``` 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /build/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack') 3 | 4 | module.exports = { 5 | entry: path.resolve(__dirname, '../example/index.js'), 6 | output: { 7 | path: path.resolve(__dirname, '../example/build'), 8 | //publicPath: 'http://127.0.0.1:8081/examples/build', 9 | filename: 'bundle.js' 10 | }, 11 | resolve: { 12 | extensions: ['.js', '.vue'] 13 | }, 14 | module: { 15 | loaders: [{ 16 | test: /\.js?$/, 17 | exclude: /node_modules/, 18 | loader: 'babel-loader', 19 | },{ 20 | test: /\.vue$/, 21 | loader: 'vue-loader' 22 | },{ 23 | test: /\.(png|jpg|gif)$/, 24 | loader: 'url-loader?limit=8192' 25 | },{ 26 | test: /\.css$/, 27 | loader: 'style-loader!css-loader' 28 | },{ 29 | test: /\.json$/, 30 | loader: 'json-loader' 31 | },{ 32 | test: /\.md$/, 33 | loader: 'raw-loader' 34 | }] 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /build/webpack.docs.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | var merge = require('webpack-merge') 4 | var config = require('./webpack.config.js') 5 | 6 | process.env.NODE_ENV = 'production' 7 | 8 | module.exports = merge(config, { 9 | entry: { 10 | main: './docs/index.js' 11 | }, 12 | output: { 13 | path: path.resolve(__dirname, '../docs'), 14 | publicPath: '/docs/', 15 | filename: 'bundle.js', 16 | } 17 | }) -------------------------------------------------------------------------------- /build/webpack.docs.dist.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | var merge = require('webpack-merge') 4 | var config = require('./webpack.docs.config.js') 5 | 6 | process.env.NODE_ENV = 'production' 7 | 8 | module.exports = merge(config, { 9 | plugins: [ 10 | new webpack.DefinePlugin({ 11 | 'process.env': { 12 | NODE_ENV: JSON.stringify('production') 13 | } 14 | }), 15 | new webpack.optimize.UglifyJsPlugin({ 16 | compress: { 17 | warnings: false 18 | } 19 | }) 20 | ] 21 | }) -------------------------------------------------------------------------------- /build/webpack.prod.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | var merge = require('webpack-merge') 4 | var config = require('./webpack.config.js') 5 | 6 | process.env.NODE_ENV = 'production' 7 | 8 | module.exports = merge(config, { 9 | entry: { 10 | main: './src/index.js' 11 | }, 12 | output: { 13 | path: path.resolve(__dirname, '../dist'), 14 | publicPath: '/dist/', 15 | filename: 'vueColorPicker.min.js', 16 | library: 'VueColorPicker', 17 | libraryTarget: 'umd' 18 | }, 19 | externals: { 20 | vue: { 21 | root: 'vue', 22 | commonjs: 'vue', 23 | commonjs2: 'vue', 24 | amd: 'vue' 25 | } 26 | }, 27 | plugins: [ 28 | new webpack.DefinePlugin({ 29 | 'process.env': { 30 | NODE_ENV: JSON.stringify('production') 31 | } 32 | }), 33 | new webpack.optimize.UglifyJsPlugin() 34 | ] 35 | }) -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Vue-colors 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Test from './index.vue' 3 | 4 | 5 | var vm = new Vue({ 6 | el: '#app', 7 | render: h => h(Test), 8 | }) -------------------------------------------------------------------------------- /docs/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | 19 | 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-color-picker", 3 | "version": "0.6.1", 4 | "title": "vue color picker", 5 | "description": "A responsive color picker with Vue.js", 6 | "homepage": "https://huangbuyi.github.io/vue-colors/", 7 | "keywords": [ 8 | "vue", 9 | "vue.js", 10 | "mobile", 11 | "color picker", 12 | "color", 13 | "responsive", 14 | "material", 15 | "multi-model", 16 | "palette" 17 | ], 18 | "main": "dist/vueColorPicker.min.js", 19 | "files": [ 20 | "dist", 21 | "lib" 22 | ], 23 | "scripts": { 24 | "dist": "webpack --config build/webpack.prod.config", 25 | "docs": "webpack-dev-server --config build/webpack.docs.config --inline ", 26 | "docs:dist": "webpack --config build/webpack.docs.dist.config" 27 | }, 28 | "author": "Shibin Huang", 29 | "license": "MIT", 30 | "devDependencies": { 31 | "babel-cli": "^6.24.0", 32 | "babel-core": "^6.18.2", 33 | "babel-loader": "^6.2.8", 34 | "babel-plugin-transform-decorators-legacy": "^1.3.4", 35 | "babel-preset-es2015": "^6.18.0", 36 | "babel-preset-stage-2": "^6.18.0", 37 | "codecov": "^2.1.0", 38 | "css-loader": "^0.28.0", 39 | "eslint": "^3.13.1", 40 | "eslint-plugin-babel": "^4.0.0", 41 | "file-loader": "^0.9.0", 42 | "less": "^2.7.2", 43 | "less-loader": "^4.0.3", 44 | "style-loader": "^0.13.1", 45 | "url-loader": "^0.5.7", 46 | "vue": "^2.2.6", 47 | "vue-loader": "^11.3.4", 48 | "vue-template-compiler": "^2.2.6", 49 | "webpack": "^2.2.1", 50 | "webpack-dev-server": "^2.4.1", 51 | "webpack-merge": "^4.1.0" 52 | }, 53 | "peerDependencies": { 54 | "vue": "^2.2.6" 55 | }, 56 | "dependencies": { 57 | "chroma-js": "^1.3.3", 58 | "lodash": "^4.17.4" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/components/ColorLocator2d/ColorLocator2d.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 114 | -------------------------------------------------------------------------------- /src/components/ColorLocator2d/Locator2d.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 94 | 95 | -------------------------------------------------------------------------------- /src/components/ColorLocator2d/index.js: -------------------------------------------------------------------------------- 1 | export {default} from './ColorLocator2d' -------------------------------------------------------------------------------- /src/components/ColorSlider/Slider.vue: -------------------------------------------------------------------------------- 1 | 27 | 28 | 114 | 115 | -------------------------------------------------------------------------------- /src/components/ColorSlider/index.js: -------------------------------------------------------------------------------- 1 | export {default} from './Slider' -------------------------------------------------------------------------------- /src/components/NumberInput/NumberInput.vue: -------------------------------------------------------------------------------- 1 | 35 | 36 | 227 | 228 | -------------------------------------------------------------------------------- /src/components/NumberInput/index.js: -------------------------------------------------------------------------------- 1 | export {default} from './NumberInput.vue' 2 | 3 | -------------------------------------------------------------------------------- /src/components/Picker/Picker.vue: -------------------------------------------------------------------------------- 1 | 102 | 103 | 284 | 285 | -------------------------------------------------------------------------------- /src/components/Picker/index.js: -------------------------------------------------------------------------------- 1 | export {default} from './Picker' -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export {default} from './components/Picker' -------------------------------------------------------------------------------- /src/utils/_test/index.test.js: -------------------------------------------------------------------------------- 1 | import calcEventPosition from '../calcEventPosition' 2 | 3 | function mockEventPosition(pageX, pageY) { 4 | return { pageX, pageY } 5 | } 6 | 7 | function mockContainer(left, top, clientWidth, clientHeight) { 8 | return { 9 | clientWidth, 10 | clientHeight, 11 | getBoundingClientRect: function () { 12 | return { left, top } 13 | } 14 | } 15 | } 16 | 17 | 18 | describe('test calcEventPosition', () => { 19 | it('valid inside container', () => { 20 | const e = mockEventPosition(150,150) 21 | const cont = mockContainer(100,100,100,100) 22 | expect(calcEventPosition(e, cont)).toEqual({ 23 | leftP:0.5, 24 | topP:0.5 25 | }) 26 | }) 27 | 28 | it('zero on corner', () => { 29 | const e = mockEventPosition(100,100) 30 | const cont = mockContainer(100,100,100,100) 31 | expect(calcEventPosition(e, cont)).toEqual({ 32 | leftP:0, 33 | topP:0 34 | }) 35 | }) 36 | 37 | it('zero on left-top outside', () => { 38 | const e = mockEventPosition(0,0) 39 | const cont = mockContainer(100,100,100,100) 40 | expect(calcEventPosition(e, cont)).toEqual({ 41 | leftP:0, 42 | topP:0 43 | }) 44 | }) 45 | 46 | it('1,1 on right-bottom outside', () => { 47 | const e = mockEventPosition(500,500) 48 | const cont = mockContainer(100,100,100,100) 49 | expect(calcEventPosition(e, cont)).toEqual({ 50 | leftP:1, 51 | topP:1 52 | }) 53 | }) 54 | 55 | }) -------------------------------------------------------------------------------- /src/utils/calcEventPosition.js: -------------------------------------------------------------------------------- 1 | export default function calcEventPosition(e, container) { 2 | const containerWidth = container.clientWidth 3 | const containerHeight = container.clientHeight 4 | const x = typeof e.pageX === 'number' ? e.pageX : e.touches[0].pageX 5 | const y = typeof e.pageY === 'number' ? e.pageY : e.touches[0].pageY 6 | let left = x - (container.getBoundingClientRect().left + window.pageXOffset) 7 | let top = y - (container.getBoundingClientRect().top + window.pageYOffset) 8 | 9 | left = left < 0 ? 0 : left 10 | left = left > containerWidth ? containerWidth : left 11 | top = top < 0 ? 0 : top 12 | top = top > containerHeight ? containerHeight : top 13 | 14 | return { 15 | leftP: left / containerWidth, 16 | topP: top / containerHeight 17 | } 18 | }`` -------------------------------------------------------------------------------- /src/utils/chroma.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @license 4 | * 5 | * chroma.js - JavaScript library for color conversions 6 | * 7 | * Copyright (c) 2011-2015, Gregor Aisch 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright notice, this 14 | * list of conditions and the following disclaimer. 15 | * 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 20 | * 3. The name Gregor Aisch may not be used to endorse or promote products 21 | * derived from this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | * DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 30 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 32 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | */ 35 | 36 | (function() { 37 | var Color, DEG2RAD, LAB_CONSTANTS, PI, PITHIRD, RAD2DEG, TWOPI, _guess_formats, _guess_formats_sorted, _input, _interpolators, abs, atan2, bezier, blend, blend_f, brewer, burn, chroma, clip_rgb, cmyk2rgb, colors, cos, css2rgb, darken, dodge, each, floor, hex2rgb, hsi2rgb, hsl2css, hsl2rgb, hsv2rgb, interpolate, interpolate_hsx, interpolate_lab, interpolate_num, interpolate_rgb, lab2lch, lab2rgb, lab_xyz, lch2lab, lch2rgb, lighten, limit, log, luminance_x, m, max, multiply, normal, num2rgb, overlay, pow, rgb2cmyk, rgb2css, rgb2hex, rgb2hsi, rgb2hsl, rgb2hsv, rgb2lab, rgb2lch, rgb2luminance, rgb2num, rgb2temperature, rgb2xyz, rgb_xyz, rnd, root, round, screen, sin, sqrt, temperature2rgb, type, unpack, w3cx11, xyz_lab, xyz_rgb, 38 | slice = [].slice; 39 | 40 | type = (function() { 41 | 42 | /* 43 | for browser-safe type checking+ 44 | ported from jQuery's $.type 45 | */ 46 | var classToType, len, name, o, ref; 47 | classToType = {}; 48 | ref = "Boolean Number String Function Array Date RegExp Undefined Null".split(" "); 49 | for (o = 0, len = ref.length; o < len; o++) { 50 | name = ref[o]; 51 | classToType["[object " + name + "]"] = name.toLowerCase(); 52 | } 53 | return function(obj) { 54 | var strType; 55 | strType = Object.prototype.toString.call(obj); 56 | return classToType[strType] || "object"; 57 | }; 58 | })(); 59 | 60 | limit = function(x, min, max) { 61 | if (min == null) { 62 | min = 0; 63 | } 64 | if (max == null) { 65 | max = 1; 66 | } 67 | if (x < min) { 68 | x = min; 69 | } 70 | if (x > max) { 71 | x = max; 72 | } 73 | return x; 74 | }; 75 | 76 | unpack = function(args) { 77 | if (args.length >= 3) { 78 | return [].slice.call(args); 79 | } else { 80 | return args[0]; 81 | } 82 | }; 83 | 84 | clip_rgb = function(rgb) { 85 | var i; 86 | for (i in rgb) { 87 | if (i < 3) { 88 | if (rgb[i] < 0) { 89 | rgb[i] = 0; 90 | } 91 | if (rgb[i] > 255) { 92 | rgb[i] = 255; 93 | } 94 | } else if (i === 3) { 95 | if (rgb[i] < 0) { 96 | rgb[i] = 0; 97 | } 98 | if (rgb[i] > 1) { 99 | rgb[i] = 1; 100 | } 101 | } 102 | } 103 | return rgb; 104 | }; 105 | 106 | PI = Math.PI, round = a => a, cos = Math.cos, floor = Math.floor, pow = Math.pow, log = Math.log, sin = Math.sin, sqrt = Math.sqrt, atan2 = Math.atan2, max = Math.max, abs = Math.abs; 107 | 108 | TWOPI = PI * 2; 109 | 110 | PITHIRD = PI / 3; 111 | 112 | DEG2RAD = PI / 180; 113 | 114 | RAD2DEG = 180 / PI; 115 | 116 | chroma = function() { 117 | if (arguments[0] instanceof Color) { 118 | return arguments[0]; 119 | } 120 | return (function(func, args, ctor) { 121 | ctor.prototype = func.prototype; 122 | var child = new ctor, result = func.apply(child, args); 123 | return Object(result) === result ? result : child; 124 | })(Color, arguments, function(){}); 125 | }; 126 | 127 | _interpolators = []; 128 | 129 | if ((typeof module !== "undefined" && module !== null) && (module.exports != null)) { 130 | module.exports = chroma; 131 | } 132 | 133 | if (typeof define === 'function' && define.amd) { 134 | define([], function() { 135 | return chroma; 136 | }); 137 | } else { 138 | root = typeof exports !== "undefined" && exports !== null ? exports : this; 139 | root.chroma = chroma; 140 | } 141 | 142 | chroma.version = '1.2.1'; 143 | 144 | 145 | /** 146 | chroma.js 147 | 148 | Copyright (c) 2011-2013, Gregor Aisch 149 | All rights reserved. 150 | 151 | Redistribution and use in source and binary forms, with or without 152 | modification, are permitted provided that the following conditions are met: 153 | 154 | * Redistributions of source code must retain the above copyright notice, this 155 | list of conditions and the following disclaimer. 156 | 157 | * Redistributions in binary form must reproduce the above copyright notice, 158 | this list of conditions and the following disclaimer in the documentation 159 | and/or other materials provided with the distribution. 160 | 161 | * The name Gregor Aisch may not be used to endorse or promote products 162 | derived from this software without specific prior written permission. 163 | 164 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 165 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 166 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 167 | DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 168 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 169 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 170 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 171 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 172 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 173 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 174 | 175 | @source: https://github.com/gka/chroma.js 176 | */ 177 | 178 | _input = {}; 179 | 180 | _guess_formats = []; 181 | 182 | _guess_formats_sorted = false; 183 | 184 | Color = (function() { 185 | function Color() { 186 | var arg, args, chk, len, len1, me, mode, o, w; 187 | me = this; 188 | args = []; 189 | for (o = 0, len = arguments.length; o < len; o++) { 190 | arg = arguments[o]; 191 | if (arg != null) { 192 | args.push(arg); 193 | } 194 | } 195 | mode = args[args.length - 1]; 196 | if (_input[mode] != null) { 197 | me._rgb = clip_rgb(_input[mode](unpack(args.slice(0, -1)))); 198 | } else { 199 | if (!_guess_formats_sorted) { 200 | _guess_formats = _guess_formats.sort(function(a, b) { 201 | return b.p - a.p; 202 | }); 203 | _guess_formats_sorted = true; 204 | } 205 | for (w = 0, len1 = _guess_formats.length; w < len1; w++) { 206 | chk = _guess_formats[w]; 207 | mode = chk.test.apply(chk, args); 208 | if (mode) { 209 | break; 210 | } 211 | } 212 | if (mode) { 213 | me._rgb = clip_rgb(_input[mode].apply(_input, args)); 214 | } 215 | } 216 | if (me._rgb == null) { 217 | console.warn('unknown format: ' + args); 218 | } 219 | if (me._rgb == null) { 220 | me._rgb = [0, 0, 0]; 221 | } 222 | if (me._rgb.length === 3) { 223 | me._rgb.push(1); 224 | } 225 | } 226 | 227 | Color.prototype.alpha = function(alpha) { 228 | if (arguments.length) { 229 | this._rgb[3] = alpha; 230 | return this; 231 | } 232 | return this._rgb[3]; 233 | }; 234 | 235 | Color.prototype.toString = function() { 236 | return this.name(); 237 | }; 238 | 239 | return Color; 240 | 241 | })(); 242 | 243 | chroma._input = _input; 244 | 245 | 246 | /** 247 | ColorBrewer colors for chroma.js 248 | 249 | Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The 250 | Pennsylvania State University. 251 | 252 | Licensed under the Apache License, Version 2.0 (the "License"); 253 | you may not use this file except in compliance with the License. 254 | You may obtain a copy of the License at 255 | http://www.apache.org/licenses/LICENSE-2.0 256 | 257 | Unless required by applicable law or agreed to in writing, software distributed 258 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 259 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 260 | specific language governing permissions and limitations under the License. 261 | 262 | @preserve 263 | */ 264 | 265 | chroma.brewer = brewer = { 266 | OrRd: ['#fff7ec', '#fee8c8', '#fdd49e', '#fdbb84', '#fc8d59', '#ef6548', '#d7301f', '#b30000', '#7f0000'], 267 | PuBu: ['#fff7fb', '#ece7f2', '#d0d1e6', '#a6bddb', '#74a9cf', '#3690c0', '#0570b0', '#045a8d', '#023858'], 268 | BuPu: ['#f7fcfd', '#e0ecf4', '#bfd3e6', '#9ebcda', '#8c96c6', '#8c6bb1', '#88419d', '#810f7c', '#4d004b'], 269 | Oranges: ['#fff5eb', '#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c', '#f16913', '#d94801', '#a63603', '#7f2704'], 270 | BuGn: ['#f7fcfd', '#e5f5f9', '#ccece6', '#99d8c9', '#66c2a4', '#41ae76', '#238b45', '#006d2c', '#00441b'], 271 | YlOrBr: ['#ffffe5', '#fff7bc', '#fee391', '#fec44f', '#fe9929', '#ec7014', '#cc4c02', '#993404', '#662506'], 272 | YlGn: ['#ffffe5', '#f7fcb9', '#d9f0a3', '#addd8e', '#78c679', '#41ab5d', '#238443', '#006837', '#004529'], 273 | Reds: ['#fff5f0', '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#a50f15', '#67000d'], 274 | RdPu: ['#fff7f3', '#fde0dd', '#fcc5c0', '#fa9fb5', '#f768a1', '#dd3497', '#ae017e', '#7a0177', '#49006a'], 275 | Greens: ['#f7fcf5', '#e5f5e0', '#c7e9c0', '#a1d99b', '#74c476', '#41ab5d', '#238b45', '#006d2c', '#00441b'], 276 | YlGnBu: ['#ffffd9', '#edf8b1', '#c7e9b4', '#7fcdbb', '#41b6c4', '#1d91c0', '#225ea8', '#253494', '#081d58'], 277 | Purples: ['#fcfbfd', '#efedf5', '#dadaeb', '#bcbddc', '#9e9ac8', '#807dba', '#6a51a3', '#54278f', '#3f007d'], 278 | GnBu: ['#f7fcf0', '#e0f3db', '#ccebc5', '#a8ddb5', '#7bccc4', '#4eb3d3', '#2b8cbe', '#0868ac', '#084081'], 279 | Greys: ['#ffffff', '#f0f0f0', '#d9d9d9', '#bdbdbd', '#969696', '#737373', '#525252', '#252525', '#000000'], 280 | YlOrRd: ['#ffffcc', '#ffeda0', '#fed976', '#feb24c', '#fd8d3c', '#fc4e2a', '#e31a1c', '#bd0026', '#800026'], 281 | PuRd: ['#f7f4f9', '#e7e1ef', '#d4b9da', '#c994c7', '#df65b0', '#e7298a', '#ce1256', '#980043', '#67001f'], 282 | Blues: ['#f7fbff', '#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#4292c6', '#2171b5', '#08519c', '#08306b'], 283 | PuBuGn: ['#fff7fb', '#ece2f0', '#d0d1e6', '#a6bddb', '#67a9cf', '#3690c0', '#02818a', '#016c59', '#014636'], 284 | Spectral: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'], 285 | RdYlGn: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#d9ef8b', '#a6d96a', '#66bd63', '#1a9850', '#006837'], 286 | RdBu: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#f7f7f7', '#d1e5f0', '#92c5de', '#4393c3', '#2166ac', '#053061'], 287 | PiYG: ['#8e0152', '#c51b7d', '#de77ae', '#f1b6da', '#fde0ef', '#f7f7f7', '#e6f5d0', '#b8e186', '#7fbc41', '#4d9221', '#276419'], 288 | PRGn: ['#40004b', '#762a83', '#9970ab', '#c2a5cf', '#e7d4e8', '#f7f7f7', '#d9f0d3', '#a6dba0', '#5aae61', '#1b7837', '#00441b'], 289 | RdYlBu: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee090', '#ffffbf', '#e0f3f8', '#abd9e9', '#74add1', '#4575b4', '#313695'], 290 | BrBG: ['#543005', '#8c510a', '#bf812d', '#dfc27d', '#f6e8c3', '#f5f5f5', '#c7eae5', '#80cdc1', '#35978f', '#01665e', '#003c30'], 291 | RdGy: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#ffffff', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a'], 292 | PuOr: ['#7f3b08', '#b35806', '#e08214', '#fdb863', '#fee0b6', '#f7f7f7', '#d8daeb', '#b2abd2', '#8073ac', '#542788', '#2d004b'], 293 | Set2: ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', '#e5c494', '#b3b3b3'], 294 | Accent: ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666'], 295 | Set1: ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', '#a65628', '#f781bf', '#999999'], 296 | Set3: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f'], 297 | Dark2: ['#1b9e77', '#d95f02', '#7570b3', '#e7298a', '#66a61e', '#e6ab02', '#a6761d', '#666666'], 298 | Paired: ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928'], 299 | Pastel2: ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae', '#f1e2cc', '#cccccc'], 300 | Pastel1: ['#fbb4ae', '#b3cde3', '#ccebc5', '#decbe4', '#fed9a6', '#ffffcc', '#e5d8bd', '#fddaec', '#f2f2f2'] 301 | }; 302 | 303 | 304 | /** 305 | X11 color names 306 | 307 | http://www.w3.org/TR/css3-color/#svg-color 308 | */ 309 | 310 | w3cx11 = { 311 | indigo: "#4b0082", 312 | gold: "#ffd700", 313 | hotpink: "#ff69b4", 314 | firebrick: "#b22222", 315 | indianred: "#cd5c5c", 316 | yellow: "#ffff00", 317 | mistyrose: "#ffe4e1", 318 | darkolivegreen: "#556b2f", 319 | olive: "#808000", 320 | darkseagreen: "#8fbc8f", 321 | pink: "#ffc0cb", 322 | tomato: "#ff6347", 323 | lightcoral: "#f08080", 324 | orangered: "#ff4500", 325 | navajowhite: "#ffdead", 326 | lime: "#00ff00", 327 | palegreen: "#98fb98", 328 | darkslategrey: "#2f4f4f", 329 | greenyellow: "#adff2f", 330 | burlywood: "#deb887", 331 | seashell: "#fff5ee", 332 | mediumspringgreen: "#00fa9a", 333 | fuchsia: "#ff00ff", 334 | papayawhip: "#ffefd5", 335 | blanchedalmond: "#ffebcd", 336 | chartreuse: "#7fff00", 337 | dimgray: "#696969", 338 | black: "#000000", 339 | peachpuff: "#ffdab9", 340 | springgreen: "#00ff7f", 341 | aquamarine: "#7fffd4", 342 | white: "#ffffff", 343 | orange: "#ffa500", 344 | lightsalmon: "#ffa07a", 345 | darkslategray: "#2f4f4f", 346 | brown: "#a52a2a", 347 | ivory: "#fffff0", 348 | dodgerblue: "#1e90ff", 349 | peru: "#cd853f", 350 | lawngreen: "#7cfc00", 351 | chocolate: "#d2691e", 352 | crimson: "#dc143c", 353 | forestgreen: "#228b22", 354 | darkgrey: "#a9a9a9", 355 | lightseagreen: "#20b2aa", 356 | cyan: "#00ffff", 357 | mintcream: "#f5fffa", 358 | silver: "#c0c0c0", 359 | antiquewhite: "#faebd7", 360 | mediumorchid: "#ba55d3", 361 | skyblue: "#87ceeb", 362 | gray: "#808080", 363 | darkturquoise: "#00ced1", 364 | goldenrod: "#daa520", 365 | darkgreen: "#006400", 366 | floralwhite: "#fffaf0", 367 | darkviolet: "#9400d3", 368 | darkgray: "#a9a9a9", 369 | moccasin: "#ffe4b5", 370 | saddlebrown: "#8b4513", 371 | grey: "#808080", 372 | darkslateblue: "#483d8b", 373 | lightskyblue: "#87cefa", 374 | lightpink: "#ffb6c1", 375 | mediumvioletred: "#c71585", 376 | slategrey: "#708090", 377 | red: "#ff0000", 378 | deeppink: "#ff1493", 379 | limegreen: "#32cd32", 380 | darkmagenta: "#8b008b", 381 | palegoldenrod: "#eee8aa", 382 | plum: "#dda0dd", 383 | turquoise: "#40e0d0", 384 | lightgrey: "#d3d3d3", 385 | lightgoldenrodyellow: "#fafad2", 386 | darkgoldenrod: "#b8860b", 387 | lavender: "#e6e6fa", 388 | maroon: "#800000", 389 | yellowgreen: "#9acd32", 390 | sandybrown: "#f4a460", 391 | thistle: "#d8bfd8", 392 | violet: "#ee82ee", 393 | navy: "#000080", 394 | magenta: "#ff00ff", 395 | dimgrey: "#696969", 396 | tan: "#d2b48c", 397 | rosybrown: "#bc8f8f", 398 | olivedrab: "#6b8e23", 399 | blue: "#0000ff", 400 | lightblue: "#add8e6", 401 | ghostwhite: "#f8f8ff", 402 | honeydew: "#f0fff0", 403 | cornflowerblue: "#6495ed", 404 | slateblue: "#6a5acd", 405 | linen: "#faf0e6", 406 | darkblue: "#00008b", 407 | powderblue: "#b0e0e6", 408 | seagreen: "#2e8b57", 409 | darkkhaki: "#bdb76b", 410 | snow: "#fffafa", 411 | sienna: "#a0522d", 412 | mediumblue: "#0000cd", 413 | royalblue: "#4169e1", 414 | lightcyan: "#e0ffff", 415 | green: "#008000", 416 | mediumpurple: "#9370db", 417 | midnightblue: "#191970", 418 | cornsilk: "#fff8dc", 419 | paleturquoise: "#afeeee", 420 | bisque: "#ffe4c4", 421 | slategray: "#708090", 422 | darkcyan: "#008b8b", 423 | khaki: "#f0e68c", 424 | wheat: "#f5deb3", 425 | teal: "#008080", 426 | darkorchid: "#9932cc", 427 | deepskyblue: "#00bfff", 428 | salmon: "#fa8072", 429 | darkred: "#8b0000", 430 | steelblue: "#4682b4", 431 | palevioletred: "#db7093", 432 | lightslategray: "#778899", 433 | aliceblue: "#f0f8ff", 434 | lightslategrey: "#778899", 435 | lightgreen: "#90ee90", 436 | orchid: "#da70d6", 437 | gainsboro: "#dcdcdc", 438 | mediumseagreen: "#3cb371", 439 | lightgray: "#d3d3d3", 440 | mediumturquoise: "#48d1cc", 441 | lemonchiffon: "#fffacd", 442 | cadetblue: "#5f9ea0", 443 | lightyellow: "#ffffe0", 444 | lavenderblush: "#fff0f5", 445 | coral: "#ff7f50", 446 | purple: "#800080", 447 | aqua: "#00ffff", 448 | whitesmoke: "#f5f5f5", 449 | mediumslateblue: "#7b68ee", 450 | darkorange: "#ff8c00", 451 | mediumaquamarine: "#66cdaa", 452 | darksalmon: "#e9967a", 453 | beige: "#f5f5dc", 454 | blueviolet: "#8a2be2", 455 | azure: "#f0ffff", 456 | lightsteelblue: "#b0c4de", 457 | oldlace: "#fdf5e6", 458 | rebeccapurple: "#663399" 459 | }; 460 | 461 | chroma.colors = colors = w3cx11; 462 | 463 | lab2rgb = function() { 464 | var a, args, b, g, l, r, x, y, z; 465 | args = unpack(arguments); 466 | l = args[0], a = args[1], b = args[2]; 467 | y = (l + 16) / 116; 468 | x = isNaN(a) ? y : y + a / 500; 469 | z = isNaN(b) ? y : y - b / 200; 470 | y = LAB_CONSTANTS.Yn * lab_xyz(y); 471 | x = LAB_CONSTANTS.Xn * lab_xyz(x); 472 | z = LAB_CONSTANTS.Zn * lab_xyz(z); 473 | r = xyz_rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z); 474 | g = xyz_rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z); 475 | b = xyz_rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z); 476 | r = limit(r, 0, 255); 477 | g = limit(g, 0, 255); 478 | b = limit(b, 0, 255); 479 | return [r, g, b, args.length > 3 ? args[3] : 1]; 480 | }; 481 | 482 | xyz_rgb = function(r) { 483 | return round(255 * (r <= 0.00304 ? 12.92 * r : 1.055 * pow(r, 1 / 2.4) - 0.055)); 484 | }; 485 | 486 | lab_xyz = function(t) { 487 | if (t > LAB_CONSTANTS.t1) { 488 | return t * t * t; 489 | } else { 490 | return LAB_CONSTANTS.t2 * (t - LAB_CONSTANTS.t0); 491 | } 492 | }; 493 | 494 | LAB_CONSTANTS = { 495 | Kn: 18, 496 | Xn: 0.950470, 497 | Yn: 1, 498 | Zn: 1.088830, 499 | t0: 0.137931034, 500 | t1: 0.206896552, 501 | t2: 0.12841855, 502 | t3: 0.008856452 503 | }; 504 | 505 | rgb2lab = function() { 506 | var b, g, r, ref, ref1, x, y, z; 507 | ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; 508 | ref1 = rgb2xyz(r, g, b), x = ref1[0], y = ref1[1], z = ref1[2]; 509 | return [116 * y - 16, 500 * (x - y), 200 * (y - z)]; 510 | }; 511 | 512 | rgb_xyz = function(r) { 513 | if ((r /= 255) <= 0.04045) { 514 | return r / 12.92; 515 | } else { 516 | return pow((r + 0.055) / 1.055, 2.4); 517 | } 518 | }; 519 | 520 | xyz_lab = function(t) { 521 | if (t > LAB_CONSTANTS.t3) { 522 | return pow(t, 1 / 3); 523 | } else { 524 | return t / LAB_CONSTANTS.t2 + LAB_CONSTANTS.t0; 525 | } 526 | }; 527 | 528 | rgb2xyz = function() { 529 | var b, g, r, ref, x, y, z; 530 | ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; 531 | r = rgb_xyz(r); 532 | g = rgb_xyz(g); 533 | b = rgb_xyz(b); 534 | x = xyz_lab((0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / LAB_CONSTANTS.Xn); 535 | y = xyz_lab((0.2126729 * r + 0.7151522 * g + 0.0721750 * b) / LAB_CONSTANTS.Yn); 536 | z = xyz_lab((0.0193339 * r + 0.1191920 * g + 0.9503041 * b) / LAB_CONSTANTS.Zn); 537 | return [x, y, z]; 538 | }; 539 | 540 | chroma.lab = function() { 541 | return (function(func, args, ctor) { 542 | ctor.prototype = func.prototype; 543 | var child = new ctor, result = func.apply(child, args); 544 | return Object(result) === result ? result : child; 545 | })(Color, slice.call(arguments).concat(['lab']), function(){}); 546 | }; 547 | 548 | _input.lab = lab2rgb; 549 | 550 | Color.prototype.lab = function() { 551 | return rgb2lab(this._rgb); 552 | }; 553 | 554 | bezier = function(colors) { 555 | var I, I0, I1, c, lab0, lab1, lab2, lab3, ref, ref1, ref2; 556 | colors = (function() { 557 | var len, o, results; 558 | results = []; 559 | for (o = 0, len = colors.length; o < len; o++) { 560 | c = colors[o]; 561 | results.push(chroma(c)); 562 | } 563 | return results; 564 | })(); 565 | if (colors.length === 2) { 566 | ref = (function() { 567 | var len, o, results; 568 | results = []; 569 | for (o = 0, len = colors.length; o < len; o++) { 570 | c = colors[o]; 571 | results.push(c.lab()); 572 | } 573 | return results; 574 | })(), lab0 = ref[0], lab1 = ref[1]; 575 | I = function(t) { 576 | var i, lab; 577 | lab = (function() { 578 | var o, results; 579 | results = []; 580 | for (i = o = 0; o <= 2; i = ++o) { 581 | results.push(lab0[i] + t * (lab1[i] - lab0[i])); 582 | } 583 | return results; 584 | })(); 585 | return chroma.lab.apply(chroma, lab); 586 | }; 587 | } else if (colors.length === 3) { 588 | ref1 = (function() { 589 | var len, o, results; 590 | results = []; 591 | for (o = 0, len = colors.length; o < len; o++) { 592 | c = colors[o]; 593 | results.push(c.lab()); 594 | } 595 | return results; 596 | })(), lab0 = ref1[0], lab1 = ref1[1], lab2 = ref1[2]; 597 | I = function(t) { 598 | var i, lab; 599 | lab = (function() { 600 | var o, results; 601 | results = []; 602 | for (i = o = 0; o <= 2; i = ++o) { 603 | results.push((1 - t) * (1 - t) * lab0[i] + 2 * (1 - t) * t * lab1[i] + t * t * lab2[i]); 604 | } 605 | return results; 606 | })(); 607 | return chroma.lab.apply(chroma, lab); 608 | }; 609 | } else if (colors.length === 4) { 610 | ref2 = (function() { 611 | var len, o, results; 612 | results = []; 613 | for (o = 0, len = colors.length; o < len; o++) { 614 | c = colors[o]; 615 | results.push(c.lab()); 616 | } 617 | return results; 618 | })(), lab0 = ref2[0], lab1 = ref2[1], lab2 = ref2[2], lab3 = ref2[3]; 619 | I = function(t) { 620 | var i, lab; 621 | lab = (function() { 622 | var o, results; 623 | results = []; 624 | for (i = o = 0; o <= 2; i = ++o) { 625 | results.push((1 - t) * (1 - t) * (1 - t) * lab0[i] + 3 * (1 - t) * (1 - t) * t * lab1[i] + 3 * (1 - t) * t * t * lab2[i] + t * t * t * lab3[i]); 626 | } 627 | return results; 628 | })(); 629 | return chroma.lab.apply(chroma, lab); 630 | }; 631 | } else if (colors.length === 5) { 632 | I0 = bezier(colors.slice(0, 3)); 633 | I1 = bezier(colors.slice(2, 5)); 634 | I = function(t) { 635 | if (t < 0.5) { 636 | return I0(t * 2); 637 | } else { 638 | return I1((t - 0.5) * 2); 639 | } 640 | }; 641 | } 642 | return I; 643 | }; 644 | 645 | chroma.bezier = function(colors) { 646 | var f; 647 | f = bezier(colors); 648 | f.scale = function() { 649 | return chroma.scale(f); 650 | }; 651 | return f; 652 | }; 653 | 654 | 655 | /* 656 | chroma.js 657 | 658 | Copyright (c) 2011-2013, Gregor Aisch 659 | All rights reserved. 660 | 661 | Redistribution and use in source and binary forms, with or without 662 | modification, are permitted provided that the following conditions are met: 663 | 664 | * Redistributions of source code must retain the above copyright notice, this 665 | list of conditions and the following disclaimer. 666 | 667 | * Redistributions in binary form must reproduce the above copyright notice, 668 | this list of conditions and the following disclaimer in the documentation 669 | and/or other materials provided with the distribution. 670 | 671 | * The name Gregor Aisch may not be used to endorse or promote products 672 | derived from this software without specific prior written permission. 673 | 674 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 675 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 676 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 677 | DISCLAIMED. IN NO EVENT SHALL GREGOR AISCH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 678 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 679 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 680 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 681 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 682 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 683 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 684 | 685 | @source: https://github.com/gka/chroma.js 686 | */ 687 | 688 | chroma.cubehelix = function(start, rotations, hue, gamma, lightness) { 689 | var dh, dl, f; 690 | if (start == null) { 691 | start = 300; 692 | } 693 | if (rotations == null) { 694 | rotations = -1.5; 695 | } 696 | if (hue == null) { 697 | hue = 1; 698 | } 699 | if (gamma == null) { 700 | gamma = 1; 701 | } 702 | if (lightness == null) { 703 | lightness = [0, 1]; 704 | } 705 | dl = lightness[1] - lightness[0]; 706 | dh = 0; 707 | f = function(fract) { 708 | var a, amp, b, cos_a, g, h, l, r, sin_a; 709 | a = TWOPI * ((start + 120) / 360 + rotations * fract); 710 | l = pow(lightness[0] + dl * fract, gamma); 711 | h = dh !== 0 ? hue[0] + fract * dh : hue; 712 | amp = h * l * (1 - l) / 2; 713 | cos_a = cos(a); 714 | sin_a = sin(a); 715 | r = l + amp * (-0.14861 * cos_a + 1.78277 * sin_a); 716 | g = l + amp * (-0.29227 * cos_a - 0.90649 * sin_a); 717 | b = l + amp * (+1.97294 * cos_a); 718 | return chroma(clip_rgb([r * 255, g * 255, b * 255])); 719 | }; 720 | f.start = function(s) { 721 | if (s == null) { 722 | return start; 723 | } 724 | start = s; 725 | return f; 726 | }; 727 | f.rotations = function(r) { 728 | if (r == null) { 729 | return rotations; 730 | } 731 | rotations = r; 732 | return f; 733 | }; 734 | f.gamma = function(g) { 735 | if (g == null) { 736 | return gamma; 737 | } 738 | gamma = g; 739 | return f; 740 | }; 741 | f.hue = function(h) { 742 | if (h == null) { 743 | return hue; 744 | } 745 | hue = h; 746 | if (type(hue) === 'array') { 747 | dh = hue[1] - hue[0]; 748 | if (dh === 0) { 749 | hue = hue[1]; 750 | } 751 | } else { 752 | dh = 0; 753 | } 754 | return f; 755 | }; 756 | f.lightness = function(h) { 757 | if (h == null) { 758 | return lightness; 759 | } 760 | lightness = h; 761 | if (type(lightness) === 'array') { 762 | dl = lightness[1] - lightness[0]; 763 | if (dl === 0) { 764 | lightness = lightness[1]; 765 | } 766 | } else { 767 | dl = 0; 768 | } 769 | return f; 770 | }; 771 | f.scale = function() { 772 | return chroma.scale(f); 773 | }; 774 | f.hue(hue); 775 | return f; 776 | }; 777 | 778 | chroma.random = function() { 779 | var code, digits, i, o; 780 | digits = '0123456789abcdef'; 781 | code = '#'; 782 | for (i = o = 0; o < 6; i = ++o) { 783 | code += digits.charAt(floor(Math.random() * 16)); 784 | } 785 | return new Color(code); 786 | }; 787 | 788 | chroma.average = function(colors) { 789 | var a, b, c, g, l, len, o, r, rgba; 790 | r = g = b = a = 0; 791 | l = colors.length; 792 | for (o = 0, len = colors.length; o < len; o++) { 793 | c = colors[o]; 794 | rgba = chroma(c).rgba(); 795 | r += rgba[0]; 796 | g += rgba[1]; 797 | b += rgba[2]; 798 | a += rgba[3]; 799 | } 800 | return new Color(r / l, g / l, b / l, a / l); 801 | }; 802 | 803 | _input.rgb = function() { 804 | var k, ref, results, v; 805 | ref = unpack(arguments); 806 | results = []; 807 | for (k in ref) { 808 | v = ref[k]; 809 | results.push(v); 810 | } 811 | return results; 812 | }; 813 | 814 | chroma.rgb = function() { 815 | return (function(func, args, ctor) { 816 | ctor.prototype = func.prototype; 817 | var child = new ctor, result = func.apply(child, args); 818 | return Object(result) === result ? result : child; 819 | })(Color, slice.call(arguments).concat(['rgb']), function(){}); 820 | }; 821 | 822 | Color.prototype.rgb = function() { 823 | return this._rgb.slice(0, 3); 824 | }; 825 | 826 | Color.prototype.rgba = function() { 827 | return this._rgb; 828 | }; 829 | 830 | _guess_formats.push({ 831 | p: 15, 832 | test: function(n) { 833 | var a; 834 | a = unpack(arguments); 835 | if (type(a) === 'array' && a.length === 3) { 836 | return 'rgb'; 837 | } 838 | if (a.length === 4 && type(a[3]) === "number" && a[3] >= 0 && a[3] <= 1) { 839 | return 'rgb'; 840 | } 841 | } 842 | }); 843 | 844 | hex2rgb = function(hex) { 845 | var a, b, g, r, rgb, u; 846 | if (hex.match(/^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/)) { 847 | if (hex.length === 4 || hex.length === 7) { 848 | hex = hex.substr(1); 849 | } 850 | if (hex.length === 3) { 851 | hex = hex.split(""); 852 | hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; 853 | } 854 | u = parseInt(hex, 16); 855 | r = u >> 16; 856 | g = u >> 8 & 0xFF; 857 | b = u & 0xFF; 858 | return [r, g, b, 1]; 859 | } 860 | if (hex.match(/^#?([A-Fa-f0-9]{8})$/)) { 861 | if (hex.length === 9) { 862 | hex = hex.substr(1); 863 | } 864 | u = parseInt(hex, 16); 865 | r = u >> 24 & 0xFF; 866 | g = u >> 16 & 0xFF; 867 | b = u >> 8 & 0xFF; 868 | a = round((u & 0xFF) / 0xFF * 100) / 100; 869 | return [r, g, b, a]; 870 | } 871 | if ((_input.css != null) && (rgb = _input.css(hex))) { 872 | return rgb; 873 | } 874 | throw "unknown color: " + hex; 875 | }; 876 | 877 | rgb2hex = function(channels, mode) { 878 | var a, b, g, hxa, r, str, u; 879 | if (mode == null) { 880 | mode = 'rgb'; 881 | } 882 | r = channels[0], g = channels[1], b = channels[2], a = channels[3]; 883 | u = r << 16 | g << 8 | b; 884 | str = "000000" + u.toString(16); 885 | str = str.substr(str.length - 6); 886 | hxa = '0' + round(a * 255).toString(16); 887 | hxa = hxa.substr(hxa.length - 2); 888 | return "#" + (function() { 889 | switch (mode.toLowerCase()) { 890 | case 'rgba': 891 | return str + hxa; 892 | case 'argb': 893 | return hxa + str; 894 | default: 895 | return str; 896 | } 897 | })(); 898 | }; 899 | 900 | _input.hex = function(h) { 901 | return hex2rgb(h); 902 | }; 903 | 904 | chroma.hex = function() { 905 | return (function(func, args, ctor) { 906 | ctor.prototype = func.prototype; 907 | var child = new ctor, result = func.apply(child, args); 908 | return Object(result) === result ? result : child; 909 | })(Color, slice.call(arguments).concat(['hex']), function(){}); 910 | }; 911 | 912 | Color.prototype.hex = function(mode) { 913 | if (mode == null) { 914 | mode = 'rgb'; 915 | } 916 | return rgb2hex(this._rgb, mode); 917 | }; 918 | 919 | _guess_formats.push({ 920 | p: 10, 921 | test: function(n) { 922 | if (arguments.length === 1 && type(n) === "string") { 923 | return 'hex'; 924 | } 925 | } 926 | }); 927 | 928 | hsl2rgb = function() { 929 | var args, b, c, g, h, i, l, o, r, ref, s, t1, t2, t3; 930 | args = unpack(arguments); 931 | h = args[0], s = args[1], l = args[2]; 932 | if (s === 0) { 933 | r = g = b = l * 255; 934 | } else { 935 | t3 = [0, 0, 0]; 936 | c = [0, 0, 0]; 937 | t2 = l < 0.5 ? l * (1 + s) : l + s - l * s; 938 | t1 = 2 * l - t2; 939 | h /= 360; 940 | t3[0] = h + 1 / 3; 941 | t3[1] = h; 942 | t3[2] = h - 1 / 3; 943 | for (i = o = 0; o <= 2; i = ++o) { 944 | if (t3[i] < 0) { 945 | t3[i] += 1; 946 | } 947 | if (t3[i] > 1) { 948 | t3[i] -= 1; 949 | } 950 | if (6 * t3[i] < 1) { 951 | c[i] = t1 + (t2 - t1) * 6 * t3[i]; 952 | } else if (2 * t3[i] < 1) { 953 | c[i] = t2; 954 | } else if (3 * t3[i] < 2) { 955 | c[i] = t1 + (t2 - t1) * ((2 / 3) - t3[i]) * 6; 956 | } else { 957 | c[i] = t1; 958 | } 959 | } 960 | ref = [round(c[0] * 255), round(c[1] * 255), round(c[2] * 255)], r = ref[0], g = ref[1], b = ref[2]; 961 | } 962 | if (args.length > 3) { 963 | return [r, g, b, args[3]]; 964 | } else { 965 | return [r, g, b]; 966 | } 967 | }; 968 | 969 | rgb2hsl = function(r, g, b) { 970 | var h, l, min, ref, s; 971 | if (r !== void 0 && r.length >= 3) { 972 | ref = r, r = ref[0], g = ref[1], b = ref[2]; 973 | } 974 | r /= 255; 975 | g /= 255; 976 | b /= 255; 977 | min = Math.min(r, g, b); 978 | max = Math.max(r, g, b); 979 | l = (max + min) / 2; 980 | if (max === min) { 981 | s = 0; 982 | h = Number.NaN; 983 | } else { 984 | s = l < 0.5 ? (max - min) / (max + min) : (max - min) / (2 - max - min); 985 | } 986 | if (r === max) { 987 | h = (g - b) / (max - min); 988 | } else if (g === max) { 989 | h = 2 + (b - r) / (max - min); 990 | } else if (b === max) { 991 | h = 4 + (r - g) / (max - min); 992 | } 993 | h *= 60; 994 | if (h < 0) { 995 | h += 360; 996 | } 997 | return [h, s, l]; 998 | }; 999 | 1000 | chroma.hsl = function() { 1001 | return (function(func, args, ctor) { 1002 | ctor.prototype = func.prototype; 1003 | var child = new ctor, result = func.apply(child, args); 1004 | return Object(result) === result ? result : child; 1005 | })(Color, slice.call(arguments).concat(['hsl']), function(){}); 1006 | }; 1007 | 1008 | _input.hsl = hsl2rgb; 1009 | 1010 | Color.prototype.hsl = function() { 1011 | return rgb2hsl(this._rgb); 1012 | }; 1013 | 1014 | hsv2rgb = function() { 1015 | var args, b, f, g, h, i, p, q, r, ref, ref1, ref2, ref3, ref4, ref5, s, t, v; 1016 | args = unpack(arguments); 1017 | h = args[0], s = args[1], v = args[2]; 1018 | v *= 255; 1019 | if (s === 0) { 1020 | r = g = b = v; 1021 | } else { 1022 | if (h === 360) { 1023 | h = 0; 1024 | } 1025 | if (h > 360) { 1026 | h -= 360; 1027 | } 1028 | if (h < 0) { 1029 | h += 360; 1030 | } 1031 | h /= 60; 1032 | i = floor(h); 1033 | f = h - i; 1034 | p = v * (1 - s); 1035 | q = v * (1 - s * f); 1036 | t = v * (1 - s * (1 - f)); 1037 | switch (i) { 1038 | case 0: 1039 | ref = [v, t, p], r = ref[0], g = ref[1], b = ref[2]; 1040 | break; 1041 | case 1: 1042 | ref1 = [q, v, p], r = ref1[0], g = ref1[1], b = ref1[2]; 1043 | break; 1044 | case 2: 1045 | ref2 = [p, v, t], r = ref2[0], g = ref2[1], b = ref2[2]; 1046 | break; 1047 | case 3: 1048 | ref3 = [p, q, v], r = ref3[0], g = ref3[1], b = ref3[2]; 1049 | break; 1050 | case 4: 1051 | ref4 = [t, p, v], r = ref4[0], g = ref4[1], b = ref4[2]; 1052 | break; 1053 | case 5: 1054 | ref5 = [v, p, q], r = ref5[0], g = ref5[1], b = ref5[2]; 1055 | } 1056 | } 1057 | r = round(r); 1058 | g = round(g); 1059 | b = round(b); 1060 | return [r, g, b, args.length > 3 ? args[3] : 1]; 1061 | }; 1062 | 1063 | rgb2hsv = function() { 1064 | var b, delta, g, h, min, r, ref, s, v; 1065 | ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; 1066 | min = Math.min(r, g, b); 1067 | max = Math.max(r, g, b); 1068 | delta = max - min; 1069 | v = max / 255.0; 1070 | if (max === 0) { 1071 | h = Number.NaN; 1072 | s = 0; 1073 | } else { 1074 | s = delta / max; 1075 | if (r === max) { 1076 | h = (g - b) / delta; 1077 | } 1078 | if (g === max) { 1079 | h = 2 + (b - r) / delta; 1080 | } 1081 | if (b === max) { 1082 | h = 4 + (r - g) / delta; 1083 | } 1084 | h *= 60; 1085 | if (h < 0) { 1086 | h += 360; 1087 | } 1088 | } 1089 | return [h, s, v]; 1090 | }; 1091 | 1092 | chroma.hsv = function() { 1093 | return (function(func, args, ctor) { 1094 | ctor.prototype = func.prototype; 1095 | var child = new ctor, result = func.apply(child, args); 1096 | return Object(result) === result ? result : child; 1097 | })(Color, slice.call(arguments).concat(['hsv']), function(){}); 1098 | }; 1099 | 1100 | _input.hsv = hsv2rgb; 1101 | 1102 | Color.prototype.hsv = function() { 1103 | return rgb2hsv(this._rgb); 1104 | }; 1105 | 1106 | num2rgb = function(num) { 1107 | var b, g, r; 1108 | if (type(num) === "number" && num >= 0 && num <= 0xFFFFFF) { 1109 | r = num >> 16; 1110 | g = (num >> 8) & 0xFF; 1111 | b = num & 0xFF; 1112 | return [r, g, b, 1]; 1113 | } 1114 | console.warn("unknown num color: " + num); 1115 | return [0, 0, 0, 1]; 1116 | }; 1117 | 1118 | rgb2num = function() { 1119 | var b, g, r, ref; 1120 | ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; 1121 | return (r << 16) + (g << 8) + b; 1122 | }; 1123 | 1124 | chroma.num = function(num) { 1125 | return new Color(num, 'num'); 1126 | }; 1127 | 1128 | Color.prototype.num = function(mode) { 1129 | if (mode == null) { 1130 | mode = 'rgb'; 1131 | } 1132 | return rgb2num(this._rgb, mode); 1133 | }; 1134 | 1135 | _input.num = num2rgb; 1136 | 1137 | _guess_formats.push({ 1138 | p: 10, 1139 | test: function(n) { 1140 | if (arguments.length === 1 && type(n) === "number" && n >= 0 && n <= 0xFFFFFF) { 1141 | return 'num'; 1142 | } 1143 | } 1144 | }); 1145 | 1146 | css2rgb = function(css) { 1147 | var aa, ab, hsl, i, m, o, rgb, w; 1148 | css = css.toLowerCase(); 1149 | if ((chroma.colors != null) && chroma.colors[css]) { 1150 | return hex2rgb(chroma.colors[css]); 1151 | } 1152 | if (m = css.match(/rgb\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*\)/)) { 1153 | rgb = m.slice(1, 4); 1154 | for (i = o = 0; o <= 2; i = ++o) { 1155 | rgb[i] = +rgb[i]; 1156 | } 1157 | rgb[3] = 1; 1158 | } else if (m = css.match(/rgba\(\s*(\-?\d+),\s*(\-?\d+)\s*,\s*(\-?\d+)\s*,\s*([01]|[01]?\.\d+)\)/)) { 1159 | rgb = m.slice(1, 5); 1160 | for (i = w = 0; w <= 3; i = ++w) { 1161 | rgb[i] = +rgb[i]; 1162 | } 1163 | } else if (m = css.match(/rgb\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/)) { 1164 | rgb = m.slice(1, 4); 1165 | for (i = aa = 0; aa <= 2; i = ++aa) { 1166 | rgb[i] = round(rgb[i] * 2.55); 1167 | } 1168 | rgb[3] = 1; 1169 | } else if (m = css.match(/rgba\(\s*(\-?\d+(?:\.\d+)?)%,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/)) { 1170 | rgb = m.slice(1, 5); 1171 | for (i = ab = 0; ab <= 2; i = ++ab) { 1172 | rgb[i] = round(rgb[i] * 2.55); 1173 | } 1174 | rgb[3] = +rgb[3]; 1175 | } else if (m = css.match(/hsl\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*\)/)) { 1176 | hsl = m.slice(1, 4); 1177 | hsl[1] *= 0.01; 1178 | hsl[2] *= 0.01; 1179 | rgb = hsl2rgb(hsl); 1180 | rgb[3] = 1; 1181 | } else if (m = css.match(/hsla\(\s*(\-?\d+(?:\.\d+)?),\s*(\-?\d+(?:\.\d+)?)%\s*,\s*(\-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)/)) { 1182 | hsl = m.slice(1, 4); 1183 | hsl[1] *= 0.01; 1184 | hsl[2] *= 0.01; 1185 | rgb = hsl2rgb(hsl); 1186 | rgb[3] = +m[4]; 1187 | } 1188 | return rgb; 1189 | }; 1190 | 1191 | rgb2css = function(rgba) { 1192 | var mode; 1193 | mode = rgba[3] < 1 ? 'rgba' : 'rgb'; 1194 | if (mode === 'rgb') { 1195 | return mode + '(' + rgba.slice(0, 3).map(round).join(',') + ')'; 1196 | } else if (mode === 'rgba') { 1197 | return mode + '(' + rgba.slice(0, 3).map(round).join(',') + ',' + rgba[3] + ')'; 1198 | } else { 1199 | 1200 | } 1201 | }; 1202 | 1203 | rnd = function(a) { 1204 | return round(a * 100) / 100; 1205 | }; 1206 | 1207 | hsl2css = function(hsl, alpha) { 1208 | var mode; 1209 | mode = alpha < 1 ? 'hsla' : 'hsl'; 1210 | hsl[0] = rnd(hsl[0] || 0); 1211 | hsl[1] = rnd(hsl[1] * 100) + '%'; 1212 | hsl[2] = rnd(hsl[2] * 100) + '%'; 1213 | if (mode === 'hsla') { 1214 | hsl[3] = alpha; 1215 | } 1216 | return mode + '(' + hsl.join(',') + ')'; 1217 | }; 1218 | 1219 | _input.css = function(h) { 1220 | return css2rgb(h); 1221 | }; 1222 | 1223 | chroma.css = function() { 1224 | return (function(func, args, ctor) { 1225 | ctor.prototype = func.prototype; 1226 | var child = new ctor, result = func.apply(child, args); 1227 | return Object(result) === result ? result : child; 1228 | })(Color, slice.call(arguments).concat(['css']), function(){}); 1229 | }; 1230 | 1231 | Color.prototype.css = function(mode) { 1232 | if (mode == null) { 1233 | mode = 'rgb'; 1234 | } 1235 | if (mode.slice(0, 3) === 'rgb') { 1236 | return rgb2css(this._rgb); 1237 | } else if (mode.slice(0, 3) === 'hsl') { 1238 | return hsl2css(this.hsl(), this.alpha()); 1239 | } 1240 | }; 1241 | 1242 | _input.named = function(name) { 1243 | return hex2rgb(w3cx11[name]); 1244 | }; 1245 | 1246 | _guess_formats.push({ 1247 | p: 20, 1248 | test: function(n) { 1249 | if (arguments.length === 1 && (w3cx11[n] != null)) { 1250 | return 'named'; 1251 | } 1252 | } 1253 | }); 1254 | 1255 | Color.prototype.name = function(n) { 1256 | var h, k; 1257 | if (arguments.length) { 1258 | if (w3cx11[n]) { 1259 | this._rgb = hex2rgb(w3cx11[n]); 1260 | } 1261 | this._rgb[3] = 1; 1262 | this; 1263 | } 1264 | h = this.hex(); 1265 | for (k in w3cx11) { 1266 | if (h === w3cx11[k]) { 1267 | return k; 1268 | } 1269 | } 1270 | return h; 1271 | }; 1272 | 1273 | lch2lab = function() { 1274 | 1275 | /* 1276 | Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel. 1277 | These formulas were invented by David Dalrymple to obtain maximum contrast without going 1278 | out of gamut if the parameters are in the range 0-1. 1279 | 1280 | A saturation multiplier was added by Gregor Aisch 1281 | */ 1282 | var c, h, l, ref; 1283 | ref = unpack(arguments), l = ref[0], c = ref[1], h = ref[2]; 1284 | h = h * DEG2RAD; 1285 | return [l, cos(h) * c, sin(h) * c]; 1286 | }; 1287 | 1288 | lch2rgb = function() { 1289 | var L, a, args, b, c, g, h, l, r, ref, ref1; 1290 | args = unpack(arguments); 1291 | l = args[0], c = args[1], h = args[2]; 1292 | ref = lch2lab(l, c, h), L = ref[0], a = ref[1], b = ref[2]; 1293 | ref1 = lab2rgb(L, a, b), r = ref1[0], g = ref1[1], b = ref1[2]; 1294 | return [limit(r, 0, 255), limit(g, 0, 255), limit(b, 0, 255), args.length > 3 ? args[3] : 1]; 1295 | }; 1296 | 1297 | lab2lch = function() { 1298 | var a, b, c, h, l, ref; 1299 | ref = unpack(arguments), l = ref[0], a = ref[1], b = ref[2]; 1300 | c = sqrt(a * a + b * b); 1301 | h = (atan2(b, a) * RAD2DEG + 360) % 360; 1302 | if (round(c * 10000) === 0) { 1303 | h = Number.NaN; 1304 | } 1305 | return [l, c, h]; 1306 | }; 1307 | 1308 | rgb2lch = function() { 1309 | var a, b, g, l, r, ref, ref1; 1310 | ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; 1311 | ref1 = rgb2lab(r, g, b), l = ref1[0], a = ref1[1], b = ref1[2]; 1312 | return lab2lch(l, a, b); 1313 | }; 1314 | 1315 | chroma.lch = function() { 1316 | var args; 1317 | args = unpack(arguments); 1318 | return new Color(args, 'lch'); 1319 | }; 1320 | 1321 | chroma.hcl = function() { 1322 | var args; 1323 | args = unpack(arguments); 1324 | return new Color(args, 'hcl'); 1325 | }; 1326 | 1327 | _input.lch = lch2rgb; 1328 | 1329 | _input.hcl = function() { 1330 | var c, h, l, ref; 1331 | ref = unpack(arguments), h = ref[0], c = ref[1], l = ref[2]; 1332 | return lch2rgb([l, c, h]); 1333 | }; 1334 | 1335 | Color.prototype.lch = function() { 1336 | return rgb2lch(this._rgb); 1337 | }; 1338 | 1339 | Color.prototype.hcl = function() { 1340 | return rgb2lch(this._rgb).reverse(); 1341 | }; 1342 | 1343 | rgb2cmyk = function(mode) { 1344 | var b, c, f, g, k, m, r, ref, y; 1345 | if (mode == null) { 1346 | mode = 'rgb'; 1347 | } 1348 | ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; 1349 | r = r / 255; 1350 | g = g / 255; 1351 | b = b / 255; 1352 | k = 1 - Math.max(r, Math.max(g, b)); 1353 | f = k < 1 ? 1 / (1 - k) : 0; 1354 | c = (1 - r - k) * f; 1355 | m = (1 - g - k) * f; 1356 | y = (1 - b - k) * f; 1357 | return [c, m, y, k]; 1358 | }; 1359 | 1360 | cmyk2rgb = function() { 1361 | var alpha, args, b, c, g, k, m, r, y; 1362 | args = unpack(arguments); 1363 | c = args[0], m = args[1], y = args[2], k = args[3]; 1364 | alpha = args.length > 4 ? args[4] : 1; 1365 | if (k === 1) { 1366 | return [0, 0, 0, alpha]; 1367 | } 1368 | r = c >= 1 ? 0 : round(255 * (1 - c) * (1 - k)); 1369 | g = m >= 1 ? 0 : round(255 * (1 - m) * (1 - k)); 1370 | b = y >= 1 ? 0 : round(255 * (1 - y) * (1 - k)); 1371 | return [r, g, b, alpha]; 1372 | }; 1373 | 1374 | _input.cmyk = function() { 1375 | return cmyk2rgb(unpack(arguments)); 1376 | }; 1377 | 1378 | chroma.cmyk = function() { 1379 | return (function(func, args, ctor) { 1380 | ctor.prototype = func.prototype; 1381 | var child = new ctor, result = func.apply(child, args); 1382 | return Object(result) === result ? result : child; 1383 | })(Color, slice.call(arguments).concat(['cmyk']), function(){}); 1384 | }; 1385 | 1386 | Color.prototype.cmyk = function() { 1387 | return rgb2cmyk(this._rgb); 1388 | }; 1389 | 1390 | _input.gl = function() { 1391 | var i, k, o, rgb, v; 1392 | rgb = (function() { 1393 | var ref, results; 1394 | ref = unpack(arguments); 1395 | results = []; 1396 | for (k in ref) { 1397 | v = ref[k]; 1398 | results.push(v); 1399 | } 1400 | return results; 1401 | }).apply(this, arguments); 1402 | for (i = o = 0; o <= 2; i = ++o) { 1403 | rgb[i] *= 255; 1404 | } 1405 | return rgb; 1406 | }; 1407 | 1408 | chroma.gl = function() { 1409 | return (function(func, args, ctor) { 1410 | ctor.prototype = func.prototype; 1411 | var child = new ctor, result = func.apply(child, args); 1412 | return Object(result) === result ? result : child; 1413 | })(Color, slice.call(arguments).concat(['gl']), function(){}); 1414 | }; 1415 | 1416 | Color.prototype.gl = function() { 1417 | var rgb; 1418 | rgb = this._rgb; 1419 | return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, rgb[3]]; 1420 | }; 1421 | 1422 | rgb2luminance = function(r, g, b) { 1423 | var ref; 1424 | ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; 1425 | r = luminance_x(r); 1426 | g = luminance_x(g); 1427 | b = luminance_x(b); 1428 | return 0.2126 * r + 0.7152 * g + 0.0722 * b; 1429 | }; 1430 | 1431 | luminance_x = function(x) { 1432 | x /= 255; 1433 | if (x <= 0.03928) { 1434 | return x / 12.92; 1435 | } else { 1436 | return pow((x + 0.055) / 1.055, 2.4); 1437 | } 1438 | }; 1439 | 1440 | _interpolators = []; 1441 | 1442 | interpolate = function(col1, col2, f, m) { 1443 | var interpol, len, o, res; 1444 | if (f == null) { 1445 | f = 0.5; 1446 | } 1447 | if (m == null) { 1448 | m = 'rgb'; 1449 | } 1450 | 1451 | /* 1452 | interpolates between colors 1453 | f = 0 --> me 1454 | f = 1 --> col 1455 | */ 1456 | if (type(col1) !== 'object') { 1457 | col1 = chroma(col1); 1458 | } 1459 | if (type(col2) !== 'object') { 1460 | col2 = chroma(col2); 1461 | } 1462 | for (o = 0, len = _interpolators.length; o < len; o++) { 1463 | interpol = _interpolators[o]; 1464 | if (m === interpol[0]) { 1465 | res = interpol[1](col1, col2, f, m); 1466 | break; 1467 | } 1468 | } 1469 | if (res == null) { 1470 | throw "color mode " + m + " is not supported"; 1471 | } 1472 | res.alpha(col1.alpha() + f * (col2.alpha() - col1.alpha())); 1473 | return res; 1474 | }; 1475 | 1476 | chroma.interpolate = interpolate; 1477 | 1478 | Color.prototype.interpolate = function(col2, f, m) { 1479 | return interpolate(this, col2, f, m); 1480 | }; 1481 | 1482 | chroma.mix = interpolate; 1483 | 1484 | Color.prototype.mix = Color.prototype.interpolate; 1485 | 1486 | interpolate_rgb = function(col1, col2, f, m) { 1487 | var xyz0, xyz1; 1488 | xyz0 = col1._rgb; 1489 | xyz1 = col2._rgb; 1490 | return new Color(xyz0[0] + f * (xyz1[0] - xyz0[0]), xyz0[1] + f * (xyz1[1] - xyz0[1]), xyz0[2] + f * (xyz1[2] - xyz0[2]), m); 1491 | }; 1492 | 1493 | _interpolators.push(['rgb', interpolate_rgb]); 1494 | 1495 | Color.prototype.luminance = function(lum, mode) { 1496 | var cur_lum, eps, max_iter, test; 1497 | if (mode == null) { 1498 | mode = 'rgb'; 1499 | } 1500 | if (!arguments.length) { 1501 | return rgb2luminance(this._rgb); 1502 | } 1503 | if (lum === 0) { 1504 | this._rgb = [0, 0, 0, this._rgb[3]]; 1505 | } else if (lum === 1) { 1506 | this._rgb = [255, 255, 255, this._rgb[3]]; 1507 | } else { 1508 | eps = 1e-7; 1509 | max_iter = 20; 1510 | test = function(l, h) { 1511 | var lm, m; 1512 | m = l.interpolate(h, 0.5, mode); 1513 | lm = m.luminance(); 1514 | if (Math.abs(lum - lm) < eps || !max_iter--) { 1515 | return m; 1516 | } 1517 | if (lm > lum) { 1518 | return test(l, m); 1519 | } 1520 | return test(m, h); 1521 | }; 1522 | cur_lum = rgb2luminance(this._rgb); 1523 | this._rgb = (cur_lum > lum ? test(chroma('black'), this) : test(this, chroma('white'))).rgba(); 1524 | } 1525 | return this; 1526 | }; 1527 | 1528 | temperature2rgb = function(kelvin) { 1529 | var b, g, r, temp; 1530 | temp = kelvin / 100; 1531 | if (temp < 66) { 1532 | r = 255; 1533 | g = -155.25485562709179 - 0.44596950469579133 * (g = temp - 2) + 104.49216199393888 * log(g); 1534 | b = temp < 20 ? 0 : -254.76935184120902 + 0.8274096064007395 * (b = temp - 10) + 115.67994401066147 * log(b); 1535 | } else { 1536 | r = 351.97690566805693 + 0.114206453784165 * (r = temp - 55) - 40.25366309332127 * log(r); 1537 | g = 325.4494125711974 + 0.07943456536662342 * (g = temp - 50) - 28.0852963507957 * log(g); 1538 | b = 255; 1539 | } 1540 | return clip_rgb([r, g, b]); 1541 | }; 1542 | 1543 | rgb2temperature = function() { 1544 | var b, eps, g, maxTemp, minTemp, r, ref, rgb, temp; 1545 | ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; 1546 | minTemp = 1000; 1547 | maxTemp = 40000; 1548 | eps = 0.4; 1549 | while (maxTemp - minTemp > eps) { 1550 | temp = (maxTemp + minTemp) * 0.5; 1551 | rgb = temperature2rgb(temp); 1552 | if ((rgb[2] / rgb[0]) >= (b / r)) { 1553 | maxTemp = temp; 1554 | } else { 1555 | minTemp = temp; 1556 | } 1557 | } 1558 | return round(temp); 1559 | }; 1560 | 1561 | chroma.temperature = chroma.kelvin = function() { 1562 | return (function(func, args, ctor) { 1563 | ctor.prototype = func.prototype; 1564 | var child = new ctor, result = func.apply(child, args); 1565 | return Object(result) === result ? result : child; 1566 | })(Color, slice.call(arguments).concat(['temperature']), function(){}); 1567 | }; 1568 | 1569 | _input.temperature = _input.kelvin = _input.K = temperature2rgb; 1570 | 1571 | Color.prototype.temperature = function() { 1572 | return rgb2temperature(this._rgb); 1573 | }; 1574 | 1575 | Color.prototype.kelvin = Color.prototype.temperature; 1576 | 1577 | chroma.contrast = function(a, b) { 1578 | var l1, l2, ref, ref1; 1579 | if ((ref = type(a)) === 'string' || ref === 'number') { 1580 | a = new Color(a); 1581 | } 1582 | if ((ref1 = type(b)) === 'string' || ref1 === 'number') { 1583 | b = new Color(b); 1584 | } 1585 | l1 = a.luminance(); 1586 | l2 = b.luminance(); 1587 | if (l1 > l2) { 1588 | return (l1 + 0.05) / (l2 + 0.05); 1589 | } else { 1590 | return (l2 + 0.05) / (l1 + 0.05); 1591 | } 1592 | }; 1593 | 1594 | Color.prototype.get = function(modechan) { 1595 | var channel, i, me, mode, ref, src; 1596 | me = this; 1597 | ref = modechan.split('.'), mode = ref[0], channel = ref[1]; 1598 | src = me[mode](); 1599 | if (channel) { 1600 | i = mode.indexOf(channel); 1601 | if (i > -1) { 1602 | return src[i]; 1603 | } else { 1604 | return console.warn('unknown channel ' + channel + ' in mode ' + mode); 1605 | } 1606 | } else { 1607 | return src; 1608 | } 1609 | }; 1610 | 1611 | Color.prototype.set = function(modechan, value) { 1612 | var channel, i, me, mode, ref, src; 1613 | me = this; 1614 | ref = modechan.split('.'), mode = ref[0], channel = ref[1]; 1615 | if (channel) { 1616 | src = me[mode](); 1617 | i = mode.indexOf(channel); 1618 | if (i > -1) { 1619 | if (type(value) === 'string') { 1620 | switch (value.charAt(0)) { 1621 | case '+': 1622 | src[i] += +value; 1623 | break; 1624 | case '-': 1625 | src[i] += +value; 1626 | break; 1627 | case '*': 1628 | src[i] *= +(value.substr(1)); 1629 | break; 1630 | case '/': 1631 | src[i] /= +(value.substr(1)); 1632 | break; 1633 | default: 1634 | src[i] = +value; 1635 | } 1636 | } else { 1637 | src[i] = value; 1638 | } 1639 | } else { 1640 | console.warn('unknown channel ' + channel + ' in mode ' + mode); 1641 | } 1642 | } else { 1643 | src = value; 1644 | } 1645 | me._rgb = chroma(src, mode).alpha(me.alpha())._rgb; 1646 | return me; 1647 | }; 1648 | 1649 | Color.prototype.darken = function(amount) { 1650 | var lab, me; 1651 | if (amount == null) { 1652 | amount = 1; 1653 | } 1654 | me = this; 1655 | lab = me.lab(); 1656 | lab[0] -= LAB_CONSTANTS.Kn * amount; 1657 | return chroma.lab(lab).alpha(me.alpha()); 1658 | }; 1659 | 1660 | Color.prototype.brighten = function(amount) { 1661 | if (amount == null) { 1662 | amount = 1; 1663 | } 1664 | return this.darken(-amount); 1665 | }; 1666 | 1667 | Color.prototype.darker = Color.prototype.darken; 1668 | 1669 | Color.prototype.brighter = Color.prototype.brighten; 1670 | 1671 | Color.prototype.saturate = function(amount) { 1672 | var lch, me; 1673 | if (amount == null) { 1674 | amount = 1; 1675 | } 1676 | me = this; 1677 | lch = me.lch(); 1678 | lch[1] += amount * LAB_CONSTANTS.Kn; 1679 | if (lch[1] < 0) { 1680 | lch[1] = 0; 1681 | } 1682 | return chroma.lch(lch).alpha(me.alpha()); 1683 | }; 1684 | 1685 | Color.prototype.desaturate = function(amount) { 1686 | if (amount == null) { 1687 | amount = 1; 1688 | } 1689 | return this.saturate(-amount); 1690 | }; 1691 | 1692 | Color.prototype.premultiply = function() { 1693 | var a, rgb; 1694 | rgb = this.rgb(); 1695 | a = this.alpha(); 1696 | return chroma(rgb[0] * a, rgb[1] * a, rgb[2] * a, a); 1697 | }; 1698 | 1699 | blend = function(bottom, top, mode) { 1700 | if (!blend[mode]) { 1701 | throw 'unknown blend mode ' + mode; 1702 | } 1703 | return blend[mode](bottom, top); 1704 | }; 1705 | 1706 | blend_f = function(f) { 1707 | return function(bottom, top) { 1708 | var c0, c1; 1709 | c0 = chroma(top).rgb(); 1710 | c1 = chroma(bottom).rgb(); 1711 | return chroma(f(c0, c1), 'rgb'); 1712 | }; 1713 | }; 1714 | 1715 | each = function(f) { 1716 | return function(c0, c1) { 1717 | var i, o, out; 1718 | out = []; 1719 | for (i = o = 0; o <= 3; i = ++o) { 1720 | out[i] = f(c0[i], c1[i]); 1721 | } 1722 | return out; 1723 | }; 1724 | }; 1725 | 1726 | normal = function(a, b) { 1727 | return a; 1728 | }; 1729 | 1730 | multiply = function(a, b) { 1731 | return a * b / 255; 1732 | }; 1733 | 1734 | darken = function(a, b) { 1735 | if (a > b) { 1736 | return b; 1737 | } else { 1738 | return a; 1739 | } 1740 | }; 1741 | 1742 | lighten = function(a, b) { 1743 | if (a > b) { 1744 | return a; 1745 | } else { 1746 | return b; 1747 | } 1748 | }; 1749 | 1750 | screen = function(a, b) { 1751 | return 255 * (1 - (1 - a / 255) * (1 - b / 255)); 1752 | }; 1753 | 1754 | overlay = function(a, b) { 1755 | if (b < 128) { 1756 | return 2 * a * b / 255; 1757 | } else { 1758 | return 255 * (1 - 2 * (1 - a / 255) * (1 - b / 255)); 1759 | } 1760 | }; 1761 | 1762 | burn = function(a, b) { 1763 | return 255 * (1 - (1 - b / 255) / (a / 255)); 1764 | }; 1765 | 1766 | dodge = function(a, b) { 1767 | if (a === 255) { 1768 | return 255; 1769 | } 1770 | a = 255 * (b / 255) / (1 - a / 255); 1771 | if (a > 255) { 1772 | return 255; 1773 | } else { 1774 | return a; 1775 | } 1776 | }; 1777 | 1778 | blend.normal = blend_f(each(normal)); 1779 | 1780 | blend.multiply = blend_f(each(multiply)); 1781 | 1782 | blend.screen = blend_f(each(screen)); 1783 | 1784 | blend.overlay = blend_f(each(overlay)); 1785 | 1786 | blend.darken = blend_f(each(darken)); 1787 | 1788 | blend.lighten = blend_f(each(lighten)); 1789 | 1790 | blend.dodge = blend_f(each(dodge)); 1791 | 1792 | blend.burn = blend_f(each(burn)); 1793 | 1794 | chroma.blend = blend; 1795 | 1796 | chroma.analyze = function(data) { 1797 | var len, o, r, val; 1798 | r = { 1799 | min: Number.MAX_VALUE, 1800 | max: Number.MAX_VALUE * -1, 1801 | sum: 0, 1802 | values: [], 1803 | count: 0 1804 | }; 1805 | for (o = 0, len = data.length; o < len; o++) { 1806 | val = data[o]; 1807 | if ((val != null) && !isNaN(val)) { 1808 | r.values.push(val); 1809 | r.sum += val; 1810 | if (val < r.min) { 1811 | r.min = val; 1812 | } 1813 | if (val > r.max) { 1814 | r.max = val; 1815 | } 1816 | r.count += 1; 1817 | } 1818 | } 1819 | r.domain = [r.min, r.max]; 1820 | r.limits = function(mode, num) { 1821 | return chroma.limits(r, mode, num); 1822 | }; 1823 | return r; 1824 | }; 1825 | 1826 | chroma.scale = function(colors, positions) { 1827 | var _classes, _colorCache, _colors, _correctLightness, _domain, _fixed, _max, _min, _mode, _nacol, _out, _padding, _pos, _spread, classifyValue, f, getClass, getColor, resetCache, setColors, tmap; 1828 | _mode = 'rgb'; 1829 | _nacol = chroma('#ccc'); 1830 | _spread = 0; 1831 | _fixed = false; 1832 | _domain = [0, 1]; 1833 | _pos = []; 1834 | _padding = [0, 0]; 1835 | _classes = false; 1836 | _colors = []; 1837 | _out = false; 1838 | _min = 0; 1839 | _max = 1; 1840 | _correctLightness = false; 1841 | _colorCache = {}; 1842 | setColors = function(colors) { 1843 | var c, col, o, ref, ref1, ref2, w; 1844 | if (colors == null) { 1845 | colors = ['#fff', '#000']; 1846 | } 1847 | if ((colors != null) && type(colors) === 'string' && (((ref = chroma.brewer) != null ? ref[colors] : void 0) != null)) { 1848 | colors = chroma.brewer[colors]; 1849 | } 1850 | if (type(colors) === 'array') { 1851 | colors = colors.slice(0); 1852 | for (c = o = 0, ref1 = colors.length - 1; 0 <= ref1 ? o <= ref1 : o >= ref1; c = 0 <= ref1 ? ++o : --o) { 1853 | col = colors[c]; 1854 | if (type(col) === "string") { 1855 | colors[c] = chroma(col); 1856 | } 1857 | } 1858 | _pos.length = 0; 1859 | for (c = w = 0, ref2 = colors.length - 1; 0 <= ref2 ? w <= ref2 : w >= ref2; c = 0 <= ref2 ? ++w : --w) { 1860 | _pos.push(c / (colors.length - 1)); 1861 | } 1862 | } 1863 | resetCache(); 1864 | return _colors = colors; 1865 | }; 1866 | getClass = function(value) { 1867 | var i, n; 1868 | if (_classes != null) { 1869 | n = _classes.length - 1; 1870 | i = 0; 1871 | while (i < n && value >= _classes[i]) { 1872 | i++; 1873 | } 1874 | return i - 1; 1875 | } 1876 | return 0; 1877 | }; 1878 | tmap = function(t) { 1879 | return t; 1880 | }; 1881 | classifyValue = function(value) { 1882 | var i, maxc, minc, n, val; 1883 | val = value; 1884 | if (_classes.length > 2) { 1885 | n = _classes.length - 1; 1886 | i = getClass(value); 1887 | minc = _classes[0] + (_classes[1] - _classes[0]) * (0 + _spread * 0.5); 1888 | maxc = _classes[n - 1] + (_classes[n] - _classes[n - 1]) * (1 - _spread * 0.5); 1889 | val = _min + ((_classes[i] + (_classes[i + 1] - _classes[i]) * 0.5 - minc) / (maxc - minc)) * (_max - _min); 1890 | } 1891 | return val; 1892 | }; 1893 | getColor = function(val, bypassMap) { 1894 | var c, col, i, k, o, p, ref, t; 1895 | if (bypassMap == null) { 1896 | bypassMap = false; 1897 | } 1898 | if (isNaN(val)) { 1899 | return _nacol; 1900 | } 1901 | if (!bypassMap) { 1902 | if (_classes && _classes.length > 2) { 1903 | c = getClass(val); 1904 | t = c / (_classes.length - 2); 1905 | t = _padding[0] + (t * (1 - _padding[0] - _padding[1])); 1906 | } else if (_max !== _min) { 1907 | t = (val - _min) / (_max - _min); 1908 | t = _padding[0] + (t * (1 - _padding[0] - _padding[1])); 1909 | t = Math.min(1, Math.max(0, t)); 1910 | } else { 1911 | t = 1; 1912 | } 1913 | } else { 1914 | t = val; 1915 | } 1916 | if (!bypassMap) { 1917 | t = tmap(t); 1918 | } 1919 | k = Math.floor(t * 10000); 1920 | if (_colorCache[k]) { 1921 | col = _colorCache[k]; 1922 | } else { 1923 | if (type(_colors) === 'array') { 1924 | for (i = o = 0, ref = _pos.length - 1; 0 <= ref ? o <= ref : o >= ref; i = 0 <= ref ? ++o : --o) { 1925 | p = _pos[i]; 1926 | if (t <= p) { 1927 | col = _colors[i]; 1928 | break; 1929 | } 1930 | if (t >= p && i === _pos.length - 1) { 1931 | col = _colors[i]; 1932 | break; 1933 | } 1934 | if (t > p && t < _pos[i + 1]) { 1935 | t = (t - p) / (_pos[i + 1] - p); 1936 | col = chroma.interpolate(_colors[i], _colors[i + 1], t, _mode); 1937 | break; 1938 | } 1939 | } 1940 | } else if (type(_colors) === 'function') { 1941 | col = _colors(t); 1942 | } 1943 | _colorCache[k] = col; 1944 | } 1945 | return col; 1946 | }; 1947 | resetCache = function() { 1948 | return _colorCache = {}; 1949 | }; 1950 | setColors(colors); 1951 | f = function(v) { 1952 | var c; 1953 | c = chroma(getColor(v)); 1954 | if (_out && c[_out]) { 1955 | return c[_out](); 1956 | } else { 1957 | return c; 1958 | } 1959 | }; 1960 | f.classes = function(classes) { 1961 | var d; 1962 | if (classes != null) { 1963 | if (type(classes) === 'array') { 1964 | _classes = classes; 1965 | _domain = [classes[0], classes[classes.length - 1]]; 1966 | } else { 1967 | d = chroma.analyze(_domain); 1968 | if (classes === 0) { 1969 | _classes = [d.min, d.max]; 1970 | } else { 1971 | _classes = chroma.limits(d, 'e', classes); 1972 | } 1973 | } 1974 | return f; 1975 | } 1976 | return _classes; 1977 | }; 1978 | f.domain = function(domain) { 1979 | var c, d, k, len, o, ref, w; 1980 | if (!arguments.length) { 1981 | return _domain; 1982 | } 1983 | _min = domain[0]; 1984 | _max = domain[domain.length - 1]; 1985 | _pos = []; 1986 | k = _colors.length; 1987 | if (domain.length === k && _min !== _max) { 1988 | for (o = 0, len = domain.length; o < len; o++) { 1989 | d = domain[o]; 1990 | _pos.push((d - _min) / (_max - _min)); 1991 | } 1992 | } else { 1993 | for (c = w = 0, ref = k - 1; 0 <= ref ? w <= ref : w >= ref; c = 0 <= ref ? ++w : --w) { 1994 | _pos.push(c / (k - 1)); 1995 | } 1996 | } 1997 | _domain = [_min, _max]; 1998 | return f; 1999 | }; 2000 | f.mode = function(_m) { 2001 | if (!arguments.length) { 2002 | return _mode; 2003 | } 2004 | _mode = _m; 2005 | resetCache(); 2006 | return f; 2007 | }; 2008 | f.range = function(colors, _pos) { 2009 | setColors(colors, _pos); 2010 | return f; 2011 | }; 2012 | f.out = function(_o) { 2013 | _out = _o; 2014 | return f; 2015 | }; 2016 | f.spread = function(val) { 2017 | if (!arguments.length) { 2018 | return _spread; 2019 | } 2020 | _spread = val; 2021 | return f; 2022 | }; 2023 | f.correctLightness = function(v) { 2024 | if (v == null) { 2025 | v = true; 2026 | } 2027 | _correctLightness = v; 2028 | resetCache(); 2029 | if (_correctLightness) { 2030 | tmap = function(t) { 2031 | var L0, L1, L_actual, L_diff, L_ideal, max_iter, pol, t0, t1; 2032 | L0 = getColor(0, true).lab()[0]; 2033 | L1 = getColor(1, true).lab()[0]; 2034 | pol = L0 > L1; 2035 | L_actual = getColor(t, true).lab()[0]; 2036 | L_ideal = L0 + (L1 - L0) * t; 2037 | L_diff = L_actual - L_ideal; 2038 | t0 = 0; 2039 | t1 = 1; 2040 | max_iter = 20; 2041 | while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) { 2042 | (function() { 2043 | if (pol) { 2044 | L_diff *= -1; 2045 | } 2046 | if (L_diff < 0) { 2047 | t0 = t; 2048 | t += (t1 - t) * 0.5; 2049 | } else { 2050 | t1 = t; 2051 | t += (t0 - t) * 0.5; 2052 | } 2053 | L_actual = getColor(t, true).lab()[0]; 2054 | return L_diff = L_actual - L_ideal; 2055 | })(); 2056 | } 2057 | return t; 2058 | }; 2059 | } else { 2060 | tmap = function(t) { 2061 | return t; 2062 | }; 2063 | } 2064 | return f; 2065 | }; 2066 | f.padding = function(p) { 2067 | if (p != null) { 2068 | if (type(p) === 'number') { 2069 | p = [p, p]; 2070 | } 2071 | _padding = p; 2072 | return f; 2073 | } else { 2074 | return _padding; 2075 | } 2076 | }; 2077 | f.colors = function() { 2078 | var dd, dm, i, numColors, o, out, ref, results, samples, w; 2079 | numColors = 0; 2080 | out = 'hex'; 2081 | if (arguments.length === 0) { 2082 | return _colors.map(function(c) { 2083 | return c[out](); 2084 | }); 2085 | } 2086 | if (arguments.length === 1) { 2087 | if (type(arguments[0]) === 'string') { 2088 | out = arguments[0]; 2089 | } else { 2090 | numColors = arguments[0]; 2091 | } 2092 | } 2093 | if (arguments.length === 2) { 2094 | numColors = arguments[0], out = arguments[1]; 2095 | } 2096 | if (numColors) { 2097 | dm = _domain[0]; 2098 | dd = _domain[1] - dm; 2099 | return (function() { 2100 | results = []; 2101 | for (var o = 0; 0 <= numColors ? o < numColors : o > numColors; 0 <= numColors ? o++ : o--){ results.push(o); } 2102 | return results; 2103 | }).apply(this).map(function(i) { 2104 | return f(dm + i / (numColors - 1) * dd)[out](); 2105 | }); 2106 | } 2107 | colors = []; 2108 | samples = []; 2109 | if (_classes && _classes.length > 2) { 2110 | for (i = w = 1, ref = _classes.length; 1 <= ref ? w < ref : w > ref; i = 1 <= ref ? ++w : --w) { 2111 | samples.push((_classes[i - 1] + _classes[i]) * 0.5); 2112 | } 2113 | } else { 2114 | samples = _domain; 2115 | } 2116 | return samples.map(function(v) { 2117 | return f(v)[out](); 2118 | }); 2119 | }; 2120 | return f; 2121 | }; 2122 | 2123 | if (chroma.scales == null) { 2124 | chroma.scales = {}; 2125 | } 2126 | 2127 | chroma.scales.cool = function() { 2128 | return chroma.scale([chroma.hsl(180, 1, .9), chroma.hsl(250, .7, .4)]); 2129 | }; 2130 | 2131 | chroma.scales.hot = function() { 2132 | return chroma.scale(['#000', '#f00', '#ff0', '#fff'], [0, .25, .75, 1]).mode('rgb'); 2133 | }; 2134 | 2135 | chroma.analyze = function(data, key, filter) { 2136 | var add, k, len, o, r, val, visit; 2137 | r = { 2138 | min: Number.MAX_VALUE, 2139 | max: Number.MAX_VALUE * -1, 2140 | sum: 0, 2141 | values: [], 2142 | count: 0 2143 | }; 2144 | if (filter == null) { 2145 | filter = function() { 2146 | return true; 2147 | }; 2148 | } 2149 | add = function(val) { 2150 | if ((val != null) && !isNaN(val)) { 2151 | r.values.push(val); 2152 | r.sum += val; 2153 | if (val < r.min) { 2154 | r.min = val; 2155 | } 2156 | if (val > r.max) { 2157 | r.max = val; 2158 | } 2159 | r.count += 1; 2160 | } 2161 | }; 2162 | visit = function(val, k) { 2163 | if (filter(val, k)) { 2164 | if ((key != null) && type(key) === 'function') { 2165 | return add(key(val)); 2166 | } else if ((key != null) && type(key) === 'string' || type(key) === 'number') { 2167 | return add(val[key]); 2168 | } else { 2169 | return add(val); 2170 | } 2171 | } 2172 | }; 2173 | if (type(data) === 'array') { 2174 | for (o = 0, len = data.length; o < len; o++) { 2175 | val = data[o]; 2176 | visit(val); 2177 | } 2178 | } else { 2179 | for (k in data) { 2180 | val = data[k]; 2181 | visit(val, k); 2182 | } 2183 | } 2184 | r.domain = [r.min, r.max]; 2185 | r.limits = function(mode, num) { 2186 | return chroma.limits(r, mode, num); 2187 | }; 2188 | return r; 2189 | }; 2190 | 2191 | chroma.limits = function(data, mode, num) { 2192 | var aa, ab, ac, ad, ae, af, ag, ah, ai, aj, ak, al, am, assignments, best, centroids, cluster, clusterSizes, dist, i, j, kClusters, limits, max_log, min, min_log, mindist, n, nb_iters, newCentroids, o, p, pb, pr, ref, ref1, ref10, ref11, ref12, ref13, ref14, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, repeat, sum, tmpKMeansBreaks, value, values, w; 2193 | if (mode == null) { 2194 | mode = 'equal'; 2195 | } 2196 | if (num == null) { 2197 | num = 7; 2198 | } 2199 | if (type(data) === 'array') { 2200 | data = chroma.analyze(data); 2201 | } 2202 | min = data.min; 2203 | max = data.max; 2204 | sum = data.sum; 2205 | values = data.values.sort(function(a, b) { 2206 | return a - b; 2207 | }); 2208 | limits = []; 2209 | if (mode.substr(0, 1) === 'c') { 2210 | limits.push(min); 2211 | limits.push(max); 2212 | } 2213 | if (mode.substr(0, 1) === 'e') { 2214 | limits.push(min); 2215 | for (i = o = 1, ref = num - 1; 1 <= ref ? o <= ref : o >= ref; i = 1 <= ref ? ++o : --o) { 2216 | limits.push(min + (i / num) * (max - min)); 2217 | } 2218 | limits.push(max); 2219 | } else if (mode.substr(0, 1) === 'l') { 2220 | if (min <= 0) { 2221 | throw 'Logarithmic scales are only possible for values > 0'; 2222 | } 2223 | min_log = Math.LOG10E * log(min); 2224 | max_log = Math.LOG10E * log(max); 2225 | limits.push(min); 2226 | for (i = w = 1, ref1 = num - 1; 1 <= ref1 ? w <= ref1 : w >= ref1; i = 1 <= ref1 ? ++w : --w) { 2227 | limits.push(pow(10, min_log + (i / num) * (max_log - min_log))); 2228 | } 2229 | limits.push(max); 2230 | } else if (mode.substr(0, 1) === 'q') { 2231 | limits.push(min); 2232 | for (i = aa = 1, ref2 = num - 1; 1 <= ref2 ? aa <= ref2 : aa >= ref2; i = 1 <= ref2 ? ++aa : --aa) { 2233 | p = values.length * i / num; 2234 | pb = floor(p); 2235 | if (pb === p) { 2236 | limits.push(values[pb]); 2237 | } else { 2238 | pr = p - pb; 2239 | limits.push(values[pb] * pr + values[pb + 1] * (1 - pr)); 2240 | } 2241 | } 2242 | limits.push(max); 2243 | } else if (mode.substr(0, 1) === 'k') { 2244 | 2245 | /* 2246 | implementation based on 2247 | http://code.google.com/p/figue/source/browse/trunk/figue.js#336 2248 | simplified for 1-d input values 2249 | */ 2250 | n = values.length; 2251 | assignments = new Array(n); 2252 | clusterSizes = new Array(num); 2253 | repeat = true; 2254 | nb_iters = 0; 2255 | centroids = null; 2256 | centroids = []; 2257 | centroids.push(min); 2258 | for (i = ab = 1, ref3 = num - 1; 1 <= ref3 ? ab <= ref3 : ab >= ref3; i = 1 <= ref3 ? ++ab : --ab) { 2259 | centroids.push(min + (i / num) * (max - min)); 2260 | } 2261 | centroids.push(max); 2262 | while (repeat) { 2263 | for (j = ac = 0, ref4 = num - 1; 0 <= ref4 ? ac <= ref4 : ac >= ref4; j = 0 <= ref4 ? ++ac : --ac) { 2264 | clusterSizes[j] = 0; 2265 | } 2266 | for (i = ad = 0, ref5 = n - 1; 0 <= ref5 ? ad <= ref5 : ad >= ref5; i = 0 <= ref5 ? ++ad : --ad) { 2267 | value = values[i]; 2268 | mindist = Number.MAX_VALUE; 2269 | for (j = ae = 0, ref6 = num - 1; 0 <= ref6 ? ae <= ref6 : ae >= ref6; j = 0 <= ref6 ? ++ae : --ae) { 2270 | dist = abs(centroids[j] - value); 2271 | if (dist < mindist) { 2272 | mindist = dist; 2273 | best = j; 2274 | } 2275 | } 2276 | clusterSizes[best]++; 2277 | assignments[i] = best; 2278 | } 2279 | newCentroids = new Array(num); 2280 | for (j = af = 0, ref7 = num - 1; 0 <= ref7 ? af <= ref7 : af >= ref7; j = 0 <= ref7 ? ++af : --af) { 2281 | newCentroids[j] = null; 2282 | } 2283 | for (i = ag = 0, ref8 = n - 1; 0 <= ref8 ? ag <= ref8 : ag >= ref8; i = 0 <= ref8 ? ++ag : --ag) { 2284 | cluster = assignments[i]; 2285 | if (newCentroids[cluster] === null) { 2286 | newCentroids[cluster] = values[i]; 2287 | } else { 2288 | newCentroids[cluster] += values[i]; 2289 | } 2290 | } 2291 | for (j = ah = 0, ref9 = num - 1; 0 <= ref9 ? ah <= ref9 : ah >= ref9; j = 0 <= ref9 ? ++ah : --ah) { 2292 | newCentroids[j] *= 1 / clusterSizes[j]; 2293 | } 2294 | repeat = false; 2295 | for (j = ai = 0, ref10 = num - 1; 0 <= ref10 ? ai <= ref10 : ai >= ref10; j = 0 <= ref10 ? ++ai : --ai) { 2296 | if (newCentroids[j] !== centroids[i]) { 2297 | repeat = true; 2298 | break; 2299 | } 2300 | } 2301 | centroids = newCentroids; 2302 | nb_iters++; 2303 | if (nb_iters > 200) { 2304 | repeat = false; 2305 | } 2306 | } 2307 | kClusters = {}; 2308 | for (j = aj = 0, ref11 = num - 1; 0 <= ref11 ? aj <= ref11 : aj >= ref11; j = 0 <= ref11 ? ++aj : --aj) { 2309 | kClusters[j] = []; 2310 | } 2311 | for (i = ak = 0, ref12 = n - 1; 0 <= ref12 ? ak <= ref12 : ak >= ref12; i = 0 <= ref12 ? ++ak : --ak) { 2312 | cluster = assignments[i]; 2313 | kClusters[cluster].push(values[i]); 2314 | } 2315 | tmpKMeansBreaks = []; 2316 | for (j = al = 0, ref13 = num - 1; 0 <= ref13 ? al <= ref13 : al >= ref13; j = 0 <= ref13 ? ++al : --al) { 2317 | tmpKMeansBreaks.push(kClusters[j][0]); 2318 | tmpKMeansBreaks.push(kClusters[j][kClusters[j].length - 1]); 2319 | } 2320 | tmpKMeansBreaks = tmpKMeansBreaks.sort(function(a, b) { 2321 | return a - b; 2322 | }); 2323 | limits.push(tmpKMeansBreaks[0]); 2324 | for (i = am = 1, ref14 = tmpKMeansBreaks.length - 1; am <= ref14; i = am += 2) { 2325 | if (!isNaN(tmpKMeansBreaks[i])) { 2326 | limits.push(tmpKMeansBreaks[i]); 2327 | } 2328 | } 2329 | } 2330 | return limits; 2331 | }; 2332 | 2333 | hsi2rgb = function(h, s, i) { 2334 | 2335 | /* 2336 | borrowed from here: 2337 | http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/hsi2rgb.cpp 2338 | */ 2339 | var args, b, g, r; 2340 | args = unpack(arguments); 2341 | h = args[0], s = args[1], i = args[2]; 2342 | h /= 360; 2343 | if (h < 1 / 3) { 2344 | b = (1 - s) / 3; 2345 | r = (1 + s * cos(TWOPI * h) / cos(PITHIRD - TWOPI * h)) / 3; 2346 | g = 1 - (b + r); 2347 | } else if (h < 2 / 3) { 2348 | h -= 1 / 3; 2349 | r = (1 - s) / 3; 2350 | g = (1 + s * cos(TWOPI * h) / cos(PITHIRD - TWOPI * h)) / 3; 2351 | b = 1 - (r + g); 2352 | } else { 2353 | h -= 2 / 3; 2354 | g = (1 - s) / 3; 2355 | b = (1 + s * cos(TWOPI * h) / cos(PITHIRD - TWOPI * h)) / 3; 2356 | r = 1 - (g + b); 2357 | } 2358 | r = limit(i * r * 3); 2359 | g = limit(i * g * 3); 2360 | b = limit(i * b * 3); 2361 | return [r * 255, g * 255, b * 255, args.length > 3 ? args[3] : 1]; 2362 | }; 2363 | 2364 | rgb2hsi = function() { 2365 | 2366 | /* 2367 | borrowed from here: 2368 | http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/rgb2hsi.cpp 2369 | */ 2370 | var b, g, h, i, min, r, ref, s; 2371 | ref = unpack(arguments), r = ref[0], g = ref[1], b = ref[2]; 2372 | TWOPI = Math.PI * 2; 2373 | r /= 255; 2374 | g /= 255; 2375 | b /= 255; 2376 | min = Math.min(r, g, b); 2377 | i = (r + g + b) / 3; 2378 | s = 1 - min / i; 2379 | if (s === 0) { 2380 | h = 0; 2381 | } else { 2382 | h = ((r - g) + (r - b)) / 2; 2383 | h /= Math.sqrt((r - g) * (r - g) + (r - b) * (g - b)); 2384 | h = Math.acos(h); 2385 | if (b > g) { 2386 | h = TWOPI - h; 2387 | } 2388 | h /= TWOPI; 2389 | } 2390 | return [h * 360, s, i]; 2391 | }; 2392 | 2393 | chroma.hsi = function() { 2394 | return (function(func, args, ctor) { 2395 | ctor.prototype = func.prototype; 2396 | var child = new ctor, result = func.apply(child, args); 2397 | return Object(result) === result ? result : child; 2398 | })(Color, slice.call(arguments).concat(['hsi']), function(){}); 2399 | }; 2400 | 2401 | _input.hsi = hsi2rgb; 2402 | 2403 | Color.prototype.hsi = function() { 2404 | return rgb2hsi(this._rgb); 2405 | }; 2406 | 2407 | interpolate_hsx = function(col1, col2, f, m) { 2408 | var dh, hue, hue0, hue1, lbv, lbv0, lbv1, res, sat, sat0, sat1, xyz0, xyz1; 2409 | if (m === 'hsl') { 2410 | xyz0 = col1.hsl(); 2411 | xyz1 = col2.hsl(); 2412 | } else if (m === 'hsv') { 2413 | xyz0 = col1.hsv(); 2414 | xyz1 = col2.hsv(); 2415 | } else if (m === 'hsi') { 2416 | xyz0 = col1.hsi(); 2417 | xyz1 = col2.hsi(); 2418 | } else if (m === 'lch' || m === 'hcl') { 2419 | m = 'hcl'; 2420 | xyz0 = col1.hcl(); 2421 | xyz1 = col2.hcl(); 2422 | } 2423 | if (m.substr(0, 1) === 'h') { 2424 | hue0 = xyz0[0], sat0 = xyz0[1], lbv0 = xyz0[2]; 2425 | hue1 = xyz1[0], sat1 = xyz1[1], lbv1 = xyz1[2]; 2426 | } 2427 | if (!isNaN(hue0) && !isNaN(hue1)) { 2428 | if (hue1 > hue0 && hue1 - hue0 > 180) { 2429 | dh = hue1 - (hue0 + 360); 2430 | } else if (hue1 < hue0 && hue0 - hue1 > 180) { 2431 | dh = hue1 + 360 - hue0; 2432 | } else { 2433 | dh = hue1 - hue0; 2434 | } 2435 | hue = hue0 + f * dh; 2436 | } else if (!isNaN(hue0)) { 2437 | hue = hue0; 2438 | if ((lbv1 === 1 || lbv1 === 0) && m !== 'hsv') { 2439 | sat = sat0; 2440 | } 2441 | } else if (!isNaN(hue1)) { 2442 | hue = hue1; 2443 | if ((lbv0 === 1 || lbv0 === 0) && m !== 'hsv') { 2444 | sat = sat1; 2445 | } 2446 | } else { 2447 | hue = Number.NaN; 2448 | } 2449 | if (sat == null) { 2450 | sat = sat0 + f * (sat1 - sat0); 2451 | } 2452 | lbv = lbv0 + f * (lbv1 - lbv0); 2453 | return res = chroma[m](hue, sat, lbv); 2454 | }; 2455 | 2456 | _interpolators = _interpolators.concat((function() { 2457 | var len, o, ref, results; 2458 | ref = ['hsv', 'hsl', 'hsi', 'hcl', 'lch']; 2459 | results = []; 2460 | for (o = 0, len = ref.length; o < len; o++) { 2461 | m = ref[o]; 2462 | results.push([m, interpolate_hsx]); 2463 | } 2464 | return results; 2465 | })()); 2466 | 2467 | interpolate_num = function(col1, col2, f, m) { 2468 | var n1, n2; 2469 | n1 = col1.num(); 2470 | n2 = col2.num(); 2471 | return chroma.num(n1 + (n2 - n1) * f, 'num'); 2472 | }; 2473 | 2474 | _interpolators.push(['num', interpolate_num]); 2475 | 2476 | interpolate_lab = function(col1, col2, f, m) { 2477 | var res, xyz0, xyz1; 2478 | xyz0 = col1.lab(); 2479 | xyz1 = col2.lab(); 2480 | return res = new Color(xyz0[0] + f * (xyz1[0] - xyz0[0]), xyz0[1] + f * (xyz1[1] - xyz0[1]), xyz0[2] + f * (xyz1[2] - xyz0[2]), m); 2481 | }; 2482 | 2483 | _interpolators.push(['lab', interpolate_lab]); 2484 | 2485 | }).call(this); 2486 | -------------------------------------------------------------------------------- /src/utils/contains.js: -------------------------------------------------------------------------------- 1 | function contains(root, n) { 2 | var node = n 3 | while (node) { 4 | if (node === root) { 5 | return true 6 | } 7 | node = node.parentNode 8 | } 9 | 10 | return false 11 | } 12 | 13 | export default contains -------------------------------------------------------------------------------- /src/utils/getBackground2d.js: -------------------------------------------------------------------------------- 1 | function getBackground2d (model, color) { 2 | 3 | let background = { 4 | 'r': `linear-gradient(to top right, rgba(${ Math.round(color[0]) },0,0,1),transparent, rgba(${ Math.round(color[0]) },255,255,1) ), 5 | linear-gradient(to bottom right, rgb(${ Math.round(color[0]) },255,0), rgb(${ Math.round(color[0]) },0,255) )`, 6 | 'g': `linear-gradient(to top right, rgba(0,${ Math.round(color[1]) },0,1),transparent, rgba(255,${ Math.round(color[1]) },255,1) ), 7 | linear-gradient(to bottom right, rgb(255,${ Math.round(color[1]) },0), rgb(0,${ Math.round(color[1]) },255) )`, 8 | 'b': `linear-gradient(to top right, rgba(0,0,${ Math.round(color[2]) },1),transparent, rgba(255,255,${ Math.round(color[2]) },1) ), 9 | linear-gradient(to bottom right, rgb(0,255,${ Math.round(color[2]) }), rgb(255,0,${ Math.round(color[2]) }) )`, 10 | 'h': `linear-gradient(to top, #000, transparent),linear-gradient(to right, #FFF, rgba(255,255,255,0)), 11 | linear-gradient(to top, hsl(${ color[0] }, 100%, 50%), hsl(${ color[0] }, 100%, 50%))`, 12 | 's': `linear-gradient(to top, #000, transparent), linear-gradient(rgba(255,255,255,${ 1-color[1] }), rgba(255,255,255,${ 1-color[1] })), 13 | linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)`, 14 | 'v': `linear-gradient(to top, rgba(0,0,0,${ 1-color[2] }), rgba(0,0,0,${ 1-color[2] })),linear-gradient(to top, #fff, transparent), 15 | linear-gradient(to right, #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%)` 16 | } 17 | 18 | return background[model] 19 | } 20 | 21 | export default getBackground2d -------------------------------------------------------------------------------- /src/utils/getTransparentBackground.js: -------------------------------------------------------------------------------- 1 | 2 | function getTransparentBackground(color = 'transparent', size = 6) { 3 | return { 4 | backgroundImage: `linear-gradient(${ color }, ${ color }), 5 | linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc), 6 | linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc)`, 7 | backgroundSize: `100% 100%,${ size*2 }px ${ size*2 }px,${ size*2 }px ${ size*2 }px`, 8 | backgroundPosition: `0 0,0 0, ${ size }px ${ size }px`, 9 | backgroundColor: '#fff' 10 | } 11 | } 12 | 13 | export default getTransparentBackground -------------------------------------------------------------------------------- /src/utils/hexToNumber.js: -------------------------------------------------------------------------------- 1 | function hexToNumber(v) { 2 | return parseInt(v.replace('#', ''), 16) 3 | } 4 | 5 | export default hexToNumber -------------------------------------------------------------------------------- /src/utils/materialColors.js: -------------------------------------------------------------------------------- 1 | const colors = [ 2 | [ 3 | ["50", "#FFEBEE"], 4 | ["100", "#FFCDD2"], 5 | ["200", "#EF9A9A"], 6 | ["300", "#E57373"], 7 | ["400", "#EF5350"], 8 | ["500", "#F44336"], 9 | ["600", "#E53935"], 10 | ["700", "#D32F2F"], 11 | ["800", "#C62828"], 12 | ["900", "#B71C1C"], 13 | ["A100", "#FF8A80"], 14 | ["A200", "#FF5252"], 15 | ["A400", "#FF1744"], 16 | ["A700", "#D50000"] 17 | ], 18 | [ 19 | ["50", "#FCE4EC"], 20 | ["100", "#F8BBD0"], 21 | ["200", "#F48FB1"], 22 | ["300", "#F06292"], 23 | ["400", "#EC407A"], 24 | ["500", "#E91E63"], 25 | ["600", "#D81B60"], 26 | ["700", "#C2185B"], 27 | ["800", "#AD1457"], 28 | ["900", "#880E4F"], 29 | ["A100", "#FF80AB"], 30 | ["A200", "#FF4081"], 31 | ["A400", "#F50057"], 32 | ["A700", "#C51162"] 33 | ], 34 | [ 35 | ["50", "#F3E5F5"], 36 | ["100", "#E1BEE7"], 37 | ["200", "#CE93D8"], 38 | ["300", "#BA68C8"], 39 | ["400", "#AB47BC"], 40 | ["500", "#9C27B0"], 41 | ["600", "#8E24AA"], 42 | ["700", "#7B1FA2"], 43 | ["800", "#6A1B9A"], 44 | ["900", "#4A148C"], 45 | ["A100", "#EA80FC"], 46 | ["A200", "#E040FB"], 47 | ["A400", "#D500F9"], 48 | ["A700", "#AA00FF"] 49 | ], 50 | [ 51 | ["50", "#EDE7F6"], 52 | ["100", "#D1C4E9"], 53 | ["200", "#B39DDB"], 54 | ["300", "#9575CD"], 55 | ["400", "#7E57C2"], 56 | ["500", "#673AB7"], 57 | ["600", "#5E35B1"], 58 | ["700", "#512DA8"], 59 | ["800", "#4527A0"], 60 | ["900", "#311B92"], 61 | ["A100", "#B388FF"], 62 | ["A200", "#7C4DFF"], 63 | ["A400", "#651FFF"], 64 | ["A700", "#6200EA"] 65 | ], 66 | [ 67 | ["50", "#E8EAF6"], 68 | ["100", "#C5CAE9"], 69 | ["200", "#9FA8DA"], 70 | ["300", "#7986CB"], 71 | ["400", "#5C6BC0"], 72 | ["500", "#3F51B5"], 73 | ["600", "#3949AB"], 74 | ["700", "#303F9F"], 75 | ["800", "#283593"], 76 | ["900", "#1A237E"], 77 | ["A100", "#8C9EFF"], 78 | ["A200", "#536DFE"], 79 | ["A400", "#3D5AFE"], 80 | ["A700", "#304FFE"] 81 | ], 82 | [ 83 | ["50", "#E3F2FD"], 84 | ["100", "#BBDEFB"], 85 | ["200", "#90CAF9"], 86 | ["300", "#64B5F6"], 87 | ["400", "#42A5F5"], 88 | ["500", "#2196F3"], 89 | ["600", "#1E88E5"], 90 | ["700", "#1976D2"], 91 | ["800", "#1565C0"], 92 | ["900", "#0D47A1"], 93 | ["A100", "#82B1FF"], 94 | ["A200", "#448AFF"], 95 | ["A400", "#2979FF"], 96 | ["A700", "#2962FF"] 97 | ], 98 | [ 99 | ["50", "#E1F5FE"], 100 | ["100", "#B3E5FC"], 101 | ["200", "#81D4FA"], 102 | ["300", "#4FC3F7"], 103 | ["400", "#29B6F6"], 104 | ["500", "#03A9F4"], 105 | ["600", "#039BE5"], 106 | ["700", "#0288D1"], 107 | ["800", "#0277BD"], 108 | ["900", "#01579B"], 109 | ["A100", "#80D8FF"], 110 | ["A200", "#40C4FF"], 111 | ["A400", "#00B0FF"], 112 | ["A700", "#0091EA"] 113 | ], 114 | [ 115 | ["50", "#E0F2F1"], 116 | ["100", "#B2DFDB"], 117 | ["200", "#80CBC4"], 118 | ["300", "#4DB6AC"], 119 | ["400", "#26A69A"], 120 | ["500", "#009688"], 121 | ["600", "#00897B"], 122 | ["700", "#00796B"], 123 | ["800", "#00695C"], 124 | ["900", "#004D40"], 125 | ["A100", "#A7FFEB"], 126 | ["A200", "#64FFDA"], 127 | ["A400", "#1DE9B6"], 128 | ["A700", "#00BFA5"] 129 | ], 130 | [ 131 | ["50", "#E0F7FA"], 132 | ["100", "#B2EBF2"], 133 | ["200", "#80DEEA"], 134 | ["300", "#4DD0E1"], 135 | ["400", "#26C6DA"], 136 | ["500", "#00BCD4"], 137 | ["600", "#00ACC1"], 138 | ["700", "#0097A7"], 139 | ["800", "#00838F"], 140 | ["900", "#006064"], 141 | ["A100", "#84FFFF"], 142 | ["A200", "#18FFFF"], 143 | ["A400", "#00E5FF"], 144 | ["A700", "#00B8D4"] 145 | ], 146 | [ 147 | ["50", "#E8F5E9"], 148 | ["100", "#C8E6C9"], 149 | ["200", "#A5D6A7"], 150 | ["300", "#81C784"], 151 | ["400", "#66BB6A"], 152 | ["500", "#4CAF50"], 153 | ["600", "#43A047"], 154 | ["700", "#388E3C"], 155 | ["800", "#2E7D32"], 156 | ["900", "#1B5E20"], 157 | ["A100", "#B9F6CA"], 158 | ["A200", "#69F0AE"], 159 | ["A400", "#00E676"], 160 | ["A700", "#00C853"] 161 | ], 162 | [ 163 | ["50", "#F1F8E9"], 164 | ["100", "#DCEDC8"], 165 | ["200", "#C5E1A5"], 166 | ["300", "#AED581"], 167 | ["400", "#9CCC65"], 168 | ["500", "#8BC34A"], 169 | ["600", "#7CB342"], 170 | ["700", "#689F38"], 171 | ["800", "#558B2F"], 172 | ["900", "#33691E"], 173 | ["A100", "#CCFF90"], 174 | ["A200", "#B2FF59"], 175 | ["A400", "#76FF03"], 176 | ["A700", "#64DD17"] 177 | ], 178 | [ 179 | ["50", "#F9FBE7"], 180 | ["100", "#F0F4C3"], 181 | ["200", "#E6EE9C"], 182 | ["300", "#DCE775"], 183 | ["400", "#D4E157"], 184 | ["500", "#CDDC39"], 185 | ["600", "#C0CA33"], 186 | ["700", "#AFB42B"], 187 | ["800", "#9E9D24"], 188 | ["900", "#827717"], 189 | ["A100", "#F4FF81"], 190 | ["A200", "#EEFF41"], 191 | ["A400", "#C6FF00"], 192 | ["A700", "#AEEA00"] 193 | ], 194 | [ 195 | ["50", "#FFFDE7"], 196 | ["100", "#FFF9C4"], 197 | ["200", "#FFF59D"], 198 | ["300", "#FFF176"], 199 | ["400", "#FFEE58"], 200 | ["500", "#FFEB3B"], 201 | ["600", "#FDD835"], 202 | ["700", "#FBC02D"], 203 | ["800", "#F9A825"], 204 | ["900", "#F57F17"], 205 | ["A100", "#FFFF8D"], 206 | ["A200", "#FFFF00"], 207 | ["A400", "#FFEA00"], 208 | ["A700", "#FFD600"] 209 | ], 210 | [ 211 | ["50", "#FFF8E1"], 212 | ["100", "#FFECB3"], 213 | ["200", "#FFE082"], 214 | ["300", "#FFD54F"], 215 | ["400", "#FFCA28"], 216 | ["500", "#FFC107"], 217 | ["600", "#FFB300"], 218 | ["700", "#FFA000"], 219 | ["800", "#FF8F00"], 220 | ["900", "#FF6F00"], 221 | ["A100", "#FFE57F"], 222 | ["A200", "#FFD740"], 223 | ["A400", "#FFC400"], 224 | ["A700", "#FFAB00"] 225 | ], 226 | [ 227 | ["50", "#FFF3E0"], 228 | ["100", "#FFE0B2"], 229 | ["200", "#FFCC80"], 230 | ["300", "#FFB74D"], 231 | ["400", "#FFA726"], 232 | ["500", "#FF9800"], 233 | ["600", "#FB8C00"], 234 | ["700", "#F57C00"], 235 | ["800", "#EF6C00"], 236 | ["900", "#E65100"], 237 | ["A100", "#FFD180"], 238 | ["A200", "#FFAB40"], 239 | ["A400", "#FF9100"], 240 | ["A700", "#FF6D00"] 241 | ], 242 | [ 243 | ["50", "#FBE9E7"], 244 | ["100", "#FFCCBC"], 245 | ["200", "#FFAB91"], 246 | ["300", "#FF8A65"], 247 | ["400", "#FF7043"], 248 | ["500", "#FF5722"], 249 | ["600", "#F4511E"], 250 | ["700", "#E64A19"], 251 | ["800", "#D84315"], 252 | ["900", "#BF360C"], 253 | ["A100", "#FF9E80"], 254 | ["A200", "#FF6E40"], 255 | ["A400", "#FF3D00"], 256 | ["A700", "#DD2C00"] 257 | ], 258 | [ 259 | ["50", "#FAFAFA"], 260 | ["100", "#F5F5F5"], 261 | ["200", "#EEEEEE"], 262 | ["300", "#E0E0E0"], 263 | ["400", "#BDBDBD"], 264 | ["500", "#9E9E9E"], 265 | ["600", "#757575"], 266 | ["700", "#616161"], 267 | ["800", "#424242"], 268 | ["900", "#212121"] 269 | ], 270 | [ 271 | ["50", "#ECEFF1"], 272 | ["100", "#CFD8DC"], 273 | ["200", "#B0BEC5"], 274 | ["300", "#90A4AE"], 275 | ["400", "#78909C"], 276 | ["500", "#607D8B"], 277 | ["600", "#546E7A"], 278 | ["700", "#455A64"], 279 | ["800", "#37474F"], 280 | ["900", "#263238"] 281 | ], 282 | [ 283 | ["50", "#EFEBE9"], 284 | ["100", "#D7CCC8"], 285 | ["200", "#BCAAA4"], 286 | ["300", "#A1887F"], 287 | ["400", "#8D6E63"], 288 | ["500", "#795548"], 289 | ["600", "#6D4C41"], 290 | ["700", "#5D4037"], 291 | ["800", "#4E342E"], 292 | ["900", "#3E2723"] 293 | ] 294 | ]; 295 | 296 | export default colors -------------------------------------------------------------------------------- /src/utils/numberTohex.js: -------------------------------------------------------------------------------- 1 | import padStart from './padStart' 2 | 3 | function numberToHex(v) { 4 | return '#' + padStart(Number(v).toString(16), 6, '0') 5 | } 6 | 7 | export default numberToHex -------------------------------------------------------------------------------- /src/utils/padStart.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | function padStart(str, targetLength, padString) { 5 | targetLength = targetLength>>0; //floor if number or convert non-number to 0; 6 | padString = String(padString || ' '); 7 | if (str.length > targetLength) { 8 | return String(str); 9 | } 10 | else { 11 | targetLength = targetLength-str.length; 12 | if (targetLength > padString.length) { 13 | padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed 14 | } 15 | return padString.slice(0,targetLength) + String(str); 16 | } 17 | }; 18 | 19 | export default padStart --------------------------------------------------------------------------------