@ppg_pl/tinting 0.0.0 → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -8
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{modal-header_10.cjs.entry.js → modal-header_9.cjs.entry.js} +9 -22
- package/dist/cjs/modal-header_9.cjs.entry.js.map +1 -0
- package/dist/cjs/tinting.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +0 -1
- package/dist/components/index10.js +3921 -9
- package/dist/components/index10.js.map +1 -1
- package/dist/components/my-component.js +9 -15
- package/dist/components/my-component.js.map +1 -1
- package/dist/components/my-modal.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{modal-header_10.entry.js → modal-header_9.entry.js} +10 -22
- package/dist/esm/modal-header_9.entry.js.map +1 -0
- package/dist/esm/tinting.js +1 -1
- package/dist/tinting/{p-06cd865b.entry.js → p-fa35b3ef.entry.js} +3 -3
- package/dist/tinting/p-fa35b3ef.entry.js.map +1 -0
- package/dist/tinting/tinting.esm.js +1 -1
- package/dist/tinting/tinting.esm.js.map +1 -1
- package/dist/types/components.d.ts +0 -13
- package/package.json +1 -1
- package/www/build/{p-06cd865b.entry.js → p-fa35b3ef.entry.js} +3 -3
- package/www/build/p-fa35b3ef.entry.js.map +1 -0
- package/www/build/tinting.esm.js +1 -1
- package/www/build/tinting.esm.js.map +1 -1
- package/www/index.html +1 -1
- package/dist/cjs/modal-header_10.cjs.entry.js.map +0 -1
- package/dist/collection/components/loader/index.css +0 -85
- package/dist/collection/components/loader/index.js +0 -19
- package/dist/collection/components/loader/index.js.map +0 -1
- package/dist/components/index11.js +0 -3949
- package/dist/components/index11.js.map +0 -1
- package/dist/components/my-loader.d.ts +0 -11
- package/dist/components/my-loader.js +0 -8
- package/dist/components/my-loader.js.map +0 -1
- package/dist/esm/modal-header_10.entry.js.map +0 -1
- package/dist/tinting/p-06cd865b.entry.js.map +0 -1
- package/dist/types/components/loader/index.d.ts +0 -3
- package/www/build/p-06cd865b.entry.js.map +0 -1
- package/www/build/p-a4907f5e.css +0 -4
- package/www/build/p-e2322b6c.js +0 -163
|
@@ -1,3949 +0,0 @@
|
|
|
1
|
-
import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
|
|
2
|
-
import { a as APIURL, b as accessToken } from './index5.js';
|
|
3
|
-
import { s as setDataLayer } from './gtmUtils.js';
|
|
4
|
-
import { u as updateFilters, f as fetchColors, l as limit$1, a as fetchProductData, d as defineCustomElement$7 } from './index2.js';
|
|
5
|
-
import { a as debounce, d as defineCustomElement$2 } from './index4.js';
|
|
6
|
-
import { d as defineCustomElement$6 } from './index7.js';
|
|
7
|
-
import { d as defineCustomElement$5 } from './index8.js';
|
|
8
|
-
import { d as defineCustomElement$4 } from './index10.js';
|
|
9
|
-
import { d as defineCustomElement$3 } from './index3.js';
|
|
10
|
-
import { d as defineCustomElement$1 } from './index9.js';
|
|
11
|
-
|
|
12
|
-
const { min: min$4, max: max$4 } = Math;
|
|
13
|
-
|
|
14
|
-
const limit = (x, low = 0, high = 1) => {
|
|
15
|
-
return min$4(max$4(low, x), high);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const clip_rgb = (rgb) => {
|
|
19
|
-
rgb._clipped = false;
|
|
20
|
-
rgb._unclipped = rgb.slice(0);
|
|
21
|
-
for (let i = 0; i <= 3; i++) {
|
|
22
|
-
if (i < 3) {
|
|
23
|
-
if (rgb[i] < 0 || rgb[i] > 255) rgb._clipped = true;
|
|
24
|
-
rgb[i] = limit(rgb[i], 0, 255);
|
|
25
|
-
} else if (i === 3) {
|
|
26
|
-
rgb[i] = limit(rgb[i], 0, 1);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return rgb;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// ported from jQuery's $.type
|
|
33
|
-
const classToType = {};
|
|
34
|
-
for (let name of [
|
|
35
|
-
'Boolean',
|
|
36
|
-
'Number',
|
|
37
|
-
'String',
|
|
38
|
-
'Function',
|
|
39
|
-
'Array',
|
|
40
|
-
'Date',
|
|
41
|
-
'RegExp',
|
|
42
|
-
'Undefined',
|
|
43
|
-
'Null'
|
|
44
|
-
]) {
|
|
45
|
-
classToType[`[object ${name}]`] = name.toLowerCase();
|
|
46
|
-
}
|
|
47
|
-
function type (obj) {
|
|
48
|
-
return classToType[Object.prototype.toString.call(obj)] || 'object';
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const unpack = (args, keyOrder = null) => {
|
|
52
|
-
// if called with more than 3 arguments, we return the arguments
|
|
53
|
-
if (args.length >= 3) return Array.prototype.slice.call(args);
|
|
54
|
-
// with less than 3 args we check if first arg is object
|
|
55
|
-
// and use the keyOrder string to extract and sort properties
|
|
56
|
-
if (type(args[0]) == 'object' && keyOrder) {
|
|
57
|
-
return keyOrder
|
|
58
|
-
.split('')
|
|
59
|
-
.filter((k) => args[0][k] !== undefined)
|
|
60
|
-
.map((k) => args[0][k]);
|
|
61
|
-
}
|
|
62
|
-
// otherwise we just return the first argument
|
|
63
|
-
// (which we suppose is an array of args)
|
|
64
|
-
return args[0].slice(0);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const last = (args) => {
|
|
68
|
-
if (args.length < 2) return null;
|
|
69
|
-
const l = args.length - 1;
|
|
70
|
-
if (type(args[l]) == 'string') return args[l].toLowerCase();
|
|
71
|
-
return null;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const { PI: PI$2, min: min$3, max: max$3 } = Math;
|
|
75
|
-
|
|
76
|
-
const rnd2 = (a) => Math.round(a * 100) / 100;
|
|
77
|
-
const rnd3 = (a) => Math.round(a * 100) / 100;
|
|
78
|
-
|
|
79
|
-
const TWOPI = PI$2 * 2;
|
|
80
|
-
const PITHIRD = PI$2 / 3;
|
|
81
|
-
const DEG2RAD = PI$2 / 180;
|
|
82
|
-
const RAD2DEG = 180 / PI$2;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Reverse the first three elements of an array
|
|
86
|
-
*
|
|
87
|
-
* @param {any[]} arr
|
|
88
|
-
* @returns {any[]}
|
|
89
|
-
*/
|
|
90
|
-
function reverse3(arr) {
|
|
91
|
-
return [...arr.slice(0, 3).reverse(), ...arr.slice(3)];
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const input = {
|
|
95
|
-
format: {},
|
|
96
|
-
autodetect: []
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
class Color {
|
|
100
|
-
constructor(...args) {
|
|
101
|
-
const me = this;
|
|
102
|
-
if (
|
|
103
|
-
type(args[0]) === 'object' &&
|
|
104
|
-
args[0].constructor &&
|
|
105
|
-
args[0].constructor === this.constructor
|
|
106
|
-
) {
|
|
107
|
-
// the argument is already a Color instance
|
|
108
|
-
return args[0];
|
|
109
|
-
}
|
|
110
|
-
// last argument could be the mode
|
|
111
|
-
let mode = last(args);
|
|
112
|
-
let autodetect = false;
|
|
113
|
-
if (!mode) {
|
|
114
|
-
autodetect = true;
|
|
115
|
-
|
|
116
|
-
if (!input.sorted) {
|
|
117
|
-
input.autodetect = input.autodetect.sort((a, b) => b.p - a.p);
|
|
118
|
-
input.sorted = true;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// auto-detect format
|
|
122
|
-
for (let chk of input.autodetect) {
|
|
123
|
-
mode = chk.test(...args);
|
|
124
|
-
if (mode) break;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
if (input.format[mode]) {
|
|
128
|
-
const rgb = input.format[mode].apply(
|
|
129
|
-
null,
|
|
130
|
-
autodetect ? args : args.slice(0, -1)
|
|
131
|
-
);
|
|
132
|
-
me._rgb = clip_rgb(rgb);
|
|
133
|
-
} else {
|
|
134
|
-
throw new Error('unknown format: ' + args);
|
|
135
|
-
}
|
|
136
|
-
// add alpha channel
|
|
137
|
-
if (me._rgb.length === 3) me._rgb.push(1);
|
|
138
|
-
}
|
|
139
|
-
toString() {
|
|
140
|
-
if (type(this.hex) == 'function') return this.hex();
|
|
141
|
-
return `[${this._rgb.join(',')}]`;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// this gets updated automatically
|
|
146
|
-
const version = '3.1.2';
|
|
147
|
-
|
|
148
|
-
const chroma = (...args) => {
|
|
149
|
-
return new Color(...args);
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
chroma.version = version;
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
X11 color names
|
|
156
|
-
|
|
157
|
-
http://www.w3.org/TR/css3-color/#svg-color
|
|
158
|
-
*/
|
|
159
|
-
|
|
160
|
-
const w3cx11 = {
|
|
161
|
-
aliceblue: '#f0f8ff',
|
|
162
|
-
antiquewhite: '#faebd7',
|
|
163
|
-
aqua: '#00ffff',
|
|
164
|
-
aquamarine: '#7fffd4',
|
|
165
|
-
azure: '#f0ffff',
|
|
166
|
-
beige: '#f5f5dc',
|
|
167
|
-
bisque: '#ffe4c4',
|
|
168
|
-
black: '#000000',
|
|
169
|
-
blanchedalmond: '#ffebcd',
|
|
170
|
-
blue: '#0000ff',
|
|
171
|
-
blueviolet: '#8a2be2',
|
|
172
|
-
brown: '#a52a2a',
|
|
173
|
-
burlywood: '#deb887',
|
|
174
|
-
cadetblue: '#5f9ea0',
|
|
175
|
-
chartreuse: '#7fff00',
|
|
176
|
-
chocolate: '#d2691e',
|
|
177
|
-
coral: '#ff7f50',
|
|
178
|
-
cornflowerblue: '#6495ed',
|
|
179
|
-
cornsilk: '#fff8dc',
|
|
180
|
-
crimson: '#dc143c',
|
|
181
|
-
cyan: '#00ffff',
|
|
182
|
-
darkblue: '#00008b',
|
|
183
|
-
darkcyan: '#008b8b',
|
|
184
|
-
darkgoldenrod: '#b8860b',
|
|
185
|
-
darkgray: '#a9a9a9',
|
|
186
|
-
darkgreen: '#006400',
|
|
187
|
-
darkgrey: '#a9a9a9',
|
|
188
|
-
darkkhaki: '#bdb76b',
|
|
189
|
-
darkmagenta: '#8b008b',
|
|
190
|
-
darkolivegreen: '#556b2f',
|
|
191
|
-
darkorange: '#ff8c00',
|
|
192
|
-
darkorchid: '#9932cc',
|
|
193
|
-
darkred: '#8b0000',
|
|
194
|
-
darksalmon: '#e9967a',
|
|
195
|
-
darkseagreen: '#8fbc8f',
|
|
196
|
-
darkslateblue: '#483d8b',
|
|
197
|
-
darkslategray: '#2f4f4f',
|
|
198
|
-
darkslategrey: '#2f4f4f',
|
|
199
|
-
darkturquoise: '#00ced1',
|
|
200
|
-
darkviolet: '#9400d3',
|
|
201
|
-
deeppink: '#ff1493',
|
|
202
|
-
deepskyblue: '#00bfff',
|
|
203
|
-
dimgray: '#696969',
|
|
204
|
-
dimgrey: '#696969',
|
|
205
|
-
dodgerblue: '#1e90ff',
|
|
206
|
-
firebrick: '#b22222',
|
|
207
|
-
floralwhite: '#fffaf0',
|
|
208
|
-
forestgreen: '#228b22',
|
|
209
|
-
fuchsia: '#ff00ff',
|
|
210
|
-
gainsboro: '#dcdcdc',
|
|
211
|
-
ghostwhite: '#f8f8ff',
|
|
212
|
-
gold: '#ffd700',
|
|
213
|
-
goldenrod: '#daa520',
|
|
214
|
-
gray: '#808080',
|
|
215
|
-
green: '#008000',
|
|
216
|
-
greenyellow: '#adff2f',
|
|
217
|
-
grey: '#808080',
|
|
218
|
-
honeydew: '#f0fff0',
|
|
219
|
-
hotpink: '#ff69b4',
|
|
220
|
-
indianred: '#cd5c5c',
|
|
221
|
-
indigo: '#4b0082',
|
|
222
|
-
ivory: '#fffff0',
|
|
223
|
-
khaki: '#f0e68c',
|
|
224
|
-
laserlemon: '#ffff54',
|
|
225
|
-
lavender: '#e6e6fa',
|
|
226
|
-
lavenderblush: '#fff0f5',
|
|
227
|
-
lawngreen: '#7cfc00',
|
|
228
|
-
lemonchiffon: '#fffacd',
|
|
229
|
-
lightblue: '#add8e6',
|
|
230
|
-
lightcoral: '#f08080',
|
|
231
|
-
lightcyan: '#e0ffff',
|
|
232
|
-
lightgoldenrod: '#fafad2',
|
|
233
|
-
lightgoldenrodyellow: '#fafad2',
|
|
234
|
-
lightgray: '#d3d3d3',
|
|
235
|
-
lightgreen: '#90ee90',
|
|
236
|
-
lightgrey: '#d3d3d3',
|
|
237
|
-
lightpink: '#ffb6c1',
|
|
238
|
-
lightsalmon: '#ffa07a',
|
|
239
|
-
lightseagreen: '#20b2aa',
|
|
240
|
-
lightskyblue: '#87cefa',
|
|
241
|
-
lightslategray: '#778899',
|
|
242
|
-
lightslategrey: '#778899',
|
|
243
|
-
lightsteelblue: '#b0c4de',
|
|
244
|
-
lightyellow: '#ffffe0',
|
|
245
|
-
lime: '#00ff00',
|
|
246
|
-
limegreen: '#32cd32',
|
|
247
|
-
linen: '#faf0e6',
|
|
248
|
-
magenta: '#ff00ff',
|
|
249
|
-
maroon: '#800000',
|
|
250
|
-
maroon2: '#7f0000',
|
|
251
|
-
maroon3: '#b03060',
|
|
252
|
-
mediumaquamarine: '#66cdaa',
|
|
253
|
-
mediumblue: '#0000cd',
|
|
254
|
-
mediumorchid: '#ba55d3',
|
|
255
|
-
mediumpurple: '#9370db',
|
|
256
|
-
mediumseagreen: '#3cb371',
|
|
257
|
-
mediumslateblue: '#7b68ee',
|
|
258
|
-
mediumspringgreen: '#00fa9a',
|
|
259
|
-
mediumturquoise: '#48d1cc',
|
|
260
|
-
mediumvioletred: '#c71585',
|
|
261
|
-
midnightblue: '#191970',
|
|
262
|
-
mintcream: '#f5fffa',
|
|
263
|
-
mistyrose: '#ffe4e1',
|
|
264
|
-
moccasin: '#ffe4b5',
|
|
265
|
-
navajowhite: '#ffdead',
|
|
266
|
-
navy: '#000080',
|
|
267
|
-
oldlace: '#fdf5e6',
|
|
268
|
-
olive: '#808000',
|
|
269
|
-
olivedrab: '#6b8e23',
|
|
270
|
-
orange: '#ffa500',
|
|
271
|
-
orangered: '#ff4500',
|
|
272
|
-
orchid: '#da70d6',
|
|
273
|
-
palegoldenrod: '#eee8aa',
|
|
274
|
-
palegreen: '#98fb98',
|
|
275
|
-
paleturquoise: '#afeeee',
|
|
276
|
-
palevioletred: '#db7093',
|
|
277
|
-
papayawhip: '#ffefd5',
|
|
278
|
-
peachpuff: '#ffdab9',
|
|
279
|
-
peru: '#cd853f',
|
|
280
|
-
pink: '#ffc0cb',
|
|
281
|
-
plum: '#dda0dd',
|
|
282
|
-
powderblue: '#b0e0e6',
|
|
283
|
-
purple: '#800080',
|
|
284
|
-
purple2: '#7f007f',
|
|
285
|
-
purple3: '#a020f0',
|
|
286
|
-
rebeccapurple: '#663399',
|
|
287
|
-
red: '#ff0000',
|
|
288
|
-
rosybrown: '#bc8f8f',
|
|
289
|
-
royalblue: '#4169e1',
|
|
290
|
-
saddlebrown: '#8b4513',
|
|
291
|
-
salmon: '#fa8072',
|
|
292
|
-
sandybrown: '#f4a460',
|
|
293
|
-
seagreen: '#2e8b57',
|
|
294
|
-
seashell: '#fff5ee',
|
|
295
|
-
sienna: '#a0522d',
|
|
296
|
-
silver: '#c0c0c0',
|
|
297
|
-
skyblue: '#87ceeb',
|
|
298
|
-
slateblue: '#6a5acd',
|
|
299
|
-
slategray: '#708090',
|
|
300
|
-
slategrey: '#708090',
|
|
301
|
-
snow: '#fffafa',
|
|
302
|
-
springgreen: '#00ff7f',
|
|
303
|
-
steelblue: '#4682b4',
|
|
304
|
-
tan: '#d2b48c',
|
|
305
|
-
teal: '#008080',
|
|
306
|
-
thistle: '#d8bfd8',
|
|
307
|
-
tomato: '#ff6347',
|
|
308
|
-
turquoise: '#40e0d0',
|
|
309
|
-
violet: '#ee82ee',
|
|
310
|
-
wheat: '#f5deb3',
|
|
311
|
-
white: '#ffffff',
|
|
312
|
-
whitesmoke: '#f5f5f5',
|
|
313
|
-
yellow: '#ffff00',
|
|
314
|
-
yellowgreen: '#9acd32'
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
const RE_HEX = /^#?([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
|
|
318
|
-
const RE_HEXA = /^#?([A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/;
|
|
319
|
-
|
|
320
|
-
const hex2rgb = (hex) => {
|
|
321
|
-
if (hex.match(RE_HEX)) {
|
|
322
|
-
// remove optional leading #
|
|
323
|
-
if (hex.length === 4 || hex.length === 7) {
|
|
324
|
-
hex = hex.substr(1);
|
|
325
|
-
}
|
|
326
|
-
// expand short-notation to full six-digit
|
|
327
|
-
if (hex.length === 3) {
|
|
328
|
-
hex = hex.split('');
|
|
329
|
-
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
|
330
|
-
}
|
|
331
|
-
const u = parseInt(hex, 16);
|
|
332
|
-
const r = u >> 16;
|
|
333
|
-
const g = (u >> 8) & 0xff;
|
|
334
|
-
const b = u & 0xff;
|
|
335
|
-
return [r, g, b, 1];
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// match rgba hex format, eg #FF000077
|
|
339
|
-
if (hex.match(RE_HEXA)) {
|
|
340
|
-
if (hex.length === 5 || hex.length === 9) {
|
|
341
|
-
// remove optional leading #
|
|
342
|
-
hex = hex.substr(1);
|
|
343
|
-
}
|
|
344
|
-
// expand short-notation to full eight-digit
|
|
345
|
-
if (hex.length === 4) {
|
|
346
|
-
hex = hex.split('');
|
|
347
|
-
hex =
|
|
348
|
-
hex[0] +
|
|
349
|
-
hex[0] +
|
|
350
|
-
hex[1] +
|
|
351
|
-
hex[1] +
|
|
352
|
-
hex[2] +
|
|
353
|
-
hex[2] +
|
|
354
|
-
hex[3] +
|
|
355
|
-
hex[3];
|
|
356
|
-
}
|
|
357
|
-
const u = parseInt(hex, 16);
|
|
358
|
-
const r = (u >> 24) & 0xff;
|
|
359
|
-
const g = (u >> 16) & 0xff;
|
|
360
|
-
const b = (u >> 8) & 0xff;
|
|
361
|
-
const a = Math.round(((u & 0xff) / 0xff) * 100) / 100;
|
|
362
|
-
return [r, g, b, a];
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// we used to check for css colors here
|
|
366
|
-
// if _input.css? and rgb = _input.css hex
|
|
367
|
-
// return rgb
|
|
368
|
-
|
|
369
|
-
throw new Error(`unknown hex color: ${hex}`);
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
const { round: round$5 } = Math;
|
|
373
|
-
|
|
374
|
-
const rgb2hex = (...args) => {
|
|
375
|
-
let [r, g, b, a] = unpack(args, 'rgba');
|
|
376
|
-
let mode = last(args) || 'auto';
|
|
377
|
-
if (a === undefined) a = 1;
|
|
378
|
-
if (mode === 'auto') {
|
|
379
|
-
mode = a < 1 ? 'rgba' : 'rgb';
|
|
380
|
-
}
|
|
381
|
-
r = round$5(r);
|
|
382
|
-
g = round$5(g);
|
|
383
|
-
b = round$5(b);
|
|
384
|
-
const u = (r << 16) | (g << 8) | b;
|
|
385
|
-
let str = '000000' + u.toString(16); //#.toUpperCase();
|
|
386
|
-
str = str.substr(str.length - 6);
|
|
387
|
-
let hxa = '0' + round$5(a * 255).toString(16);
|
|
388
|
-
hxa = hxa.substr(hxa.length - 2);
|
|
389
|
-
switch (mode.toLowerCase()) {
|
|
390
|
-
case 'rgba':
|
|
391
|
-
return `#${str}${hxa}`;
|
|
392
|
-
case 'argb':
|
|
393
|
-
return `#${hxa}${str}`;
|
|
394
|
-
default:
|
|
395
|
-
return `#${str}`;
|
|
396
|
-
}
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
Color.prototype.name = function () {
|
|
400
|
-
const hex = rgb2hex(this._rgb, 'rgb');
|
|
401
|
-
for (let n of Object.keys(w3cx11)) {
|
|
402
|
-
if (w3cx11[n] === hex) return n.toLowerCase();
|
|
403
|
-
}
|
|
404
|
-
return hex;
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
input.format.named = (name) => {
|
|
408
|
-
name = name.toLowerCase();
|
|
409
|
-
if (w3cx11[name]) return hex2rgb(w3cx11[name]);
|
|
410
|
-
throw new Error('unknown color name: ' + name);
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
input.autodetect.push({
|
|
414
|
-
p: 5,
|
|
415
|
-
test: (h, ...rest) => {
|
|
416
|
-
if (!rest.length && type(h) === 'string' && w3cx11[h.toLowerCase()]) {
|
|
417
|
-
return 'named';
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
Color.prototype.alpha = function (a, mutate = false) {
|
|
423
|
-
if (a !== undefined && type(a) === 'number') {
|
|
424
|
-
if (mutate) {
|
|
425
|
-
this._rgb[3] = a;
|
|
426
|
-
return this;
|
|
427
|
-
}
|
|
428
|
-
return new Color([this._rgb[0], this._rgb[1], this._rgb[2], a], 'rgb');
|
|
429
|
-
}
|
|
430
|
-
return this._rgb[3];
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
Color.prototype.clipped = function () {
|
|
434
|
-
return this._rgb._clipped || false;
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
const labConstants = {
|
|
438
|
-
// Corresponds roughly to RGB brighter/darker
|
|
439
|
-
Kn: 18,
|
|
440
|
-
|
|
441
|
-
// D65 standard referent
|
|
442
|
-
labWhitePoint: 'd65',
|
|
443
|
-
Xn: 0.95047,
|
|
444
|
-
Yn: 1,
|
|
445
|
-
Zn: 1.08883,
|
|
446
|
-
|
|
447
|
-
t0: 0.137931034, // 4 / 29
|
|
448
|
-
t1: 0.206896552, // 6 / 29
|
|
449
|
-
t2: 0.12841855, // 3 * t1 * t1
|
|
450
|
-
t3: 0.008856452, // t1 * t1 * t1,
|
|
451
|
-
|
|
452
|
-
kE: 216.0 / 24389.0,
|
|
453
|
-
kKE: 8.0,
|
|
454
|
-
kK: 24389.0 / 27.0,
|
|
455
|
-
|
|
456
|
-
RefWhiteRGB: {
|
|
457
|
-
// sRGB
|
|
458
|
-
X: 0.95047,
|
|
459
|
-
Y: 1,
|
|
460
|
-
Z: 1.08883
|
|
461
|
-
},
|
|
462
|
-
|
|
463
|
-
MtxRGB2XYZ: {
|
|
464
|
-
m00: 0.4124564390896922,
|
|
465
|
-
m01: 0.21267285140562253,
|
|
466
|
-
m02: 0.0193338955823293,
|
|
467
|
-
m10: 0.357576077643909,
|
|
468
|
-
m11: 0.715152155287818,
|
|
469
|
-
m12: 0.11919202588130297,
|
|
470
|
-
m20: 0.18043748326639894,
|
|
471
|
-
m21: 0.07217499330655958,
|
|
472
|
-
m22: 0.9503040785363679
|
|
473
|
-
},
|
|
474
|
-
|
|
475
|
-
MtxXYZ2RGB: {
|
|
476
|
-
m00: 3.2404541621141045,
|
|
477
|
-
m01: -0.9692660305051868,
|
|
478
|
-
m02: 0.055643430959114726,
|
|
479
|
-
m10: -1.5371385127977166,
|
|
480
|
-
m11: 1.8760108454466942,
|
|
481
|
-
m12: -0.2040259135167538,
|
|
482
|
-
m20: -0.498531409556016,
|
|
483
|
-
m21: 0.041556017530349834,
|
|
484
|
-
m22: 1.0572251882231791
|
|
485
|
-
},
|
|
486
|
-
|
|
487
|
-
// used in rgb2xyz
|
|
488
|
-
As: 0.9414285350000001,
|
|
489
|
-
Bs: 1.040417467,
|
|
490
|
-
Cs: 1.089532651,
|
|
491
|
-
|
|
492
|
-
MtxAdaptMa: {
|
|
493
|
-
m00: 0.8951,
|
|
494
|
-
m01: -0.7502,
|
|
495
|
-
m02: 0.0389,
|
|
496
|
-
m10: 0.2664,
|
|
497
|
-
m11: 1.7135,
|
|
498
|
-
m12: -0.0685,
|
|
499
|
-
m20: -0.1614,
|
|
500
|
-
m21: 0.0367,
|
|
501
|
-
m22: 1.0296
|
|
502
|
-
},
|
|
503
|
-
|
|
504
|
-
MtxAdaptMaI: {
|
|
505
|
-
m00: 0.9869929054667123,
|
|
506
|
-
m01: 0.43230526972339456,
|
|
507
|
-
m02: -0.008528664575177328,
|
|
508
|
-
m10: -0.14705425642099013,
|
|
509
|
-
m11: 0.5183602715367776,
|
|
510
|
-
m12: 0.04004282165408487,
|
|
511
|
-
m20: 0.15996265166373125,
|
|
512
|
-
m21: 0.0492912282128556,
|
|
513
|
-
m22: 0.9684866957875502
|
|
514
|
-
}
|
|
515
|
-
};
|
|
516
|
-
|
|
517
|
-
// taken from https://de.mathworks.com/help/images/ref/whitepoint.html
|
|
518
|
-
const ILLUMINANTS = new Map([
|
|
519
|
-
// ASTM E308-01
|
|
520
|
-
['a', [1.0985, 0.35585]],
|
|
521
|
-
// Wyszecki & Stiles, p. 769
|
|
522
|
-
['b', [1.0985, 0.35585]],
|
|
523
|
-
// C ASTM E308-01
|
|
524
|
-
['c', [0.98074, 1.18232]],
|
|
525
|
-
// D50 (ASTM E308-01)
|
|
526
|
-
['d50', [0.96422, 0.82521]],
|
|
527
|
-
// D55 (ASTM E308-01)
|
|
528
|
-
['d55', [0.95682, 0.92149]],
|
|
529
|
-
// D65 (ASTM E308-01)
|
|
530
|
-
['d65', [0.95047, 1.08883]],
|
|
531
|
-
// E (ASTM E308-01)
|
|
532
|
-
['e', [1, 1, 1]],
|
|
533
|
-
// F2 (ASTM E308-01)
|
|
534
|
-
['f2', [0.99186, 0.67393]],
|
|
535
|
-
// F7 (ASTM E308-01)
|
|
536
|
-
['f7', [0.95041, 1.08747]],
|
|
537
|
-
// F11 (ASTM E308-01)
|
|
538
|
-
['f11', [1.00962, 0.6435]],
|
|
539
|
-
['icc', [0.96422, 0.82521]]
|
|
540
|
-
]);
|
|
541
|
-
|
|
542
|
-
function setLabWhitePoint(name) {
|
|
543
|
-
const ill = ILLUMINANTS.get(String(name).toLowerCase());
|
|
544
|
-
if (!ill) {
|
|
545
|
-
throw new Error('unknown Lab illuminant ' + name);
|
|
546
|
-
}
|
|
547
|
-
labConstants.labWhitePoint = name;
|
|
548
|
-
labConstants.Xn = ill[0];
|
|
549
|
-
labConstants.Zn = ill[1];
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
function getLabWhitePoint() {
|
|
553
|
-
return labConstants.labWhitePoint;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
/*
|
|
557
|
-
* L* [0..100]
|
|
558
|
-
* a [-100..100]
|
|
559
|
-
* b [-100..100]
|
|
560
|
-
*/
|
|
561
|
-
const lab2rgb = (...args) => {
|
|
562
|
-
args = unpack(args, 'lab');
|
|
563
|
-
const [L, a, b] = args;
|
|
564
|
-
const [x, y, z] = lab2xyz(L, a, b);
|
|
565
|
-
const [r, g, b_] = xyz2rgb(x, y, z);
|
|
566
|
-
return [r, g, b_, args.length > 3 ? args[3] : 1];
|
|
567
|
-
};
|
|
568
|
-
|
|
569
|
-
const lab2xyz = (L, a, b) => {
|
|
570
|
-
const { kE, kK, kKE, Xn, Yn, Zn } = labConstants;
|
|
571
|
-
|
|
572
|
-
const fy = (L + 16.0) / 116.0;
|
|
573
|
-
const fx = 0.002 * a + fy;
|
|
574
|
-
const fz = fy - 0.005 * b;
|
|
575
|
-
|
|
576
|
-
const fx3 = fx * fx * fx;
|
|
577
|
-
const fz3 = fz * fz * fz;
|
|
578
|
-
|
|
579
|
-
const xr = fx3 > kE ? fx3 : (116.0 * fx - 16.0) / kK;
|
|
580
|
-
const yr = L > kKE ? Math.pow((L + 16.0) / 116.0, 3.0) : L / kK;
|
|
581
|
-
const zr = fz3 > kE ? fz3 : (116.0 * fz - 16.0) / kK;
|
|
582
|
-
|
|
583
|
-
const x = xr * Xn;
|
|
584
|
-
const y = yr * Yn;
|
|
585
|
-
const z = zr * Zn;
|
|
586
|
-
|
|
587
|
-
return [x, y, z];
|
|
588
|
-
};
|
|
589
|
-
|
|
590
|
-
const compand = (linear) => {
|
|
591
|
-
/* sRGB */
|
|
592
|
-
const sign = Math.sign(linear);
|
|
593
|
-
linear = Math.abs(linear);
|
|
594
|
-
return (
|
|
595
|
-
(linear <= 0.0031308
|
|
596
|
-
? linear * 12.92
|
|
597
|
-
: 1.055 * Math.pow(linear, 1.0 / 2.4) - 0.055) * sign
|
|
598
|
-
);
|
|
599
|
-
};
|
|
600
|
-
|
|
601
|
-
const xyz2rgb = (x, y, z) => {
|
|
602
|
-
const { MtxAdaptMa, MtxAdaptMaI, MtxXYZ2RGB, RefWhiteRGB, Xn, Yn, Zn } =
|
|
603
|
-
labConstants;
|
|
604
|
-
|
|
605
|
-
const As = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
|
|
606
|
-
const Bs = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
|
|
607
|
-
const Cs = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
|
|
608
|
-
|
|
609
|
-
const Ad =
|
|
610
|
-
RefWhiteRGB.X * MtxAdaptMa.m00 +
|
|
611
|
-
RefWhiteRGB.Y * MtxAdaptMa.m10 +
|
|
612
|
-
RefWhiteRGB.Z * MtxAdaptMa.m20;
|
|
613
|
-
const Bd =
|
|
614
|
-
RefWhiteRGB.X * MtxAdaptMa.m01 +
|
|
615
|
-
RefWhiteRGB.Y * MtxAdaptMa.m11 +
|
|
616
|
-
RefWhiteRGB.Z * MtxAdaptMa.m21;
|
|
617
|
-
const Cd =
|
|
618
|
-
RefWhiteRGB.X * MtxAdaptMa.m02 +
|
|
619
|
-
RefWhiteRGB.Y * MtxAdaptMa.m12 +
|
|
620
|
-
RefWhiteRGB.Z * MtxAdaptMa.m22;
|
|
621
|
-
|
|
622
|
-
const X1 =
|
|
623
|
-
(x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20) *
|
|
624
|
-
(Ad / As);
|
|
625
|
-
const Y1 =
|
|
626
|
-
(x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21) *
|
|
627
|
-
(Bd / Bs);
|
|
628
|
-
const Z1 =
|
|
629
|
-
(x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22) *
|
|
630
|
-
(Cd / Cs);
|
|
631
|
-
|
|
632
|
-
const X2 =
|
|
633
|
-
X1 * MtxAdaptMaI.m00 + Y1 * MtxAdaptMaI.m10 + Z1 * MtxAdaptMaI.m20;
|
|
634
|
-
const Y2 =
|
|
635
|
-
X1 * MtxAdaptMaI.m01 + Y1 * MtxAdaptMaI.m11 + Z1 * MtxAdaptMaI.m21;
|
|
636
|
-
const Z2 =
|
|
637
|
-
X1 * MtxAdaptMaI.m02 + Y1 * MtxAdaptMaI.m12 + Z1 * MtxAdaptMaI.m22;
|
|
638
|
-
|
|
639
|
-
const r = compand(
|
|
640
|
-
X2 * MtxXYZ2RGB.m00 + Y2 * MtxXYZ2RGB.m10 + Z2 * MtxXYZ2RGB.m20
|
|
641
|
-
);
|
|
642
|
-
const g = compand(
|
|
643
|
-
X2 * MtxXYZ2RGB.m01 + Y2 * MtxXYZ2RGB.m11 + Z2 * MtxXYZ2RGB.m21
|
|
644
|
-
);
|
|
645
|
-
const b = compand(
|
|
646
|
-
X2 * MtxXYZ2RGB.m02 + Y2 * MtxXYZ2RGB.m12 + Z2 * MtxXYZ2RGB.m22
|
|
647
|
-
);
|
|
648
|
-
|
|
649
|
-
return [r * 255, g * 255, b * 255];
|
|
650
|
-
};
|
|
651
|
-
|
|
652
|
-
const rgb2lab = (...args) => {
|
|
653
|
-
const [r, g, b, ...rest] = unpack(args, 'rgb');
|
|
654
|
-
const [x, y, z] = rgb2xyz(r, g, b);
|
|
655
|
-
const [L, a, b_] = xyz2lab(x, y, z);
|
|
656
|
-
return [L, a, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
|
|
657
|
-
};
|
|
658
|
-
|
|
659
|
-
function xyz2lab(x, y, z) {
|
|
660
|
-
const { Xn, Yn, Zn, kE, kK } = labConstants;
|
|
661
|
-
const xr = x / Xn;
|
|
662
|
-
const yr = y / Yn;
|
|
663
|
-
const zr = z / Zn;
|
|
664
|
-
|
|
665
|
-
const fx = xr > kE ? Math.pow(xr, 1.0 / 3.0) : (kK * xr + 16.0) / 116.0;
|
|
666
|
-
const fy = yr > kE ? Math.pow(yr, 1.0 / 3.0) : (kK * yr + 16.0) / 116.0;
|
|
667
|
-
const fz = zr > kE ? Math.pow(zr, 1.0 / 3.0) : (kK * zr + 16.0) / 116.0;
|
|
668
|
-
|
|
669
|
-
return [116.0 * fy - 16.0, 500.0 * (fx - fy), 200.0 * (fy - fz)];
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
function gammaAdjustSRGB(companded) {
|
|
673
|
-
const sign = Math.sign(companded);
|
|
674
|
-
companded = Math.abs(companded);
|
|
675
|
-
const linear =
|
|
676
|
-
companded <= 0.04045
|
|
677
|
-
? companded / 12.92
|
|
678
|
-
: Math.pow((companded + 0.055) / 1.055, 2.4);
|
|
679
|
-
return linear * sign;
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
const rgb2xyz = (r, g, b) => {
|
|
683
|
-
// normalize and gamma adjust
|
|
684
|
-
r = gammaAdjustSRGB(r / 255);
|
|
685
|
-
g = gammaAdjustSRGB(g / 255);
|
|
686
|
-
b = gammaAdjustSRGB(b / 255);
|
|
687
|
-
|
|
688
|
-
const { MtxRGB2XYZ, MtxAdaptMa, MtxAdaptMaI, Xn, Yn, Zn, As, Bs, Cs } =
|
|
689
|
-
labConstants;
|
|
690
|
-
|
|
691
|
-
let x = r * MtxRGB2XYZ.m00 + g * MtxRGB2XYZ.m10 + b * MtxRGB2XYZ.m20;
|
|
692
|
-
let y = r * MtxRGB2XYZ.m01 + g * MtxRGB2XYZ.m11 + b * MtxRGB2XYZ.m21;
|
|
693
|
-
let z = r * MtxRGB2XYZ.m02 + g * MtxRGB2XYZ.m12 + b * MtxRGB2XYZ.m22;
|
|
694
|
-
|
|
695
|
-
const Ad = Xn * MtxAdaptMa.m00 + Yn * MtxAdaptMa.m10 + Zn * MtxAdaptMa.m20;
|
|
696
|
-
const Bd = Xn * MtxAdaptMa.m01 + Yn * MtxAdaptMa.m11 + Zn * MtxAdaptMa.m21;
|
|
697
|
-
const Cd = Xn * MtxAdaptMa.m02 + Yn * MtxAdaptMa.m12 + Zn * MtxAdaptMa.m22;
|
|
698
|
-
|
|
699
|
-
let X = x * MtxAdaptMa.m00 + y * MtxAdaptMa.m10 + z * MtxAdaptMa.m20;
|
|
700
|
-
let Y = x * MtxAdaptMa.m01 + y * MtxAdaptMa.m11 + z * MtxAdaptMa.m21;
|
|
701
|
-
let Z = x * MtxAdaptMa.m02 + y * MtxAdaptMa.m12 + z * MtxAdaptMa.m22;
|
|
702
|
-
|
|
703
|
-
X *= Ad / As;
|
|
704
|
-
Y *= Bd / Bs;
|
|
705
|
-
Z *= Cd / Cs;
|
|
706
|
-
|
|
707
|
-
x = X * MtxAdaptMaI.m00 + Y * MtxAdaptMaI.m10 + Z * MtxAdaptMaI.m20;
|
|
708
|
-
y = X * MtxAdaptMaI.m01 + Y * MtxAdaptMaI.m11 + Z * MtxAdaptMaI.m21;
|
|
709
|
-
z = X * MtxAdaptMaI.m02 + Y * MtxAdaptMaI.m12 + Z * MtxAdaptMaI.m22;
|
|
710
|
-
|
|
711
|
-
return [x, y, z];
|
|
712
|
-
};
|
|
713
|
-
|
|
714
|
-
Color.prototype.lab = function () {
|
|
715
|
-
return rgb2lab(this._rgb);
|
|
716
|
-
};
|
|
717
|
-
|
|
718
|
-
const lab$1 = (...args) => new Color(...args, 'lab');
|
|
719
|
-
Object.assign(chroma, { lab: lab$1, getLabWhitePoint, setLabWhitePoint });
|
|
720
|
-
|
|
721
|
-
input.format.lab = lab2rgb;
|
|
722
|
-
|
|
723
|
-
input.autodetect.push({
|
|
724
|
-
p: 2,
|
|
725
|
-
test: (...args) => {
|
|
726
|
-
args = unpack(args, 'lab');
|
|
727
|
-
if (type(args) === 'array' && args.length === 3) {
|
|
728
|
-
return 'lab';
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
});
|
|
732
|
-
|
|
733
|
-
Color.prototype.darken = function (amount = 1) {
|
|
734
|
-
const me = this;
|
|
735
|
-
const lab = me.lab();
|
|
736
|
-
lab[0] -= labConstants.Kn * amount;
|
|
737
|
-
return new Color(lab, 'lab').alpha(me.alpha(), true);
|
|
738
|
-
};
|
|
739
|
-
|
|
740
|
-
Color.prototype.brighten = function (amount = 1) {
|
|
741
|
-
return this.darken(-amount);
|
|
742
|
-
};
|
|
743
|
-
|
|
744
|
-
Color.prototype.darker = Color.prototype.darken;
|
|
745
|
-
Color.prototype.brighter = Color.prototype.brighten;
|
|
746
|
-
|
|
747
|
-
Color.prototype.get = function (mc) {
|
|
748
|
-
const [mode, channel] = mc.split('.');
|
|
749
|
-
const src = this[mode]();
|
|
750
|
-
if (channel) {
|
|
751
|
-
const i = mode.indexOf(channel) - (mode.substr(0, 2) === 'ok' ? 2 : 0);
|
|
752
|
-
if (i > -1) return src[i];
|
|
753
|
-
throw new Error(`unknown channel ${channel} in mode ${mode}`);
|
|
754
|
-
} else {
|
|
755
|
-
return src;
|
|
756
|
-
}
|
|
757
|
-
};
|
|
758
|
-
|
|
759
|
-
const { pow: pow$6 } = Math;
|
|
760
|
-
|
|
761
|
-
const EPS = 1e-7;
|
|
762
|
-
const MAX_ITER = 20;
|
|
763
|
-
|
|
764
|
-
Color.prototype.luminance = function (lum, mode = 'rgb') {
|
|
765
|
-
if (lum !== undefined && type(lum) === 'number') {
|
|
766
|
-
if (lum === 0) {
|
|
767
|
-
// return pure black
|
|
768
|
-
return new Color([0, 0, 0, this._rgb[3]], 'rgb');
|
|
769
|
-
}
|
|
770
|
-
if (lum === 1) {
|
|
771
|
-
// return pure white
|
|
772
|
-
return new Color([255, 255, 255, this._rgb[3]], 'rgb');
|
|
773
|
-
}
|
|
774
|
-
// compute new color using...
|
|
775
|
-
let cur_lum = this.luminance();
|
|
776
|
-
let max_iter = MAX_ITER;
|
|
777
|
-
|
|
778
|
-
const test = (low, high) => {
|
|
779
|
-
const mid = low.interpolate(high, 0.5, mode);
|
|
780
|
-
const lm = mid.luminance();
|
|
781
|
-
if (Math.abs(lum - lm) < EPS || !max_iter--) {
|
|
782
|
-
// close enough
|
|
783
|
-
return mid;
|
|
784
|
-
}
|
|
785
|
-
return lm > lum ? test(low, mid) : test(mid, high);
|
|
786
|
-
};
|
|
787
|
-
|
|
788
|
-
const rgb = (
|
|
789
|
-
cur_lum > lum
|
|
790
|
-
? test(new Color([0, 0, 0]), this)
|
|
791
|
-
: test(this, new Color([255, 255, 255]))
|
|
792
|
-
).rgb();
|
|
793
|
-
return new Color([...rgb, this._rgb[3]]);
|
|
794
|
-
}
|
|
795
|
-
return rgb2luminance(...this._rgb.slice(0, 3));
|
|
796
|
-
};
|
|
797
|
-
|
|
798
|
-
const rgb2luminance = (r, g, b) => {
|
|
799
|
-
// relative luminance
|
|
800
|
-
// see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
|
801
|
-
r = luminance_x(r);
|
|
802
|
-
g = luminance_x(g);
|
|
803
|
-
b = luminance_x(b);
|
|
804
|
-
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
805
|
-
};
|
|
806
|
-
|
|
807
|
-
const luminance_x = (x) => {
|
|
808
|
-
x /= 255;
|
|
809
|
-
return x <= 0.03928 ? x / 12.92 : pow$6((x + 0.055) / 1.055, 2.4);
|
|
810
|
-
};
|
|
811
|
-
|
|
812
|
-
const index = {};
|
|
813
|
-
|
|
814
|
-
const mix = (col1, col2, f = 0.5, ...rest) => {
|
|
815
|
-
let mode = rest[0] || 'lrgb';
|
|
816
|
-
if (!index[mode] && !rest.length) {
|
|
817
|
-
// fall back to the first supported mode
|
|
818
|
-
mode = Object.keys(index)[0];
|
|
819
|
-
}
|
|
820
|
-
if (!index[mode]) {
|
|
821
|
-
throw new Error(`interpolation mode ${mode} is not defined`);
|
|
822
|
-
}
|
|
823
|
-
if (type(col1) !== 'object') col1 = new Color(col1);
|
|
824
|
-
if (type(col2) !== 'object') col2 = new Color(col2);
|
|
825
|
-
return index[mode](col1, col2, f).alpha(
|
|
826
|
-
col1.alpha() + f * (col2.alpha() - col1.alpha())
|
|
827
|
-
);
|
|
828
|
-
};
|
|
829
|
-
|
|
830
|
-
Color.prototype.mix = Color.prototype.interpolate = function (
|
|
831
|
-
col2,
|
|
832
|
-
f = 0.5,
|
|
833
|
-
...rest
|
|
834
|
-
) {
|
|
835
|
-
return mix(this, col2, f, ...rest);
|
|
836
|
-
};
|
|
837
|
-
|
|
838
|
-
Color.prototype.premultiply = function (mutate = false) {
|
|
839
|
-
const rgb = this._rgb;
|
|
840
|
-
const a = rgb[3];
|
|
841
|
-
if (mutate) {
|
|
842
|
-
this._rgb = [rgb[0] * a, rgb[1] * a, rgb[2] * a, a];
|
|
843
|
-
return this;
|
|
844
|
-
} else {
|
|
845
|
-
return new Color([rgb[0] * a, rgb[1] * a, rgb[2] * a, a], 'rgb');
|
|
846
|
-
}
|
|
847
|
-
};
|
|
848
|
-
|
|
849
|
-
const { sin: sin$3, cos: cos$4 } = Math;
|
|
850
|
-
|
|
851
|
-
const lch2lab = (...args) => {
|
|
852
|
-
/*
|
|
853
|
-
Convert from a qualitative parameter h and a quantitative parameter l to a 24-bit pixel.
|
|
854
|
-
These formulas were invented by David Dalrymple to obtain maximum contrast without going
|
|
855
|
-
out of gamut if the parameters are in the range 0-1.
|
|
856
|
-
|
|
857
|
-
A saturation multiplier was added by Gregor Aisch
|
|
858
|
-
*/
|
|
859
|
-
let [l, c, h] = unpack(args, 'lch');
|
|
860
|
-
if (isNaN(h)) h = 0;
|
|
861
|
-
h = h * DEG2RAD;
|
|
862
|
-
return [l, cos$4(h) * c, sin$3(h) * c];
|
|
863
|
-
};
|
|
864
|
-
|
|
865
|
-
const lch2rgb = (...args) => {
|
|
866
|
-
args = unpack(args, 'lch');
|
|
867
|
-
const [l, c, h] = args;
|
|
868
|
-
const [L, a, b_] = lch2lab(l, c, h);
|
|
869
|
-
const [r, g, b] = lab2rgb(L, a, b_);
|
|
870
|
-
return [r, g, b, args.length > 3 ? args[3] : 1];
|
|
871
|
-
};
|
|
872
|
-
|
|
873
|
-
const hcl2rgb = (...args) => {
|
|
874
|
-
const hcl = reverse3(unpack(args, 'hcl'));
|
|
875
|
-
return lch2rgb(...hcl);
|
|
876
|
-
};
|
|
877
|
-
|
|
878
|
-
const { sqrt: sqrt$4, atan2: atan2$2, round: round$4 } = Math;
|
|
879
|
-
|
|
880
|
-
const lab2lch = (...args) => {
|
|
881
|
-
const [l, a, b] = unpack(args, 'lab');
|
|
882
|
-
const c = sqrt$4(a * a + b * b);
|
|
883
|
-
let h = (atan2$2(b, a) * RAD2DEG + 360) % 360;
|
|
884
|
-
if (round$4(c * 10000) === 0) h = Number.NaN;
|
|
885
|
-
return [l, c, h];
|
|
886
|
-
};
|
|
887
|
-
|
|
888
|
-
const rgb2lch = (...args) => {
|
|
889
|
-
const [r, g, b, ...rest] = unpack(args, 'rgb');
|
|
890
|
-
const [l, a, b_] = rgb2lab(r, g, b);
|
|
891
|
-
const [L, c, h] = lab2lch(l, a, b_);
|
|
892
|
-
return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
|
|
893
|
-
};
|
|
894
|
-
|
|
895
|
-
Color.prototype.lch = function () {
|
|
896
|
-
return rgb2lch(this._rgb);
|
|
897
|
-
};
|
|
898
|
-
Color.prototype.hcl = function () {
|
|
899
|
-
return reverse3(rgb2lch(this._rgb));
|
|
900
|
-
};
|
|
901
|
-
|
|
902
|
-
const lch$1 = (...args) => new Color(...args, 'lch');
|
|
903
|
-
const hcl = (...args) => new Color(...args, 'hcl');
|
|
904
|
-
|
|
905
|
-
Object.assign(chroma, { lch: lch$1, hcl });
|
|
906
|
-
|
|
907
|
-
input.format.lch = lch2rgb;
|
|
908
|
-
input.format.hcl = hcl2rgb;
|
|
909
|
-
['lch', 'hcl'].forEach((m) =>
|
|
910
|
-
input.autodetect.push({
|
|
911
|
-
p: 2,
|
|
912
|
-
test: (...args) => {
|
|
913
|
-
args = unpack(args, m);
|
|
914
|
-
if (type(args) === 'array' && args.length === 3) {
|
|
915
|
-
return m;
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
})
|
|
919
|
-
);
|
|
920
|
-
|
|
921
|
-
Color.prototype.saturate = function (amount = 1) {
|
|
922
|
-
const me = this;
|
|
923
|
-
const lch = me.lch();
|
|
924
|
-
lch[1] += labConstants.Kn * amount;
|
|
925
|
-
if (lch[1] < 0) lch[1] = 0;
|
|
926
|
-
return new Color(lch, 'lch').alpha(me.alpha(), true);
|
|
927
|
-
};
|
|
928
|
-
|
|
929
|
-
Color.prototype.desaturate = function (amount = 1) {
|
|
930
|
-
return this.saturate(-amount);
|
|
931
|
-
};
|
|
932
|
-
|
|
933
|
-
Color.prototype.set = function (mc, value, mutate = false) {
|
|
934
|
-
const [mode, channel] = mc.split('.');
|
|
935
|
-
const src = this[mode]();
|
|
936
|
-
if (channel) {
|
|
937
|
-
const i = mode.indexOf(channel) - (mode.substr(0, 2) === 'ok' ? 2 : 0);
|
|
938
|
-
if (i > -1) {
|
|
939
|
-
if (type(value) == 'string') {
|
|
940
|
-
switch (value.charAt(0)) {
|
|
941
|
-
case '+':
|
|
942
|
-
src[i] += +value;
|
|
943
|
-
break;
|
|
944
|
-
case '-':
|
|
945
|
-
src[i] += +value;
|
|
946
|
-
break;
|
|
947
|
-
case '*':
|
|
948
|
-
src[i] *= +value.substr(1);
|
|
949
|
-
break;
|
|
950
|
-
case '/':
|
|
951
|
-
src[i] /= +value.substr(1);
|
|
952
|
-
break;
|
|
953
|
-
default:
|
|
954
|
-
src[i] = +value;
|
|
955
|
-
}
|
|
956
|
-
} else if (type(value) === 'number') {
|
|
957
|
-
src[i] = value;
|
|
958
|
-
} else {
|
|
959
|
-
throw new Error(`unsupported value for Color.set`);
|
|
960
|
-
}
|
|
961
|
-
const out = new Color(src, mode);
|
|
962
|
-
if (mutate) {
|
|
963
|
-
this._rgb = out._rgb;
|
|
964
|
-
return this;
|
|
965
|
-
}
|
|
966
|
-
return out;
|
|
967
|
-
}
|
|
968
|
-
throw new Error(`unknown channel ${channel} in mode ${mode}`);
|
|
969
|
-
} else {
|
|
970
|
-
return src;
|
|
971
|
-
}
|
|
972
|
-
};
|
|
973
|
-
|
|
974
|
-
Color.prototype.tint = function (f = 0.5, ...rest) {
|
|
975
|
-
return mix(this, 'white', f, ...rest);
|
|
976
|
-
};
|
|
977
|
-
|
|
978
|
-
Color.prototype.shade = function (f = 0.5, ...rest) {
|
|
979
|
-
return mix(this, 'black', f, ...rest);
|
|
980
|
-
};
|
|
981
|
-
|
|
982
|
-
const rgb$1 = (col1, col2, f) => {
|
|
983
|
-
const xyz0 = col1._rgb;
|
|
984
|
-
const xyz1 = col2._rgb;
|
|
985
|
-
return new Color(
|
|
986
|
-
xyz0[0] + f * (xyz1[0] - xyz0[0]),
|
|
987
|
-
xyz0[1] + f * (xyz1[1] - xyz0[1]),
|
|
988
|
-
xyz0[2] + f * (xyz1[2] - xyz0[2]),
|
|
989
|
-
'rgb'
|
|
990
|
-
);
|
|
991
|
-
};
|
|
992
|
-
|
|
993
|
-
// register interpolator
|
|
994
|
-
index.rgb = rgb$1;
|
|
995
|
-
|
|
996
|
-
const { sqrt: sqrt$3, pow: pow$5 } = Math;
|
|
997
|
-
|
|
998
|
-
const lrgb = (col1, col2, f) => {
|
|
999
|
-
const [x1, y1, z1] = col1._rgb;
|
|
1000
|
-
const [x2, y2, z2] = col2._rgb;
|
|
1001
|
-
return new Color(
|
|
1002
|
-
sqrt$3(pow$5(x1, 2) * (1 - f) + pow$5(x2, 2) * f),
|
|
1003
|
-
sqrt$3(pow$5(y1, 2) * (1 - f) + pow$5(y2, 2) * f),
|
|
1004
|
-
sqrt$3(pow$5(z1, 2) * (1 - f) + pow$5(z2, 2) * f),
|
|
1005
|
-
'rgb'
|
|
1006
|
-
);
|
|
1007
|
-
};
|
|
1008
|
-
|
|
1009
|
-
// register interpolator
|
|
1010
|
-
index.lrgb = lrgb;
|
|
1011
|
-
|
|
1012
|
-
const lab = (col1, col2, f) => {
|
|
1013
|
-
const xyz0 = col1.lab();
|
|
1014
|
-
const xyz1 = col2.lab();
|
|
1015
|
-
return new Color(
|
|
1016
|
-
xyz0[0] + f * (xyz1[0] - xyz0[0]),
|
|
1017
|
-
xyz0[1] + f * (xyz1[1] - xyz0[1]),
|
|
1018
|
-
xyz0[2] + f * (xyz1[2] - xyz0[2]),
|
|
1019
|
-
'lab'
|
|
1020
|
-
);
|
|
1021
|
-
};
|
|
1022
|
-
|
|
1023
|
-
// register interpolator
|
|
1024
|
-
index.lab = lab;
|
|
1025
|
-
|
|
1026
|
-
const interpolate_hsx = (col1, col2, f, m) => {
|
|
1027
|
-
let xyz0, xyz1;
|
|
1028
|
-
if (m === 'hsl') {
|
|
1029
|
-
xyz0 = col1.hsl();
|
|
1030
|
-
xyz1 = col2.hsl();
|
|
1031
|
-
} else if (m === 'hsv') {
|
|
1032
|
-
xyz0 = col1.hsv();
|
|
1033
|
-
xyz1 = col2.hsv();
|
|
1034
|
-
} else if (m === 'hcg') {
|
|
1035
|
-
xyz0 = col1.hcg();
|
|
1036
|
-
xyz1 = col2.hcg();
|
|
1037
|
-
} else if (m === 'hsi') {
|
|
1038
|
-
xyz0 = col1.hsi();
|
|
1039
|
-
xyz1 = col2.hsi();
|
|
1040
|
-
} else if (m === 'lch' || m === 'hcl') {
|
|
1041
|
-
m = 'hcl';
|
|
1042
|
-
xyz0 = col1.hcl();
|
|
1043
|
-
xyz1 = col2.hcl();
|
|
1044
|
-
} else if (m === 'oklch') {
|
|
1045
|
-
xyz0 = col1.oklch().reverse();
|
|
1046
|
-
xyz1 = col2.oklch().reverse();
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
let hue0, hue1, sat0, sat1, lbv0, lbv1;
|
|
1050
|
-
if (m.substr(0, 1) === 'h' || m === 'oklch') {
|
|
1051
|
-
[hue0, sat0, lbv0] = xyz0;
|
|
1052
|
-
[hue1, sat1, lbv1] = xyz1;
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
let sat, hue, lbv, dh;
|
|
1056
|
-
|
|
1057
|
-
if (!isNaN(hue0) && !isNaN(hue1)) {
|
|
1058
|
-
// both colors have hue
|
|
1059
|
-
if (hue1 > hue0 && hue1 - hue0 > 180) {
|
|
1060
|
-
dh = hue1 - (hue0 + 360);
|
|
1061
|
-
} else if (hue1 < hue0 && hue0 - hue1 > 180) {
|
|
1062
|
-
dh = hue1 + 360 - hue0;
|
|
1063
|
-
} else {
|
|
1064
|
-
dh = hue1 - hue0;
|
|
1065
|
-
}
|
|
1066
|
-
hue = hue0 + f * dh;
|
|
1067
|
-
} else if (!isNaN(hue0)) {
|
|
1068
|
-
hue = hue0;
|
|
1069
|
-
if ((lbv1 == 1 || lbv1 == 0) && m != 'hsv') sat = sat0;
|
|
1070
|
-
} else if (!isNaN(hue1)) {
|
|
1071
|
-
hue = hue1;
|
|
1072
|
-
if ((lbv0 == 1 || lbv0 == 0) && m != 'hsv') sat = sat1;
|
|
1073
|
-
} else {
|
|
1074
|
-
hue = Number.NaN;
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
|
-
if (sat === undefined) sat = sat0 + f * (sat1 - sat0);
|
|
1078
|
-
lbv = lbv0 + f * (lbv1 - lbv0);
|
|
1079
|
-
return m === 'oklch'
|
|
1080
|
-
? new Color([lbv, sat, hue], m)
|
|
1081
|
-
: new Color([hue, sat, lbv], m);
|
|
1082
|
-
};
|
|
1083
|
-
|
|
1084
|
-
const lch = (col1, col2, f) => {
|
|
1085
|
-
return interpolate_hsx(col1, col2, f, 'lch');
|
|
1086
|
-
};
|
|
1087
|
-
|
|
1088
|
-
// register interpolator
|
|
1089
|
-
index.lch = lch;
|
|
1090
|
-
index.hcl = lch;
|
|
1091
|
-
|
|
1092
|
-
const num2rgb = (num) => {
|
|
1093
|
-
if (type(num) == 'number' && num >= 0 && num <= 0xffffff) {
|
|
1094
|
-
const r = num >> 16;
|
|
1095
|
-
const g = (num >> 8) & 0xff;
|
|
1096
|
-
const b = num & 0xff;
|
|
1097
|
-
return [r, g, b, 1];
|
|
1098
|
-
}
|
|
1099
|
-
throw new Error('unknown num color: ' + num);
|
|
1100
|
-
};
|
|
1101
|
-
|
|
1102
|
-
const rgb2num = (...args) => {
|
|
1103
|
-
const [r, g, b] = unpack(args, 'rgb');
|
|
1104
|
-
return (r << 16) + (g << 8) + b;
|
|
1105
|
-
};
|
|
1106
|
-
|
|
1107
|
-
Color.prototype.num = function () {
|
|
1108
|
-
return rgb2num(this._rgb);
|
|
1109
|
-
};
|
|
1110
|
-
|
|
1111
|
-
const num$1 = (...args) => new Color(...args, 'num');
|
|
1112
|
-
|
|
1113
|
-
Object.assign(chroma, { num: num$1 });
|
|
1114
|
-
|
|
1115
|
-
input.format.num = num2rgb;
|
|
1116
|
-
|
|
1117
|
-
input.autodetect.push({
|
|
1118
|
-
p: 5,
|
|
1119
|
-
test: (...args) => {
|
|
1120
|
-
if (
|
|
1121
|
-
args.length === 1 &&
|
|
1122
|
-
type(args[0]) === 'number' &&
|
|
1123
|
-
args[0] >= 0 &&
|
|
1124
|
-
args[0] <= 0xffffff
|
|
1125
|
-
) {
|
|
1126
|
-
return 'num';
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
});
|
|
1130
|
-
|
|
1131
|
-
const num = (col1, col2, f) => {
|
|
1132
|
-
const c1 = col1.num();
|
|
1133
|
-
const c2 = col2.num();
|
|
1134
|
-
return new Color(c1 + f * (c2 - c1), 'num');
|
|
1135
|
-
};
|
|
1136
|
-
|
|
1137
|
-
// register interpolator
|
|
1138
|
-
index.num = num;
|
|
1139
|
-
|
|
1140
|
-
const { floor: floor$3 } = Math;
|
|
1141
|
-
|
|
1142
|
-
/*
|
|
1143
|
-
* this is basically just HSV with some minor tweaks
|
|
1144
|
-
*
|
|
1145
|
-
* hue.. [0..360]
|
|
1146
|
-
* chroma .. [0..1]
|
|
1147
|
-
* grayness .. [0..1]
|
|
1148
|
-
*/
|
|
1149
|
-
|
|
1150
|
-
const hcg2rgb = (...args) => {
|
|
1151
|
-
args = unpack(args, 'hcg');
|
|
1152
|
-
let [h, c, _g] = args;
|
|
1153
|
-
let r, g, b;
|
|
1154
|
-
_g = _g * 255;
|
|
1155
|
-
const _c = c * 255;
|
|
1156
|
-
if (c === 0) {
|
|
1157
|
-
r = g = b = _g;
|
|
1158
|
-
} else {
|
|
1159
|
-
if (h === 360) h = 0;
|
|
1160
|
-
if (h > 360) h -= 360;
|
|
1161
|
-
if (h < 0) h += 360;
|
|
1162
|
-
h /= 60;
|
|
1163
|
-
const i = floor$3(h);
|
|
1164
|
-
const f = h - i;
|
|
1165
|
-
const p = _g * (1 - c);
|
|
1166
|
-
const q = p + _c * (1 - f);
|
|
1167
|
-
const t = p + _c * f;
|
|
1168
|
-
const v = p + _c;
|
|
1169
|
-
switch (i) {
|
|
1170
|
-
case 0:
|
|
1171
|
-
[r, g, b] = [v, t, p];
|
|
1172
|
-
break;
|
|
1173
|
-
case 1:
|
|
1174
|
-
[r, g, b] = [q, v, p];
|
|
1175
|
-
break;
|
|
1176
|
-
case 2:
|
|
1177
|
-
[r, g, b] = [p, v, t];
|
|
1178
|
-
break;
|
|
1179
|
-
case 3:
|
|
1180
|
-
[r, g, b] = [p, q, v];
|
|
1181
|
-
break;
|
|
1182
|
-
case 4:
|
|
1183
|
-
[r, g, b] = [t, p, v];
|
|
1184
|
-
break;
|
|
1185
|
-
case 5:
|
|
1186
|
-
[r, g, b] = [v, p, q];
|
|
1187
|
-
break;
|
|
1188
|
-
}
|
|
1189
|
-
}
|
|
1190
|
-
return [r, g, b, args.length > 3 ? args[3] : 1];
|
|
1191
|
-
};
|
|
1192
|
-
|
|
1193
|
-
const rgb2hcg = (...args) => {
|
|
1194
|
-
const [r, g, b] = unpack(args, 'rgb');
|
|
1195
|
-
const minRgb = min$3(r, g, b);
|
|
1196
|
-
const maxRgb = max$3(r, g, b);
|
|
1197
|
-
const delta = maxRgb - minRgb;
|
|
1198
|
-
const c = (delta * 100) / 255;
|
|
1199
|
-
const _g = (minRgb / (255 - delta)) * 100;
|
|
1200
|
-
let h;
|
|
1201
|
-
if (delta === 0) {
|
|
1202
|
-
h = Number.NaN;
|
|
1203
|
-
} else {
|
|
1204
|
-
if (r === maxRgb) h = (g - b) / delta;
|
|
1205
|
-
if (g === maxRgb) h = 2 + (b - r) / delta;
|
|
1206
|
-
if (b === maxRgb) h = 4 + (r - g) / delta;
|
|
1207
|
-
h *= 60;
|
|
1208
|
-
if (h < 0) h += 360;
|
|
1209
|
-
}
|
|
1210
|
-
return [h, c, _g];
|
|
1211
|
-
};
|
|
1212
|
-
|
|
1213
|
-
Color.prototype.hcg = function () {
|
|
1214
|
-
return rgb2hcg(this._rgb);
|
|
1215
|
-
};
|
|
1216
|
-
|
|
1217
|
-
const hcg$1 = (...args) => new Color(...args, 'hcg');
|
|
1218
|
-
chroma.hcg = hcg$1;
|
|
1219
|
-
|
|
1220
|
-
input.format.hcg = hcg2rgb;
|
|
1221
|
-
|
|
1222
|
-
input.autodetect.push({
|
|
1223
|
-
p: 1,
|
|
1224
|
-
test: (...args) => {
|
|
1225
|
-
args = unpack(args, 'hcg');
|
|
1226
|
-
if (type(args) === 'array' && args.length === 3) {
|
|
1227
|
-
return 'hcg';
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
});
|
|
1231
|
-
|
|
1232
|
-
const hcg = (col1, col2, f) => {
|
|
1233
|
-
return interpolate_hsx(col1, col2, f, 'hcg');
|
|
1234
|
-
};
|
|
1235
|
-
|
|
1236
|
-
// register interpolator
|
|
1237
|
-
index.hcg = hcg;
|
|
1238
|
-
|
|
1239
|
-
const { cos: cos$3 } = Math;
|
|
1240
|
-
|
|
1241
|
-
/*
|
|
1242
|
-
* hue [0..360]
|
|
1243
|
-
* saturation [0..1]
|
|
1244
|
-
* intensity [0..1]
|
|
1245
|
-
*/
|
|
1246
|
-
const hsi2rgb = (...args) => {
|
|
1247
|
-
/*
|
|
1248
|
-
borrowed from here:
|
|
1249
|
-
http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/hsi2rgb.cpp
|
|
1250
|
-
*/
|
|
1251
|
-
args = unpack(args, 'hsi');
|
|
1252
|
-
let [h, s, i] = args;
|
|
1253
|
-
let r, g, b;
|
|
1254
|
-
|
|
1255
|
-
if (isNaN(h)) h = 0;
|
|
1256
|
-
if (isNaN(s)) s = 0;
|
|
1257
|
-
// normalize hue
|
|
1258
|
-
if (h > 360) h -= 360;
|
|
1259
|
-
if (h < 0) h += 360;
|
|
1260
|
-
h /= 360;
|
|
1261
|
-
if (h < 1 / 3) {
|
|
1262
|
-
b = (1 - s) / 3;
|
|
1263
|
-
r = (1 + (s * cos$3(TWOPI * h)) / cos$3(PITHIRD - TWOPI * h)) / 3;
|
|
1264
|
-
g = 1 - (b + r);
|
|
1265
|
-
} else if (h < 2 / 3) {
|
|
1266
|
-
h -= 1 / 3;
|
|
1267
|
-
r = (1 - s) / 3;
|
|
1268
|
-
g = (1 + (s * cos$3(TWOPI * h)) / cos$3(PITHIRD - TWOPI * h)) / 3;
|
|
1269
|
-
b = 1 - (r + g);
|
|
1270
|
-
} else {
|
|
1271
|
-
h -= 2 / 3;
|
|
1272
|
-
g = (1 - s) / 3;
|
|
1273
|
-
b = (1 + (s * cos$3(TWOPI * h)) / cos$3(PITHIRD - TWOPI * h)) / 3;
|
|
1274
|
-
r = 1 - (g + b);
|
|
1275
|
-
}
|
|
1276
|
-
r = limit(i * r * 3);
|
|
1277
|
-
g = limit(i * g * 3);
|
|
1278
|
-
b = limit(i * b * 3);
|
|
1279
|
-
return [r * 255, g * 255, b * 255, args.length > 3 ? args[3] : 1];
|
|
1280
|
-
};
|
|
1281
|
-
|
|
1282
|
-
const { min: min$2, sqrt: sqrt$2, acos } = Math;
|
|
1283
|
-
|
|
1284
|
-
const rgb2hsi = (...args) => {
|
|
1285
|
-
/*
|
|
1286
|
-
borrowed from here:
|
|
1287
|
-
http://hummer.stanford.edu/museinfo/doc/examples/humdrum/keyscape2/rgb2hsi.cpp
|
|
1288
|
-
*/
|
|
1289
|
-
let [r, g, b] = unpack(args, 'rgb');
|
|
1290
|
-
r /= 255;
|
|
1291
|
-
g /= 255;
|
|
1292
|
-
b /= 255;
|
|
1293
|
-
let h;
|
|
1294
|
-
const min_ = min$2(r, g, b);
|
|
1295
|
-
const i = (r + g + b) / 3;
|
|
1296
|
-
const s = i > 0 ? 1 - min_ / i : 0;
|
|
1297
|
-
if (s === 0) {
|
|
1298
|
-
h = NaN;
|
|
1299
|
-
} else {
|
|
1300
|
-
h = (r - g + (r - b)) / 2;
|
|
1301
|
-
h /= sqrt$2((r - g) * (r - g) + (r - b) * (g - b));
|
|
1302
|
-
h = acos(h);
|
|
1303
|
-
if (b > g) {
|
|
1304
|
-
h = TWOPI - h;
|
|
1305
|
-
}
|
|
1306
|
-
h /= TWOPI;
|
|
1307
|
-
}
|
|
1308
|
-
return [h * 360, s, i];
|
|
1309
|
-
};
|
|
1310
|
-
|
|
1311
|
-
Color.prototype.hsi = function () {
|
|
1312
|
-
return rgb2hsi(this._rgb);
|
|
1313
|
-
};
|
|
1314
|
-
|
|
1315
|
-
const hsi$1 = (...args) => new Color(...args, 'hsi');
|
|
1316
|
-
chroma.hsi = hsi$1;
|
|
1317
|
-
|
|
1318
|
-
input.format.hsi = hsi2rgb;
|
|
1319
|
-
|
|
1320
|
-
input.autodetect.push({
|
|
1321
|
-
p: 2,
|
|
1322
|
-
test: (...args) => {
|
|
1323
|
-
args = unpack(args, 'hsi');
|
|
1324
|
-
if (type(args) === 'array' && args.length === 3) {
|
|
1325
|
-
return 'hsi';
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
});
|
|
1329
|
-
|
|
1330
|
-
const hsi = (col1, col2, f) => {
|
|
1331
|
-
return interpolate_hsx(col1, col2, f, 'hsi');
|
|
1332
|
-
};
|
|
1333
|
-
|
|
1334
|
-
// register interpolator
|
|
1335
|
-
index.hsi = hsi;
|
|
1336
|
-
|
|
1337
|
-
const hsl2rgb = (...args) => {
|
|
1338
|
-
args = unpack(args, 'hsl');
|
|
1339
|
-
const [h, s, l] = args;
|
|
1340
|
-
let r, g, b;
|
|
1341
|
-
if (s === 0) {
|
|
1342
|
-
r = g = b = l * 255;
|
|
1343
|
-
} else {
|
|
1344
|
-
const t3 = [0, 0, 0];
|
|
1345
|
-
const c = [0, 0, 0];
|
|
1346
|
-
const t2 = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
1347
|
-
const t1 = 2 * l - t2;
|
|
1348
|
-
const h_ = h / 360;
|
|
1349
|
-
t3[0] = h_ + 1 / 3;
|
|
1350
|
-
t3[1] = h_;
|
|
1351
|
-
t3[2] = h_ - 1 / 3;
|
|
1352
|
-
for (let i = 0; i < 3; i++) {
|
|
1353
|
-
if (t3[i] < 0) t3[i] += 1;
|
|
1354
|
-
if (t3[i] > 1) t3[i] -= 1;
|
|
1355
|
-
if (6 * t3[i] < 1) c[i] = t1 + (t2 - t1) * 6 * t3[i];
|
|
1356
|
-
else if (2 * t3[i] < 1) c[i] = t2;
|
|
1357
|
-
else if (3 * t3[i] < 2) c[i] = t1 + (t2 - t1) * (2 / 3 - t3[i]) * 6;
|
|
1358
|
-
else c[i] = t1;
|
|
1359
|
-
}
|
|
1360
|
-
[r, g, b] = [c[0] * 255, c[1] * 255, c[2] * 255];
|
|
1361
|
-
}
|
|
1362
|
-
if (args.length > 3) {
|
|
1363
|
-
// keep alpha channel
|
|
1364
|
-
return [r, g, b, args[3]];
|
|
1365
|
-
}
|
|
1366
|
-
return [r, g, b, 1];
|
|
1367
|
-
};
|
|
1368
|
-
|
|
1369
|
-
/*
|
|
1370
|
-
* supported arguments:
|
|
1371
|
-
* - rgb2hsl(r,g,b)
|
|
1372
|
-
* - rgb2hsl(r,g,b,a)
|
|
1373
|
-
* - rgb2hsl([r,g,b])
|
|
1374
|
-
* - rgb2hsl([r,g,b,a])
|
|
1375
|
-
* - rgb2hsl({r,g,b,a})
|
|
1376
|
-
*/
|
|
1377
|
-
const rgb2hsl$1 = (...args) => {
|
|
1378
|
-
args = unpack(args, 'rgba');
|
|
1379
|
-
let [r, g, b] = args;
|
|
1380
|
-
|
|
1381
|
-
r /= 255;
|
|
1382
|
-
g /= 255;
|
|
1383
|
-
b /= 255;
|
|
1384
|
-
|
|
1385
|
-
const minRgb = min$3(r, g, b);
|
|
1386
|
-
const maxRgb = max$3(r, g, b);
|
|
1387
|
-
|
|
1388
|
-
const l = (maxRgb + minRgb) / 2;
|
|
1389
|
-
let s, h;
|
|
1390
|
-
|
|
1391
|
-
if (maxRgb === minRgb) {
|
|
1392
|
-
s = 0;
|
|
1393
|
-
h = Number.NaN;
|
|
1394
|
-
} else {
|
|
1395
|
-
s =
|
|
1396
|
-
l < 0.5
|
|
1397
|
-
? (maxRgb - minRgb) / (maxRgb + minRgb)
|
|
1398
|
-
: (maxRgb - minRgb) / (2 - maxRgb - minRgb);
|
|
1399
|
-
}
|
|
1400
|
-
|
|
1401
|
-
if (r == maxRgb) h = (g - b) / (maxRgb - minRgb);
|
|
1402
|
-
else if (g == maxRgb) h = 2 + (b - r) / (maxRgb - minRgb);
|
|
1403
|
-
else if (b == maxRgb) h = 4 + (r - g) / (maxRgb - minRgb);
|
|
1404
|
-
|
|
1405
|
-
h *= 60;
|
|
1406
|
-
if (h < 0) h += 360;
|
|
1407
|
-
if (args.length > 3 && args[3] !== undefined) return [h, s, l, args[3]];
|
|
1408
|
-
return [h, s, l];
|
|
1409
|
-
};
|
|
1410
|
-
|
|
1411
|
-
Color.prototype.hsl = function () {
|
|
1412
|
-
return rgb2hsl$1(this._rgb);
|
|
1413
|
-
};
|
|
1414
|
-
|
|
1415
|
-
const hsl$1 = (...args) => new Color(...args, 'hsl');
|
|
1416
|
-
chroma.hsl = hsl$1;
|
|
1417
|
-
|
|
1418
|
-
input.format.hsl = hsl2rgb;
|
|
1419
|
-
|
|
1420
|
-
input.autodetect.push({
|
|
1421
|
-
p: 2,
|
|
1422
|
-
test: (...args) => {
|
|
1423
|
-
args = unpack(args, 'hsl');
|
|
1424
|
-
if (type(args) === 'array' && args.length === 3) {
|
|
1425
|
-
return 'hsl';
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
});
|
|
1429
|
-
|
|
1430
|
-
const hsl = (col1, col2, f) => {
|
|
1431
|
-
return interpolate_hsx(col1, col2, f, 'hsl');
|
|
1432
|
-
};
|
|
1433
|
-
|
|
1434
|
-
// register interpolator
|
|
1435
|
-
index.hsl = hsl;
|
|
1436
|
-
|
|
1437
|
-
const { floor: floor$2 } = Math;
|
|
1438
|
-
|
|
1439
|
-
const hsv2rgb = (...args) => {
|
|
1440
|
-
args = unpack(args, 'hsv');
|
|
1441
|
-
let [h, s, v] = args;
|
|
1442
|
-
let r, g, b;
|
|
1443
|
-
v *= 255;
|
|
1444
|
-
if (s === 0) {
|
|
1445
|
-
r = g = b = v;
|
|
1446
|
-
} else {
|
|
1447
|
-
if (h === 360) h = 0;
|
|
1448
|
-
if (h > 360) h -= 360;
|
|
1449
|
-
if (h < 0) h += 360;
|
|
1450
|
-
h /= 60;
|
|
1451
|
-
|
|
1452
|
-
const i = floor$2(h);
|
|
1453
|
-
const f = h - i;
|
|
1454
|
-
const p = v * (1 - s);
|
|
1455
|
-
const q = v * (1 - s * f);
|
|
1456
|
-
const t = v * (1 - s * (1 - f));
|
|
1457
|
-
|
|
1458
|
-
switch (i) {
|
|
1459
|
-
case 0:
|
|
1460
|
-
[r, g, b] = [v, t, p];
|
|
1461
|
-
break;
|
|
1462
|
-
case 1:
|
|
1463
|
-
[r, g, b] = [q, v, p];
|
|
1464
|
-
break;
|
|
1465
|
-
case 2:
|
|
1466
|
-
[r, g, b] = [p, v, t];
|
|
1467
|
-
break;
|
|
1468
|
-
case 3:
|
|
1469
|
-
[r, g, b] = [p, q, v];
|
|
1470
|
-
break;
|
|
1471
|
-
case 4:
|
|
1472
|
-
[r, g, b] = [t, p, v];
|
|
1473
|
-
break;
|
|
1474
|
-
case 5:
|
|
1475
|
-
[r, g, b] = [v, p, q];
|
|
1476
|
-
break;
|
|
1477
|
-
}
|
|
1478
|
-
}
|
|
1479
|
-
return [r, g, b, args.length > 3 ? args[3] : 1];
|
|
1480
|
-
};
|
|
1481
|
-
|
|
1482
|
-
const { min: min$1, max: max$2 } = Math;
|
|
1483
|
-
|
|
1484
|
-
/*
|
|
1485
|
-
* supported arguments:
|
|
1486
|
-
* - rgb2hsv(r,g,b)
|
|
1487
|
-
* - rgb2hsv([r,g,b])
|
|
1488
|
-
* - rgb2hsv({r,g,b})
|
|
1489
|
-
*/
|
|
1490
|
-
const rgb2hsl = (...args) => {
|
|
1491
|
-
args = unpack(args, 'rgb');
|
|
1492
|
-
let [r, g, b] = args;
|
|
1493
|
-
const min_ = min$1(r, g, b);
|
|
1494
|
-
const max_ = max$2(r, g, b);
|
|
1495
|
-
const delta = max_ - min_;
|
|
1496
|
-
let h, s, v;
|
|
1497
|
-
v = max_ / 255.0;
|
|
1498
|
-
if (max_ === 0) {
|
|
1499
|
-
h = Number.NaN;
|
|
1500
|
-
s = 0;
|
|
1501
|
-
} else {
|
|
1502
|
-
s = delta / max_;
|
|
1503
|
-
if (r === max_) h = (g - b) / delta;
|
|
1504
|
-
if (g === max_) h = 2 + (b - r) / delta;
|
|
1505
|
-
if (b === max_) h = 4 + (r - g) / delta;
|
|
1506
|
-
h *= 60;
|
|
1507
|
-
if (h < 0) h += 360;
|
|
1508
|
-
}
|
|
1509
|
-
return [h, s, v];
|
|
1510
|
-
};
|
|
1511
|
-
|
|
1512
|
-
Color.prototype.hsv = function () {
|
|
1513
|
-
return rgb2hsl(this._rgb);
|
|
1514
|
-
};
|
|
1515
|
-
|
|
1516
|
-
const hsv$1 = (...args) => new Color(...args, 'hsv');
|
|
1517
|
-
chroma.hsv = hsv$1;
|
|
1518
|
-
|
|
1519
|
-
input.format.hsv = hsv2rgb;
|
|
1520
|
-
|
|
1521
|
-
input.autodetect.push({
|
|
1522
|
-
p: 2,
|
|
1523
|
-
test: (...args) => {
|
|
1524
|
-
args = unpack(args, 'hsv');
|
|
1525
|
-
if (type(args) === 'array' && args.length === 3) {
|
|
1526
|
-
return 'hsv';
|
|
1527
|
-
}
|
|
1528
|
-
}
|
|
1529
|
-
});
|
|
1530
|
-
|
|
1531
|
-
const hsv = (col1, col2, f) => {
|
|
1532
|
-
return interpolate_hsx(col1, col2, f, 'hsv');
|
|
1533
|
-
};
|
|
1534
|
-
|
|
1535
|
-
// register interpolator
|
|
1536
|
-
index.hsv = hsv;
|
|
1537
|
-
|
|
1538
|
-
// from https://www.w3.org/TR/css-color-4/multiply-matrices.js
|
|
1539
|
-
function multiplyMatrices(A, B) {
|
|
1540
|
-
let m = A.length;
|
|
1541
|
-
|
|
1542
|
-
if (!Array.isArray(A[0])) {
|
|
1543
|
-
// A is vector, convert to [[a, b, c, ...]]
|
|
1544
|
-
A = [A];
|
|
1545
|
-
}
|
|
1546
|
-
|
|
1547
|
-
if (!Array.isArray(B[0])) {
|
|
1548
|
-
// B is vector, convert to [[a], [b], [c], ...]]
|
|
1549
|
-
B = B.map((x) => [x]);
|
|
1550
|
-
}
|
|
1551
|
-
|
|
1552
|
-
let p = B[0].length;
|
|
1553
|
-
let B_cols = B[0].map((_, i) => B.map((x) => x[i])); // transpose B
|
|
1554
|
-
let product = A.map((row) =>
|
|
1555
|
-
B_cols.map((col) => {
|
|
1556
|
-
if (!Array.isArray(row)) {
|
|
1557
|
-
return col.reduce((a, c) => a + c * row, 0);
|
|
1558
|
-
}
|
|
1559
|
-
|
|
1560
|
-
return row.reduce((a, c, i) => a + c * (col[i] || 0), 0);
|
|
1561
|
-
})
|
|
1562
|
-
);
|
|
1563
|
-
|
|
1564
|
-
if (m === 1) {
|
|
1565
|
-
product = product[0]; // Avoid [[a, b, c, ...]]
|
|
1566
|
-
}
|
|
1567
|
-
|
|
1568
|
-
if (p === 1) {
|
|
1569
|
-
return product.map((x) => x[0]); // Avoid [[a], [b], [c], ...]]
|
|
1570
|
-
}
|
|
1571
|
-
|
|
1572
|
-
return product;
|
|
1573
|
-
}
|
|
1574
|
-
|
|
1575
|
-
const oklab2rgb = (...args) => {
|
|
1576
|
-
args = unpack(args, 'lab');
|
|
1577
|
-
const [L, a, b, ...rest] = args;
|
|
1578
|
-
const [X, Y, Z] = OKLab_to_XYZ([L, a, b]);
|
|
1579
|
-
const [r, g, b_] = xyz2rgb(X, Y, Z);
|
|
1580
|
-
return [r, g, b_, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
|
|
1581
|
-
};
|
|
1582
|
-
|
|
1583
|
-
// from https://www.w3.org/TR/css-color-4/#color-conversion-code
|
|
1584
|
-
function OKLab_to_XYZ(OKLab) {
|
|
1585
|
-
// Given OKLab, convert to XYZ relative to D65
|
|
1586
|
-
var LMStoXYZ = [
|
|
1587
|
-
[1.2268798758459243, -0.5578149944602171, 0.2813910456659647],
|
|
1588
|
-
[-0.0405757452148008, 1.112286803280317, -0.0717110580655164],
|
|
1589
|
-
[-0.0763729366746601, -0.4214933324022432, 1.5869240198367816]
|
|
1590
|
-
];
|
|
1591
|
-
var OKLabtoLMS = [
|
|
1592
|
-
[1.0, 0.3963377773761749, 0.2158037573099136],
|
|
1593
|
-
[1.0, -0.1055613458156586, -0.0638541728258133],
|
|
1594
|
-
[1.0, -0.0894841775298119, -1.2914855480194092]
|
|
1595
|
-
];
|
|
1596
|
-
|
|
1597
|
-
var LMSnl = multiplyMatrices(OKLabtoLMS, OKLab);
|
|
1598
|
-
return multiplyMatrices(
|
|
1599
|
-
LMStoXYZ,
|
|
1600
|
-
LMSnl.map((c) => c ** 3)
|
|
1601
|
-
);
|
|
1602
|
-
}
|
|
1603
|
-
|
|
1604
|
-
const rgb2oklab = (...args) => {
|
|
1605
|
-
const [r, g, b, ...rest] = unpack(args, 'rgb');
|
|
1606
|
-
const xyz = rgb2xyz(r, g, b);
|
|
1607
|
-
const oklab = XYZ_to_OKLab(xyz);
|
|
1608
|
-
return [...oklab, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
|
|
1609
|
-
};
|
|
1610
|
-
|
|
1611
|
-
// from https://www.w3.org/TR/css-color-4/#color-conversion-code
|
|
1612
|
-
function XYZ_to_OKLab(XYZ) {
|
|
1613
|
-
// Given XYZ relative to D65, convert to OKLab
|
|
1614
|
-
const XYZtoLMS = [
|
|
1615
|
-
[0.819022437996703, 0.3619062600528904, -0.1288737815209879],
|
|
1616
|
-
[0.0329836539323885, 0.9292868615863434, 0.0361446663506424],
|
|
1617
|
-
[0.0481771893596242, 0.2642395317527308, 0.6335478284694309]
|
|
1618
|
-
];
|
|
1619
|
-
const LMStoOKLab = [
|
|
1620
|
-
[0.210454268309314, 0.7936177747023054, -0.0040720430116193],
|
|
1621
|
-
[1.9779985324311684, -2.4285922420485799, 0.450593709617411],
|
|
1622
|
-
[0.0259040424655478, 0.7827717124575296, -0.8086757549230774]
|
|
1623
|
-
];
|
|
1624
|
-
|
|
1625
|
-
const LMS = multiplyMatrices(XYZtoLMS, XYZ);
|
|
1626
|
-
// JavaScript Math.cbrt returns a sign-matched cube root
|
|
1627
|
-
// beware if porting to other languages
|
|
1628
|
-
// especially if tempted to use a general power function
|
|
1629
|
-
return multiplyMatrices(
|
|
1630
|
-
LMStoOKLab,
|
|
1631
|
-
LMS.map((c) => Math.cbrt(c))
|
|
1632
|
-
);
|
|
1633
|
-
// L in range [0,1]. For use in CSS, multiply by 100 and add a percent
|
|
1634
|
-
}
|
|
1635
|
-
|
|
1636
|
-
Color.prototype.oklab = function () {
|
|
1637
|
-
return rgb2oklab(this._rgb);
|
|
1638
|
-
};
|
|
1639
|
-
|
|
1640
|
-
const oklab$1 = (...args) => new Color(...args, 'oklab');
|
|
1641
|
-
Object.assign(chroma, { oklab: oklab$1 });
|
|
1642
|
-
|
|
1643
|
-
input.format.oklab = oklab2rgb;
|
|
1644
|
-
|
|
1645
|
-
input.autodetect.push({
|
|
1646
|
-
p: 2,
|
|
1647
|
-
test: (...args) => {
|
|
1648
|
-
args = unpack(args, 'oklab');
|
|
1649
|
-
if (type(args) === 'array' && args.length === 3) {
|
|
1650
|
-
return 'oklab';
|
|
1651
|
-
}
|
|
1652
|
-
}
|
|
1653
|
-
});
|
|
1654
|
-
|
|
1655
|
-
const oklab = (col1, col2, f) => {
|
|
1656
|
-
const xyz0 = col1.oklab();
|
|
1657
|
-
const xyz1 = col2.oklab();
|
|
1658
|
-
return new Color(
|
|
1659
|
-
xyz0[0] + f * (xyz1[0] - xyz0[0]),
|
|
1660
|
-
xyz0[1] + f * (xyz1[1] - xyz0[1]),
|
|
1661
|
-
xyz0[2] + f * (xyz1[2] - xyz0[2]),
|
|
1662
|
-
'oklab'
|
|
1663
|
-
);
|
|
1664
|
-
};
|
|
1665
|
-
|
|
1666
|
-
// register interpolator
|
|
1667
|
-
index.oklab = oklab;
|
|
1668
|
-
|
|
1669
|
-
const oklch$1 = (col1, col2, f) => {
|
|
1670
|
-
return interpolate_hsx(col1, col2, f, 'oklch');
|
|
1671
|
-
};
|
|
1672
|
-
|
|
1673
|
-
// register interpolator
|
|
1674
|
-
index.oklch = oklch$1;
|
|
1675
|
-
|
|
1676
|
-
const { pow: pow$4, sqrt: sqrt$1, PI: PI$1, cos: cos$2, sin: sin$2, atan2: atan2$1 } = Math;
|
|
1677
|
-
|
|
1678
|
-
const average = (colors, mode = 'lrgb', weights = null) => {
|
|
1679
|
-
const l = colors.length;
|
|
1680
|
-
if (!weights) weights = Array.from(new Array(l)).map(() => 1);
|
|
1681
|
-
// normalize weights
|
|
1682
|
-
const k =
|
|
1683
|
-
l /
|
|
1684
|
-
weights.reduce(function (a, b) {
|
|
1685
|
-
return a + b;
|
|
1686
|
-
});
|
|
1687
|
-
weights.forEach((w, i) => {
|
|
1688
|
-
weights[i] *= k;
|
|
1689
|
-
});
|
|
1690
|
-
// convert colors to Color objects
|
|
1691
|
-
colors = colors.map((c) => new Color(c));
|
|
1692
|
-
if (mode === 'lrgb') {
|
|
1693
|
-
return _average_lrgb(colors, weights);
|
|
1694
|
-
}
|
|
1695
|
-
const first = colors.shift();
|
|
1696
|
-
const xyz = first.get(mode);
|
|
1697
|
-
const cnt = [];
|
|
1698
|
-
let dx = 0;
|
|
1699
|
-
let dy = 0;
|
|
1700
|
-
// initial color
|
|
1701
|
-
for (let i = 0; i < xyz.length; i++) {
|
|
1702
|
-
xyz[i] = (xyz[i] || 0) * weights[0];
|
|
1703
|
-
cnt.push(isNaN(xyz[i]) ? 0 : weights[0]);
|
|
1704
|
-
if (mode.charAt(i) === 'h' && !isNaN(xyz[i])) {
|
|
1705
|
-
const A = (xyz[i] / 180) * PI$1;
|
|
1706
|
-
dx += cos$2(A) * weights[0];
|
|
1707
|
-
dy += sin$2(A) * weights[0];
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
|
|
1711
|
-
let alpha = first.alpha() * weights[0];
|
|
1712
|
-
colors.forEach((c, ci) => {
|
|
1713
|
-
const xyz2 = c.get(mode);
|
|
1714
|
-
alpha += c.alpha() * weights[ci + 1];
|
|
1715
|
-
for (let i = 0; i < xyz.length; i++) {
|
|
1716
|
-
if (!isNaN(xyz2[i])) {
|
|
1717
|
-
cnt[i] += weights[ci + 1];
|
|
1718
|
-
if (mode.charAt(i) === 'h') {
|
|
1719
|
-
const A = (xyz2[i] / 180) * PI$1;
|
|
1720
|
-
dx += cos$2(A) * weights[ci + 1];
|
|
1721
|
-
dy += sin$2(A) * weights[ci + 1];
|
|
1722
|
-
} else {
|
|
1723
|
-
xyz[i] += xyz2[i] * weights[ci + 1];
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
|
-
}
|
|
1727
|
-
});
|
|
1728
|
-
|
|
1729
|
-
for (let i = 0; i < xyz.length; i++) {
|
|
1730
|
-
if (mode.charAt(i) === 'h') {
|
|
1731
|
-
let A = (atan2$1(dy / cnt[i], dx / cnt[i]) / PI$1) * 180;
|
|
1732
|
-
while (A < 0) A += 360;
|
|
1733
|
-
while (A >= 360) A -= 360;
|
|
1734
|
-
xyz[i] = A;
|
|
1735
|
-
} else {
|
|
1736
|
-
xyz[i] = xyz[i] / cnt[i];
|
|
1737
|
-
}
|
|
1738
|
-
}
|
|
1739
|
-
alpha /= l;
|
|
1740
|
-
return new Color(xyz, mode).alpha(alpha > 0.99999 ? 1 : alpha, true);
|
|
1741
|
-
};
|
|
1742
|
-
|
|
1743
|
-
const _average_lrgb = (colors, weights) => {
|
|
1744
|
-
const l = colors.length;
|
|
1745
|
-
const xyz = [0, 0, 0, 0];
|
|
1746
|
-
for (let i = 0; i < colors.length; i++) {
|
|
1747
|
-
const col = colors[i];
|
|
1748
|
-
const f = weights[i] / l;
|
|
1749
|
-
const rgb = col._rgb;
|
|
1750
|
-
xyz[0] += pow$4(rgb[0], 2) * f;
|
|
1751
|
-
xyz[1] += pow$4(rgb[1], 2) * f;
|
|
1752
|
-
xyz[2] += pow$4(rgb[2], 2) * f;
|
|
1753
|
-
xyz[3] += rgb[3] * f;
|
|
1754
|
-
}
|
|
1755
|
-
xyz[0] = sqrt$1(xyz[0]);
|
|
1756
|
-
xyz[1] = sqrt$1(xyz[1]);
|
|
1757
|
-
xyz[2] = sqrt$1(xyz[2]);
|
|
1758
|
-
if (xyz[3] > 0.9999999) xyz[3] = 1;
|
|
1759
|
-
return new Color(clip_rgb(xyz));
|
|
1760
|
-
};
|
|
1761
|
-
|
|
1762
|
-
// minimal multi-purpose interface
|
|
1763
|
-
|
|
1764
|
-
const { pow: pow$3 } = Math;
|
|
1765
|
-
|
|
1766
|
-
function scale (colors) {
|
|
1767
|
-
// constructor
|
|
1768
|
-
let _mode = 'rgb';
|
|
1769
|
-
let _nacol = chroma('#ccc');
|
|
1770
|
-
let _spread = 0;
|
|
1771
|
-
// const _fixed = false;
|
|
1772
|
-
let _domain = [0, 1];
|
|
1773
|
-
let _pos = [];
|
|
1774
|
-
let _padding = [0, 0];
|
|
1775
|
-
let _classes = false;
|
|
1776
|
-
let _colors = [];
|
|
1777
|
-
let _out = false;
|
|
1778
|
-
let _min = 0;
|
|
1779
|
-
let _max = 1;
|
|
1780
|
-
let _correctLightness = false;
|
|
1781
|
-
let _colorCache = {};
|
|
1782
|
-
let _useCache = true;
|
|
1783
|
-
let _gamma = 1;
|
|
1784
|
-
|
|
1785
|
-
// private methods
|
|
1786
|
-
|
|
1787
|
-
const setColors = function (colors) {
|
|
1788
|
-
colors = colors || ['#fff', '#000'];
|
|
1789
|
-
if (
|
|
1790
|
-
colors &&
|
|
1791
|
-
type(colors) === 'string' &&
|
|
1792
|
-
chroma.brewer &&
|
|
1793
|
-
chroma.brewer[colors.toLowerCase()]
|
|
1794
|
-
) {
|
|
1795
|
-
colors = chroma.brewer[colors.toLowerCase()];
|
|
1796
|
-
}
|
|
1797
|
-
if (type(colors) === 'array') {
|
|
1798
|
-
// handle single color
|
|
1799
|
-
if (colors.length === 1) {
|
|
1800
|
-
colors = [colors[0], colors[0]];
|
|
1801
|
-
}
|
|
1802
|
-
// make a copy of the colors
|
|
1803
|
-
colors = colors.slice(0);
|
|
1804
|
-
// convert to chroma classes
|
|
1805
|
-
for (let c = 0; c < colors.length; c++) {
|
|
1806
|
-
colors[c] = chroma(colors[c]);
|
|
1807
|
-
}
|
|
1808
|
-
// auto-fill color position
|
|
1809
|
-
_pos.length = 0;
|
|
1810
|
-
for (let c = 0; c < colors.length; c++) {
|
|
1811
|
-
_pos.push(c / (colors.length - 1));
|
|
1812
|
-
}
|
|
1813
|
-
}
|
|
1814
|
-
resetCache();
|
|
1815
|
-
return (_colors = colors);
|
|
1816
|
-
};
|
|
1817
|
-
|
|
1818
|
-
const getClass = function (value) {
|
|
1819
|
-
if (_classes != null) {
|
|
1820
|
-
const n = _classes.length - 1;
|
|
1821
|
-
let i = 0;
|
|
1822
|
-
while (i < n && value >= _classes[i]) {
|
|
1823
|
-
i++;
|
|
1824
|
-
}
|
|
1825
|
-
return i - 1;
|
|
1826
|
-
}
|
|
1827
|
-
return 0;
|
|
1828
|
-
};
|
|
1829
|
-
|
|
1830
|
-
let tMapLightness = (t) => t;
|
|
1831
|
-
let tMapDomain = (t) => t;
|
|
1832
|
-
|
|
1833
|
-
// const classifyValue = function(value) {
|
|
1834
|
-
// let val = value;
|
|
1835
|
-
// if (_classes.length > 2) {
|
|
1836
|
-
// const n = _classes.length-1;
|
|
1837
|
-
// const i = getClass(value);
|
|
1838
|
-
// const minc = _classes[0] + ((_classes[1]-_classes[0]) * (0 + (_spread * 0.5))); // center of 1st class
|
|
1839
|
-
// const maxc = _classes[n-1] + ((_classes[n]-_classes[n-1]) * (1 - (_spread * 0.5))); // center of last class
|
|
1840
|
-
// val = _min + ((((_classes[i] + ((_classes[i+1] - _classes[i]) * 0.5)) - minc) / (maxc-minc)) * (_max - _min));
|
|
1841
|
-
// }
|
|
1842
|
-
// return val;
|
|
1843
|
-
// };
|
|
1844
|
-
|
|
1845
|
-
const getColor = function (val, bypassMap) {
|
|
1846
|
-
let col, t;
|
|
1847
|
-
if (bypassMap == null) {
|
|
1848
|
-
bypassMap = false;
|
|
1849
|
-
}
|
|
1850
|
-
if (isNaN(val) || val === null) {
|
|
1851
|
-
return _nacol;
|
|
1852
|
-
}
|
|
1853
|
-
if (!bypassMap) {
|
|
1854
|
-
if (_classes && _classes.length > 2) {
|
|
1855
|
-
// find the class
|
|
1856
|
-
const c = getClass(val);
|
|
1857
|
-
t = c / (_classes.length - 2);
|
|
1858
|
-
} else if (_max !== _min) {
|
|
1859
|
-
// just interpolate between min/max
|
|
1860
|
-
t = (val - _min) / (_max - _min);
|
|
1861
|
-
} else {
|
|
1862
|
-
t = 1;
|
|
1863
|
-
}
|
|
1864
|
-
} else {
|
|
1865
|
-
t = val;
|
|
1866
|
-
}
|
|
1867
|
-
|
|
1868
|
-
// domain map
|
|
1869
|
-
t = tMapDomain(t);
|
|
1870
|
-
|
|
1871
|
-
if (!bypassMap) {
|
|
1872
|
-
t = tMapLightness(t); // lightness correction
|
|
1873
|
-
}
|
|
1874
|
-
|
|
1875
|
-
if (_gamma !== 1) {
|
|
1876
|
-
t = pow$3(t, _gamma);
|
|
1877
|
-
}
|
|
1878
|
-
|
|
1879
|
-
t = _padding[0] + t * (1 - _padding[0] - _padding[1]);
|
|
1880
|
-
|
|
1881
|
-
t = limit(t, 0, 1);
|
|
1882
|
-
|
|
1883
|
-
const k = Math.floor(t * 10000);
|
|
1884
|
-
|
|
1885
|
-
if (_useCache && _colorCache[k]) {
|
|
1886
|
-
col = _colorCache[k];
|
|
1887
|
-
} else {
|
|
1888
|
-
if (type(_colors) === 'array') {
|
|
1889
|
-
//for i in [0.._pos.length-1]
|
|
1890
|
-
for (let i = 0; i < _pos.length; i++) {
|
|
1891
|
-
const p = _pos[i];
|
|
1892
|
-
if (t <= p) {
|
|
1893
|
-
col = _colors[i];
|
|
1894
|
-
break;
|
|
1895
|
-
}
|
|
1896
|
-
if (t >= p && i === _pos.length - 1) {
|
|
1897
|
-
col = _colors[i];
|
|
1898
|
-
break;
|
|
1899
|
-
}
|
|
1900
|
-
if (t > p && t < _pos[i + 1]) {
|
|
1901
|
-
t = (t - p) / (_pos[i + 1] - p);
|
|
1902
|
-
col = chroma.interpolate(
|
|
1903
|
-
_colors[i],
|
|
1904
|
-
_colors[i + 1],
|
|
1905
|
-
t,
|
|
1906
|
-
_mode
|
|
1907
|
-
);
|
|
1908
|
-
break;
|
|
1909
|
-
}
|
|
1910
|
-
}
|
|
1911
|
-
} else if (type(_colors) === 'function') {
|
|
1912
|
-
col = _colors(t);
|
|
1913
|
-
}
|
|
1914
|
-
if (_useCache) {
|
|
1915
|
-
_colorCache[k] = col;
|
|
1916
|
-
}
|
|
1917
|
-
}
|
|
1918
|
-
return col;
|
|
1919
|
-
};
|
|
1920
|
-
|
|
1921
|
-
var resetCache = () => (_colorCache = {});
|
|
1922
|
-
|
|
1923
|
-
setColors(colors);
|
|
1924
|
-
|
|
1925
|
-
// public interface
|
|
1926
|
-
|
|
1927
|
-
const f = function (v) {
|
|
1928
|
-
const c = chroma(getColor(v));
|
|
1929
|
-
if (_out && c[_out]) {
|
|
1930
|
-
return c[_out]();
|
|
1931
|
-
} else {
|
|
1932
|
-
return c;
|
|
1933
|
-
}
|
|
1934
|
-
};
|
|
1935
|
-
|
|
1936
|
-
f.classes = function (classes) {
|
|
1937
|
-
if (classes != null) {
|
|
1938
|
-
if (type(classes) === 'array') {
|
|
1939
|
-
_classes = classes;
|
|
1940
|
-
_domain = [classes[0], classes[classes.length - 1]];
|
|
1941
|
-
} else {
|
|
1942
|
-
const d = chroma.analyze(_domain);
|
|
1943
|
-
if (classes === 0) {
|
|
1944
|
-
_classes = [d.min, d.max];
|
|
1945
|
-
} else {
|
|
1946
|
-
_classes = chroma.limits(d, 'e', classes);
|
|
1947
|
-
}
|
|
1948
|
-
}
|
|
1949
|
-
return f;
|
|
1950
|
-
}
|
|
1951
|
-
return _classes;
|
|
1952
|
-
};
|
|
1953
|
-
|
|
1954
|
-
f.domain = function (domain) {
|
|
1955
|
-
if (!arguments.length) {
|
|
1956
|
-
return _domain;
|
|
1957
|
-
}
|
|
1958
|
-
_min = domain[0];
|
|
1959
|
-
_max = domain[domain.length - 1];
|
|
1960
|
-
_pos = [];
|
|
1961
|
-
const k = _colors.length;
|
|
1962
|
-
if (domain.length === k && _min !== _max) {
|
|
1963
|
-
// update positions
|
|
1964
|
-
for (let d of Array.from(domain)) {
|
|
1965
|
-
_pos.push((d - _min) / (_max - _min));
|
|
1966
|
-
}
|
|
1967
|
-
} else {
|
|
1968
|
-
for (let c = 0; c < k; c++) {
|
|
1969
|
-
_pos.push(c / (k - 1));
|
|
1970
|
-
}
|
|
1971
|
-
if (domain.length > 2) {
|
|
1972
|
-
// set domain map
|
|
1973
|
-
const tOut = domain.map((d, i) => i / (domain.length - 1));
|
|
1974
|
-
const tBreaks = domain.map((d) => (d - _min) / (_max - _min));
|
|
1975
|
-
if (!tBreaks.every((val, i) => tOut[i] === val)) {
|
|
1976
|
-
tMapDomain = (t) => {
|
|
1977
|
-
if (t <= 0 || t >= 1) return t;
|
|
1978
|
-
let i = 0;
|
|
1979
|
-
while (t >= tBreaks[i + 1]) i++;
|
|
1980
|
-
const f =
|
|
1981
|
-
(t - tBreaks[i]) / (tBreaks[i + 1] - tBreaks[i]);
|
|
1982
|
-
const out = tOut[i] + f * (tOut[i + 1] - tOut[i]);
|
|
1983
|
-
return out;
|
|
1984
|
-
};
|
|
1985
|
-
}
|
|
1986
|
-
}
|
|
1987
|
-
}
|
|
1988
|
-
_domain = [_min, _max];
|
|
1989
|
-
return f;
|
|
1990
|
-
};
|
|
1991
|
-
|
|
1992
|
-
f.mode = function (_m) {
|
|
1993
|
-
if (!arguments.length) {
|
|
1994
|
-
return _mode;
|
|
1995
|
-
}
|
|
1996
|
-
_mode = _m;
|
|
1997
|
-
resetCache();
|
|
1998
|
-
return f;
|
|
1999
|
-
};
|
|
2000
|
-
|
|
2001
|
-
f.range = function (colors, _pos) {
|
|
2002
|
-
setColors(colors);
|
|
2003
|
-
return f;
|
|
2004
|
-
};
|
|
2005
|
-
|
|
2006
|
-
f.out = function (_o) {
|
|
2007
|
-
_out = _o;
|
|
2008
|
-
return f;
|
|
2009
|
-
};
|
|
2010
|
-
|
|
2011
|
-
f.spread = function (val) {
|
|
2012
|
-
if (!arguments.length) {
|
|
2013
|
-
return _spread;
|
|
2014
|
-
}
|
|
2015
|
-
_spread = val;
|
|
2016
|
-
return f;
|
|
2017
|
-
};
|
|
2018
|
-
|
|
2019
|
-
f.correctLightness = function (v) {
|
|
2020
|
-
if (v == null) {
|
|
2021
|
-
v = true;
|
|
2022
|
-
}
|
|
2023
|
-
_correctLightness = v;
|
|
2024
|
-
resetCache();
|
|
2025
|
-
if (_correctLightness) {
|
|
2026
|
-
tMapLightness = function (t) {
|
|
2027
|
-
const L0 = getColor(0, true).lab()[0];
|
|
2028
|
-
const L1 = getColor(1, true).lab()[0];
|
|
2029
|
-
const pol = L0 > L1;
|
|
2030
|
-
let L_actual = getColor(t, true).lab()[0];
|
|
2031
|
-
const L_ideal = L0 + (L1 - L0) * t;
|
|
2032
|
-
let L_diff = L_actual - L_ideal;
|
|
2033
|
-
let t0 = 0;
|
|
2034
|
-
let t1 = 1;
|
|
2035
|
-
let max_iter = 20;
|
|
2036
|
-
while (Math.abs(L_diff) > 1e-2 && max_iter-- > 0) {
|
|
2037
|
-
(function () {
|
|
2038
|
-
if (pol) {
|
|
2039
|
-
L_diff *= -1;
|
|
2040
|
-
}
|
|
2041
|
-
if (L_diff < 0) {
|
|
2042
|
-
t0 = t;
|
|
2043
|
-
t += (t1 - t) * 0.5;
|
|
2044
|
-
} else {
|
|
2045
|
-
t1 = t;
|
|
2046
|
-
t += (t0 - t) * 0.5;
|
|
2047
|
-
}
|
|
2048
|
-
L_actual = getColor(t, true).lab()[0];
|
|
2049
|
-
return (L_diff = L_actual - L_ideal);
|
|
2050
|
-
})();
|
|
2051
|
-
}
|
|
2052
|
-
return t;
|
|
2053
|
-
};
|
|
2054
|
-
} else {
|
|
2055
|
-
tMapLightness = (t) => t;
|
|
2056
|
-
}
|
|
2057
|
-
return f;
|
|
2058
|
-
};
|
|
2059
|
-
|
|
2060
|
-
f.padding = function (p) {
|
|
2061
|
-
if (p != null) {
|
|
2062
|
-
if (type(p) === 'number') {
|
|
2063
|
-
p = [p, p];
|
|
2064
|
-
}
|
|
2065
|
-
_padding = p;
|
|
2066
|
-
return f;
|
|
2067
|
-
} else {
|
|
2068
|
-
return _padding;
|
|
2069
|
-
}
|
|
2070
|
-
};
|
|
2071
|
-
|
|
2072
|
-
f.colors = function (numColors, out) {
|
|
2073
|
-
// If no arguments are given, return the original colors that were provided
|
|
2074
|
-
if (arguments.length < 2) {
|
|
2075
|
-
out = 'hex';
|
|
2076
|
-
}
|
|
2077
|
-
let result = [];
|
|
2078
|
-
|
|
2079
|
-
if (arguments.length === 0) {
|
|
2080
|
-
result = _colors.slice(0);
|
|
2081
|
-
} else if (numColors === 1) {
|
|
2082
|
-
result = [f(0.5)];
|
|
2083
|
-
} else if (numColors > 1) {
|
|
2084
|
-
const dm = _domain[0];
|
|
2085
|
-
const dd = _domain[1] - dm;
|
|
2086
|
-
result = __range__(0, numColors, false).map((i) =>
|
|
2087
|
-
f(dm + (i / (numColors - 1)) * dd)
|
|
2088
|
-
);
|
|
2089
|
-
} else {
|
|
2090
|
-
// returns all colors based on the defined classes
|
|
2091
|
-
colors = [];
|
|
2092
|
-
let samples = [];
|
|
2093
|
-
if (_classes && _classes.length > 2) {
|
|
2094
|
-
for (
|
|
2095
|
-
let i = 1, end = _classes.length, asc = 1 <= end;
|
|
2096
|
-
asc ? i < end : i > end;
|
|
2097
|
-
asc ? i++ : i--
|
|
2098
|
-
) {
|
|
2099
|
-
samples.push((_classes[i - 1] + _classes[i]) * 0.5);
|
|
2100
|
-
}
|
|
2101
|
-
} else {
|
|
2102
|
-
samples = _domain;
|
|
2103
|
-
}
|
|
2104
|
-
result = samples.map((v) => f(v));
|
|
2105
|
-
}
|
|
2106
|
-
|
|
2107
|
-
if (chroma[out]) {
|
|
2108
|
-
result = result.map((c) => c[out]());
|
|
2109
|
-
}
|
|
2110
|
-
return result;
|
|
2111
|
-
};
|
|
2112
|
-
|
|
2113
|
-
f.cache = function (c) {
|
|
2114
|
-
if (c != null) {
|
|
2115
|
-
_useCache = c;
|
|
2116
|
-
return f;
|
|
2117
|
-
} else {
|
|
2118
|
-
return _useCache;
|
|
2119
|
-
}
|
|
2120
|
-
};
|
|
2121
|
-
|
|
2122
|
-
f.gamma = function (g) {
|
|
2123
|
-
if (g != null) {
|
|
2124
|
-
_gamma = g;
|
|
2125
|
-
return f;
|
|
2126
|
-
} else {
|
|
2127
|
-
return _gamma;
|
|
2128
|
-
}
|
|
2129
|
-
};
|
|
2130
|
-
|
|
2131
|
-
f.nodata = function (d) {
|
|
2132
|
-
if (d != null) {
|
|
2133
|
-
_nacol = chroma(d);
|
|
2134
|
-
return f;
|
|
2135
|
-
} else {
|
|
2136
|
-
return _nacol;
|
|
2137
|
-
}
|
|
2138
|
-
};
|
|
2139
|
-
|
|
2140
|
-
return f;
|
|
2141
|
-
}
|
|
2142
|
-
|
|
2143
|
-
function __range__(left, right, inclusive) {
|
|
2144
|
-
let range = [];
|
|
2145
|
-
let ascending = left < right;
|
|
2146
|
-
let end = !inclusive ? right : ascending ? right + 1 : right - 1;
|
|
2147
|
-
for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
|
|
2148
|
-
range.push(i);
|
|
2149
|
-
}
|
|
2150
|
-
return range;
|
|
2151
|
-
}
|
|
2152
|
-
|
|
2153
|
-
//
|
|
2154
|
-
|
|
2155
|
-
// nth row of the pascal triangle
|
|
2156
|
-
const binom_row = function (n) {
|
|
2157
|
-
let row = [1, 1];
|
|
2158
|
-
for (let i = 1; i < n; i++) {
|
|
2159
|
-
let newrow = [1];
|
|
2160
|
-
for (let j = 1; j <= row.length; j++) {
|
|
2161
|
-
newrow[j] = (row[j] || 0) + row[j - 1];
|
|
2162
|
-
}
|
|
2163
|
-
row = newrow;
|
|
2164
|
-
}
|
|
2165
|
-
return row;
|
|
2166
|
-
};
|
|
2167
|
-
|
|
2168
|
-
const bezier = function (colors) {
|
|
2169
|
-
let I, lab0, lab1, lab2;
|
|
2170
|
-
colors = colors.map((c) => new Color(c));
|
|
2171
|
-
if (colors.length === 2) {
|
|
2172
|
-
// linear interpolation
|
|
2173
|
-
[lab0, lab1] = colors.map((c) => c.lab());
|
|
2174
|
-
I = function (t) {
|
|
2175
|
-
const lab = [0, 1, 2].map((i) => lab0[i] + t * (lab1[i] - lab0[i]));
|
|
2176
|
-
return new Color(lab, 'lab');
|
|
2177
|
-
};
|
|
2178
|
-
} else if (colors.length === 3) {
|
|
2179
|
-
// quadratic bezier interpolation
|
|
2180
|
-
[lab0, lab1, lab2] = colors.map((c) => c.lab());
|
|
2181
|
-
I = function (t) {
|
|
2182
|
-
const lab = [0, 1, 2].map(
|
|
2183
|
-
(i) =>
|
|
2184
|
-
(1 - t) * (1 - t) * lab0[i] +
|
|
2185
|
-
2 * (1 - t) * t * lab1[i] +
|
|
2186
|
-
t * t * lab2[i]
|
|
2187
|
-
);
|
|
2188
|
-
return new Color(lab, 'lab');
|
|
2189
|
-
};
|
|
2190
|
-
} else if (colors.length === 4) {
|
|
2191
|
-
// cubic bezier interpolation
|
|
2192
|
-
let lab3;
|
|
2193
|
-
[lab0, lab1, lab2, lab3] = colors.map((c) => c.lab());
|
|
2194
|
-
I = function (t) {
|
|
2195
|
-
const lab = [0, 1, 2].map(
|
|
2196
|
-
(i) =>
|
|
2197
|
-
(1 - t) * (1 - t) * (1 - t) * lab0[i] +
|
|
2198
|
-
3 * (1 - t) * (1 - t) * t * lab1[i] +
|
|
2199
|
-
3 * (1 - t) * t * t * lab2[i] +
|
|
2200
|
-
t * t * t * lab3[i]
|
|
2201
|
-
);
|
|
2202
|
-
return new Color(lab, 'lab');
|
|
2203
|
-
};
|
|
2204
|
-
} else if (colors.length >= 5) {
|
|
2205
|
-
// general case (degree n bezier)
|
|
2206
|
-
let labs, row, n;
|
|
2207
|
-
labs = colors.map((c) => c.lab());
|
|
2208
|
-
n = colors.length - 1;
|
|
2209
|
-
row = binom_row(n);
|
|
2210
|
-
I = function (t) {
|
|
2211
|
-
const u = 1 - t;
|
|
2212
|
-
const lab = [0, 1, 2].map((i) =>
|
|
2213
|
-
labs.reduce(
|
|
2214
|
-
(sum, el, j) =>
|
|
2215
|
-
sum + row[j] * u ** (n - j) * t ** j * el[i],
|
|
2216
|
-
0
|
|
2217
|
-
)
|
|
2218
|
-
);
|
|
2219
|
-
return new Color(lab, 'lab');
|
|
2220
|
-
};
|
|
2221
|
-
} else {
|
|
2222
|
-
throw new RangeError('No point in running bezier with only one color.');
|
|
2223
|
-
}
|
|
2224
|
-
return I;
|
|
2225
|
-
};
|
|
2226
|
-
|
|
2227
|
-
const bezier$1 = (colors) => {
|
|
2228
|
-
const f = bezier(colors);
|
|
2229
|
-
f.scale = () => scale(f);
|
|
2230
|
-
return f;
|
|
2231
|
-
};
|
|
2232
|
-
|
|
2233
|
-
const { round: round$3 } = Math;
|
|
2234
|
-
|
|
2235
|
-
Color.prototype.rgb = function (rnd = true) {
|
|
2236
|
-
if (rnd === false) return this._rgb.slice(0, 3);
|
|
2237
|
-
return this._rgb.slice(0, 3).map(round$3);
|
|
2238
|
-
};
|
|
2239
|
-
|
|
2240
|
-
Color.prototype.rgba = function (rnd = true) {
|
|
2241
|
-
return this._rgb.slice(0, 4).map((v, i) => {
|
|
2242
|
-
return i < 3 ? (rnd === false ? v : round$3(v)) : v;
|
|
2243
|
-
});
|
|
2244
|
-
};
|
|
2245
|
-
|
|
2246
|
-
const rgb = (...args) => new Color(...args, 'rgb');
|
|
2247
|
-
Object.assign(chroma, { rgb });
|
|
2248
|
-
|
|
2249
|
-
input.format.rgb = (...args) => {
|
|
2250
|
-
const rgba = unpack(args, 'rgba');
|
|
2251
|
-
if (rgba[3] === undefined) rgba[3] = 1;
|
|
2252
|
-
return rgba;
|
|
2253
|
-
};
|
|
2254
|
-
|
|
2255
|
-
input.autodetect.push({
|
|
2256
|
-
p: 3,
|
|
2257
|
-
test: (...args) => {
|
|
2258
|
-
args = unpack(args, 'rgba');
|
|
2259
|
-
if (
|
|
2260
|
-
type(args) === 'array' &&
|
|
2261
|
-
(args.length === 3 ||
|
|
2262
|
-
(args.length === 4 &&
|
|
2263
|
-
type(args[3]) == 'number' &&
|
|
2264
|
-
args[3] >= 0 &&
|
|
2265
|
-
args[3] <= 1))
|
|
2266
|
-
) {
|
|
2267
|
-
return 'rgb';
|
|
2268
|
-
}
|
|
2269
|
-
}
|
|
2270
|
-
});
|
|
2271
|
-
|
|
2272
|
-
/*
|
|
2273
|
-
* interpolates between a set of colors uzing a bezier spline
|
|
2274
|
-
* blend mode formulas taken from https://web.archive.org/web/20180110014946/http://www.venture-ware.com/kevin/coding/lets-learn-math-photoshop-blend-modes/
|
|
2275
|
-
*/
|
|
2276
|
-
|
|
2277
|
-
const blend = (bottom, top, mode) => {
|
|
2278
|
-
if (!blend[mode]) {
|
|
2279
|
-
throw new Error('unknown blend mode ' + mode);
|
|
2280
|
-
}
|
|
2281
|
-
return blend[mode](bottom, top);
|
|
2282
|
-
};
|
|
2283
|
-
|
|
2284
|
-
const blend_f = (f) => (bottom, top) => {
|
|
2285
|
-
const c0 = chroma(top).rgb();
|
|
2286
|
-
const c1 = chroma(bottom).rgb();
|
|
2287
|
-
return chroma.rgb(f(c0, c1));
|
|
2288
|
-
};
|
|
2289
|
-
|
|
2290
|
-
const each = (f) => (c0, c1) => {
|
|
2291
|
-
const out = [];
|
|
2292
|
-
out[0] = f(c0[0], c1[0]);
|
|
2293
|
-
out[1] = f(c0[1], c1[1]);
|
|
2294
|
-
out[2] = f(c0[2], c1[2]);
|
|
2295
|
-
return out;
|
|
2296
|
-
};
|
|
2297
|
-
|
|
2298
|
-
const normal = (a) => a;
|
|
2299
|
-
const multiply = (a, b) => (a * b) / 255;
|
|
2300
|
-
const darken = (a, b) => (a > b ? b : a);
|
|
2301
|
-
const lighten = (a, b) => (a > b ? a : b);
|
|
2302
|
-
const screen = (a, b) => 255 * (1 - (1 - a / 255) * (1 - b / 255));
|
|
2303
|
-
const overlay = (a, b) =>
|
|
2304
|
-
b < 128 ? (2 * a * b) / 255 : 255 * (1 - 2 * (1 - a / 255) * (1 - b / 255));
|
|
2305
|
-
const burn = (a, b) => 255 * (1 - (1 - b / 255) / (a / 255));
|
|
2306
|
-
const dodge = (a, b) => {
|
|
2307
|
-
if (a === 255) return 255;
|
|
2308
|
-
a = (255 * (b / 255)) / (1 - a / 255);
|
|
2309
|
-
return a > 255 ? 255 : a;
|
|
2310
|
-
};
|
|
2311
|
-
|
|
2312
|
-
// # add = (a,b) ->
|
|
2313
|
-
// # if (a + b > 255) then 255 else a + b
|
|
2314
|
-
|
|
2315
|
-
blend.normal = blend_f(each(normal));
|
|
2316
|
-
blend.multiply = blend_f(each(multiply));
|
|
2317
|
-
blend.screen = blend_f(each(screen));
|
|
2318
|
-
blend.overlay = blend_f(each(overlay));
|
|
2319
|
-
blend.darken = blend_f(each(darken));
|
|
2320
|
-
blend.lighten = blend_f(each(lighten));
|
|
2321
|
-
blend.dodge = blend_f(each(dodge));
|
|
2322
|
-
blend.burn = blend_f(each(burn));
|
|
2323
|
-
|
|
2324
|
-
// cubehelix interpolation
|
|
2325
|
-
const { pow: pow$2, sin: sin$1, cos: cos$1 } = Math;
|
|
2326
|
-
|
|
2327
|
-
function cubehelix (
|
|
2328
|
-
start = 300,
|
|
2329
|
-
rotations = -1.5,
|
|
2330
|
-
hue = 1,
|
|
2331
|
-
gamma = 1,
|
|
2332
|
-
lightness = [0, 1]
|
|
2333
|
-
) {
|
|
2334
|
-
let dh = 0,
|
|
2335
|
-
dl;
|
|
2336
|
-
if (type(lightness) === 'array') {
|
|
2337
|
-
dl = lightness[1] - lightness[0];
|
|
2338
|
-
} else {
|
|
2339
|
-
dl = 0;
|
|
2340
|
-
lightness = [lightness, lightness];
|
|
2341
|
-
}
|
|
2342
|
-
const f = function (fract) {
|
|
2343
|
-
const a = TWOPI * ((start + 120) / 360 + rotations * fract);
|
|
2344
|
-
const l = pow$2(lightness[0] + dl * fract, gamma);
|
|
2345
|
-
const h = dh !== 0 ? hue[0] + fract * dh : hue;
|
|
2346
|
-
const amp = (h * l * (1 - l)) / 2;
|
|
2347
|
-
const cos_a = cos$1(a);
|
|
2348
|
-
const sin_a = sin$1(a);
|
|
2349
|
-
const r = l + amp * (-0.14861 * cos_a + 1.78277 * sin_a);
|
|
2350
|
-
const g = l + amp * (-0.29227 * cos_a - 0.90649 * sin_a);
|
|
2351
|
-
const b = l + amp * (+1.97294 * cos_a);
|
|
2352
|
-
return chroma(clip_rgb([r * 255, g * 255, b * 255, 1]));
|
|
2353
|
-
};
|
|
2354
|
-
f.start = function (s) {
|
|
2355
|
-
if (s == null) {
|
|
2356
|
-
return start;
|
|
2357
|
-
}
|
|
2358
|
-
start = s;
|
|
2359
|
-
return f;
|
|
2360
|
-
};
|
|
2361
|
-
f.rotations = function (r) {
|
|
2362
|
-
if (r == null) {
|
|
2363
|
-
return rotations;
|
|
2364
|
-
}
|
|
2365
|
-
rotations = r;
|
|
2366
|
-
return f;
|
|
2367
|
-
};
|
|
2368
|
-
f.gamma = function (g) {
|
|
2369
|
-
if (g == null) {
|
|
2370
|
-
return gamma;
|
|
2371
|
-
}
|
|
2372
|
-
gamma = g;
|
|
2373
|
-
return f;
|
|
2374
|
-
};
|
|
2375
|
-
f.hue = function (h) {
|
|
2376
|
-
if (h == null) {
|
|
2377
|
-
return hue;
|
|
2378
|
-
}
|
|
2379
|
-
hue = h;
|
|
2380
|
-
if (type(hue) === 'array') {
|
|
2381
|
-
dh = hue[1] - hue[0];
|
|
2382
|
-
if (dh === 0) {
|
|
2383
|
-
hue = hue[1];
|
|
2384
|
-
}
|
|
2385
|
-
} else {
|
|
2386
|
-
dh = 0;
|
|
2387
|
-
}
|
|
2388
|
-
return f;
|
|
2389
|
-
};
|
|
2390
|
-
f.lightness = function (h) {
|
|
2391
|
-
if (h == null) {
|
|
2392
|
-
return lightness;
|
|
2393
|
-
}
|
|
2394
|
-
if (type(h) === 'array') {
|
|
2395
|
-
lightness = h;
|
|
2396
|
-
dl = h[1] - h[0];
|
|
2397
|
-
} else {
|
|
2398
|
-
lightness = [h, h];
|
|
2399
|
-
dl = 0;
|
|
2400
|
-
}
|
|
2401
|
-
return f;
|
|
2402
|
-
};
|
|
2403
|
-
f.scale = () => chroma.scale(f);
|
|
2404
|
-
f.hue(hue);
|
|
2405
|
-
return f;
|
|
2406
|
-
}
|
|
2407
|
-
|
|
2408
|
-
const digits = '0123456789abcdef';
|
|
2409
|
-
|
|
2410
|
-
const { floor: floor$1, random } = Math;
|
|
2411
|
-
|
|
2412
|
-
const random$1 = () => {
|
|
2413
|
-
let code = '#';
|
|
2414
|
-
for (let i = 0; i < 6; i++) {
|
|
2415
|
-
code += digits.charAt(floor$1(random() * 16));
|
|
2416
|
-
}
|
|
2417
|
-
return new Color(code, 'hex');
|
|
2418
|
-
};
|
|
2419
|
-
|
|
2420
|
-
const { log: log$1, pow: pow$1, floor, abs: abs$1 } = Math;
|
|
2421
|
-
|
|
2422
|
-
function analyze(data, key = null) {
|
|
2423
|
-
const r = {
|
|
2424
|
-
min: Number.MAX_VALUE,
|
|
2425
|
-
max: Number.MAX_VALUE * -1,
|
|
2426
|
-
sum: 0,
|
|
2427
|
-
values: [],
|
|
2428
|
-
count: 0
|
|
2429
|
-
};
|
|
2430
|
-
if (type(data) === 'object') {
|
|
2431
|
-
data = Object.values(data);
|
|
2432
|
-
}
|
|
2433
|
-
data.forEach((val) => {
|
|
2434
|
-
if (key && type(val) === 'object') val = val[key];
|
|
2435
|
-
if (val !== undefined && val !== null && !isNaN(val)) {
|
|
2436
|
-
r.values.push(val);
|
|
2437
|
-
r.sum += val;
|
|
2438
|
-
if (val < r.min) r.min = val;
|
|
2439
|
-
if (val > r.max) r.max = val;
|
|
2440
|
-
r.count += 1;
|
|
2441
|
-
}
|
|
2442
|
-
});
|
|
2443
|
-
|
|
2444
|
-
r.domain = [r.min, r.max];
|
|
2445
|
-
|
|
2446
|
-
r.limits = (mode, num) => limits(r, mode, num);
|
|
2447
|
-
|
|
2448
|
-
return r;
|
|
2449
|
-
}
|
|
2450
|
-
|
|
2451
|
-
function limits(data, mode = 'equal', num = 7) {
|
|
2452
|
-
if (type(data) == 'array') {
|
|
2453
|
-
data = analyze(data);
|
|
2454
|
-
}
|
|
2455
|
-
const { min, max } = data;
|
|
2456
|
-
const values = data.values.sort((a, b) => a - b);
|
|
2457
|
-
|
|
2458
|
-
if (num === 1) {
|
|
2459
|
-
return [min, max];
|
|
2460
|
-
}
|
|
2461
|
-
|
|
2462
|
-
const limits = [];
|
|
2463
|
-
|
|
2464
|
-
if (mode.substr(0, 1) === 'c') {
|
|
2465
|
-
// continuous
|
|
2466
|
-
limits.push(min);
|
|
2467
|
-
limits.push(max);
|
|
2468
|
-
}
|
|
2469
|
-
|
|
2470
|
-
if (mode.substr(0, 1) === 'e') {
|
|
2471
|
-
// equal interval
|
|
2472
|
-
limits.push(min);
|
|
2473
|
-
for (let i = 1; i < num; i++) {
|
|
2474
|
-
limits.push(min + (i / num) * (max - min));
|
|
2475
|
-
}
|
|
2476
|
-
limits.push(max);
|
|
2477
|
-
} else if (mode.substr(0, 1) === 'l') {
|
|
2478
|
-
// log scale
|
|
2479
|
-
if (min <= 0) {
|
|
2480
|
-
throw new Error(
|
|
2481
|
-
'Logarithmic scales are only possible for values > 0'
|
|
2482
|
-
);
|
|
2483
|
-
}
|
|
2484
|
-
const min_log = Math.LOG10E * log$1(min);
|
|
2485
|
-
const max_log = Math.LOG10E * log$1(max);
|
|
2486
|
-
limits.push(min);
|
|
2487
|
-
for (let i = 1; i < num; i++) {
|
|
2488
|
-
limits.push(pow$1(10, min_log + (i / num) * (max_log - min_log)));
|
|
2489
|
-
}
|
|
2490
|
-
limits.push(max);
|
|
2491
|
-
} else if (mode.substr(0, 1) === 'q') {
|
|
2492
|
-
// quantile scale
|
|
2493
|
-
limits.push(min);
|
|
2494
|
-
for (let i = 1; i < num; i++) {
|
|
2495
|
-
const p = ((values.length - 1) * i) / num;
|
|
2496
|
-
const pb = floor(p);
|
|
2497
|
-
if (pb === p) {
|
|
2498
|
-
limits.push(values[pb]);
|
|
2499
|
-
} else {
|
|
2500
|
-
// p > pb
|
|
2501
|
-
const pr = p - pb;
|
|
2502
|
-
limits.push(values[pb] * (1 - pr) + values[pb + 1] * pr);
|
|
2503
|
-
}
|
|
2504
|
-
}
|
|
2505
|
-
limits.push(max);
|
|
2506
|
-
} else if (mode.substr(0, 1) === 'k') {
|
|
2507
|
-
// k-means clustering
|
|
2508
|
-
/*
|
|
2509
|
-
implementation based on
|
|
2510
|
-
http://code.google.com/p/figue/source/browse/trunk/figue.js#336
|
|
2511
|
-
simplified for 1-d input values
|
|
2512
|
-
*/
|
|
2513
|
-
let cluster;
|
|
2514
|
-
const n = values.length;
|
|
2515
|
-
const assignments = new Array(n);
|
|
2516
|
-
const clusterSizes = new Array(num);
|
|
2517
|
-
let repeat = true;
|
|
2518
|
-
let nb_iters = 0;
|
|
2519
|
-
let centroids = null;
|
|
2520
|
-
|
|
2521
|
-
// get seed values
|
|
2522
|
-
centroids = [];
|
|
2523
|
-
centroids.push(min);
|
|
2524
|
-
for (let i = 1; i < num; i++) {
|
|
2525
|
-
centroids.push(min + (i / num) * (max - min));
|
|
2526
|
-
}
|
|
2527
|
-
centroids.push(max);
|
|
2528
|
-
|
|
2529
|
-
while (repeat) {
|
|
2530
|
-
// assignment step
|
|
2531
|
-
for (let j = 0; j < num; j++) {
|
|
2532
|
-
clusterSizes[j] = 0;
|
|
2533
|
-
}
|
|
2534
|
-
for (let i = 0; i < n; i++) {
|
|
2535
|
-
const value = values[i];
|
|
2536
|
-
let mindist = Number.MAX_VALUE;
|
|
2537
|
-
let best;
|
|
2538
|
-
for (let j = 0; j < num; j++) {
|
|
2539
|
-
const dist = abs$1(centroids[j] - value);
|
|
2540
|
-
if (dist < mindist) {
|
|
2541
|
-
mindist = dist;
|
|
2542
|
-
best = j;
|
|
2543
|
-
}
|
|
2544
|
-
clusterSizes[best]++;
|
|
2545
|
-
assignments[i] = best;
|
|
2546
|
-
}
|
|
2547
|
-
}
|
|
2548
|
-
|
|
2549
|
-
// update centroids step
|
|
2550
|
-
const newCentroids = new Array(num);
|
|
2551
|
-
for (let j = 0; j < num; j++) {
|
|
2552
|
-
newCentroids[j] = null;
|
|
2553
|
-
}
|
|
2554
|
-
for (let i = 0; i < n; i++) {
|
|
2555
|
-
cluster = assignments[i];
|
|
2556
|
-
if (newCentroids[cluster] === null) {
|
|
2557
|
-
newCentroids[cluster] = values[i];
|
|
2558
|
-
} else {
|
|
2559
|
-
newCentroids[cluster] += values[i];
|
|
2560
|
-
}
|
|
2561
|
-
}
|
|
2562
|
-
for (let j = 0; j < num; j++) {
|
|
2563
|
-
newCentroids[j] *= 1 / clusterSizes[j];
|
|
2564
|
-
}
|
|
2565
|
-
|
|
2566
|
-
// check convergence
|
|
2567
|
-
repeat = false;
|
|
2568
|
-
for (let j = 0; j < num; j++) {
|
|
2569
|
-
if (newCentroids[j] !== centroids[j]) {
|
|
2570
|
-
repeat = true;
|
|
2571
|
-
break;
|
|
2572
|
-
}
|
|
2573
|
-
}
|
|
2574
|
-
|
|
2575
|
-
centroids = newCentroids;
|
|
2576
|
-
nb_iters++;
|
|
2577
|
-
|
|
2578
|
-
if (nb_iters > 200) {
|
|
2579
|
-
repeat = false;
|
|
2580
|
-
}
|
|
2581
|
-
}
|
|
2582
|
-
|
|
2583
|
-
// finished k-means clustering
|
|
2584
|
-
// the next part is borrowed from gabrielflor.it
|
|
2585
|
-
const kClusters = {};
|
|
2586
|
-
for (let j = 0; j < num; j++) {
|
|
2587
|
-
kClusters[j] = [];
|
|
2588
|
-
}
|
|
2589
|
-
for (let i = 0; i < n; i++) {
|
|
2590
|
-
cluster = assignments[i];
|
|
2591
|
-
kClusters[cluster].push(values[i]);
|
|
2592
|
-
}
|
|
2593
|
-
let tmpKMeansBreaks = [];
|
|
2594
|
-
for (let j = 0; j < num; j++) {
|
|
2595
|
-
tmpKMeansBreaks.push(kClusters[j][0]);
|
|
2596
|
-
tmpKMeansBreaks.push(kClusters[j][kClusters[j].length - 1]);
|
|
2597
|
-
}
|
|
2598
|
-
tmpKMeansBreaks = tmpKMeansBreaks.sort((a, b) => a - b);
|
|
2599
|
-
limits.push(tmpKMeansBreaks[0]);
|
|
2600
|
-
for (let i = 1; i < tmpKMeansBreaks.length; i += 2) {
|
|
2601
|
-
const v = tmpKMeansBreaks[i];
|
|
2602
|
-
if (!isNaN(v) && limits.indexOf(v) === -1) {
|
|
2603
|
-
limits.push(v);
|
|
2604
|
-
}
|
|
2605
|
-
}
|
|
2606
|
-
}
|
|
2607
|
-
return limits;
|
|
2608
|
-
}
|
|
2609
|
-
|
|
2610
|
-
const contrast = (a, b) => {
|
|
2611
|
-
// WCAG contrast ratio
|
|
2612
|
-
// see http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
|
|
2613
|
-
a = new Color(a);
|
|
2614
|
-
b = new Color(b);
|
|
2615
|
-
const l1 = a.luminance();
|
|
2616
|
-
const l2 = b.luminance();
|
|
2617
|
-
return l1 > l2 ? (l1 + 0.05) / (l2 + 0.05) : (l2 + 0.05) / (l1 + 0.05);
|
|
2618
|
-
};
|
|
2619
|
-
|
|
2620
|
-
/**
|
|
2621
|
-
* @license
|
|
2622
|
-
*
|
|
2623
|
-
* The APCA contrast prediction algorithm is based of the formulas published
|
|
2624
|
-
* in the APCA-1.0.98G specification by Myndex. The specification is available at:
|
|
2625
|
-
* https://raw.githubusercontent.com/Myndex/apca-w3/master/images/APCAw3_0.1.17_APCA0.0.98G.svg
|
|
2626
|
-
*
|
|
2627
|
-
* Note that the APCA implementation is still beta, so please update to
|
|
2628
|
-
* future versions of chroma.js when they become available.
|
|
2629
|
-
*
|
|
2630
|
-
* You can read more about the APCA Readability Criterion at
|
|
2631
|
-
* https://readtech.org/ARC/
|
|
2632
|
-
*/
|
|
2633
|
-
|
|
2634
|
-
// constants
|
|
2635
|
-
const W_offset = 0.027;
|
|
2636
|
-
const P_in = 0.0005;
|
|
2637
|
-
const P_out = 0.1;
|
|
2638
|
-
const R_scale = 1.14;
|
|
2639
|
-
const B_threshold = 0.022;
|
|
2640
|
-
const B_exp = 1.414;
|
|
2641
|
-
|
|
2642
|
-
const contrastAPCA = (text, bg) => {
|
|
2643
|
-
// parse input colors
|
|
2644
|
-
text = new Color(text);
|
|
2645
|
-
bg = new Color(bg);
|
|
2646
|
-
// if text color has alpha, blend against background
|
|
2647
|
-
if (text.alpha() < 1) {
|
|
2648
|
-
text = mix(bg, text, text.alpha(), 'rgb');
|
|
2649
|
-
}
|
|
2650
|
-
const l_text = lum(...text.rgb());
|
|
2651
|
-
const l_bg = lum(...bg.rgb());
|
|
2652
|
-
|
|
2653
|
-
// soft clamp black levels
|
|
2654
|
-
const Y_text =
|
|
2655
|
-
l_text >= B_threshold
|
|
2656
|
-
? l_text
|
|
2657
|
-
: l_text + Math.pow(B_threshold - l_text, B_exp);
|
|
2658
|
-
const Y_bg =
|
|
2659
|
-
l_bg >= B_threshold ? l_bg : l_bg + Math.pow(B_threshold - l_bg, B_exp);
|
|
2660
|
-
|
|
2661
|
-
// normal polarity (dark text on light background)
|
|
2662
|
-
const S_norm = Math.pow(Y_bg, 0.56) - Math.pow(Y_text, 0.57);
|
|
2663
|
-
// reverse polarity (light text on dark background)
|
|
2664
|
-
const S_rev = Math.pow(Y_bg, 0.65) - Math.pow(Y_text, 0.62);
|
|
2665
|
-
// clamp noise then scale
|
|
2666
|
-
const C =
|
|
2667
|
-
Math.abs(Y_bg - Y_text) < P_in
|
|
2668
|
-
? 0
|
|
2669
|
-
: Y_text < Y_bg
|
|
2670
|
-
? S_norm * R_scale
|
|
2671
|
-
: S_rev * R_scale;
|
|
2672
|
-
// clamp minimum contrast then offset
|
|
2673
|
-
const S_apc = Math.abs(C) < P_out ? 0 : C > 0 ? C - W_offset : C + W_offset;
|
|
2674
|
-
// scale to 100
|
|
2675
|
-
return S_apc * 100;
|
|
2676
|
-
};
|
|
2677
|
-
|
|
2678
|
-
function lum(r, g, b) {
|
|
2679
|
-
return (
|
|
2680
|
-
0.2126729 * Math.pow(r / 255, 2.4) +
|
|
2681
|
-
0.7151522 * Math.pow(g / 255, 2.4) +
|
|
2682
|
-
0.072175 * Math.pow(b / 255, 2.4)
|
|
2683
|
-
);
|
|
2684
|
-
}
|
|
2685
|
-
|
|
2686
|
-
const { sqrt, pow, min, max: max$1, atan2, abs, cos, sin, exp, PI } = Math;
|
|
2687
|
-
|
|
2688
|
-
function deltaE (a, b, Kl = 1, Kc = 1, Kh = 1) {
|
|
2689
|
-
// Delta E (CIE 2000)
|
|
2690
|
-
// see http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE2000.html
|
|
2691
|
-
var rad2deg = function (rad) {
|
|
2692
|
-
return (360 * rad) / (2 * PI);
|
|
2693
|
-
};
|
|
2694
|
-
var deg2rad = function (deg) {
|
|
2695
|
-
return (2 * PI * deg) / 360;
|
|
2696
|
-
};
|
|
2697
|
-
a = new Color(a);
|
|
2698
|
-
b = new Color(b);
|
|
2699
|
-
const [L1, a1, b1] = Array.from(a.lab());
|
|
2700
|
-
const [L2, a2, b2] = Array.from(b.lab());
|
|
2701
|
-
const avgL = (L1 + L2) / 2;
|
|
2702
|
-
const C1 = sqrt(pow(a1, 2) + pow(b1, 2));
|
|
2703
|
-
const C2 = sqrt(pow(a2, 2) + pow(b2, 2));
|
|
2704
|
-
const avgC = (C1 + C2) / 2;
|
|
2705
|
-
const G = 0.5 * (1 - sqrt(pow(avgC, 7) / (pow(avgC, 7) + pow(25, 7))));
|
|
2706
|
-
const a1p = a1 * (1 + G);
|
|
2707
|
-
const a2p = a2 * (1 + G);
|
|
2708
|
-
const C1p = sqrt(pow(a1p, 2) + pow(b1, 2));
|
|
2709
|
-
const C2p = sqrt(pow(a2p, 2) + pow(b2, 2));
|
|
2710
|
-
const avgCp = (C1p + C2p) / 2;
|
|
2711
|
-
const arctan1 = rad2deg(atan2(b1, a1p));
|
|
2712
|
-
const arctan2 = rad2deg(atan2(b2, a2p));
|
|
2713
|
-
const h1p = arctan1 >= 0 ? arctan1 : arctan1 + 360;
|
|
2714
|
-
const h2p = arctan2 >= 0 ? arctan2 : arctan2 + 360;
|
|
2715
|
-
const avgHp =
|
|
2716
|
-
abs(h1p - h2p) > 180 ? (h1p + h2p + 360) / 2 : (h1p + h2p) / 2;
|
|
2717
|
-
const T =
|
|
2718
|
-
1 -
|
|
2719
|
-
0.17 * cos(deg2rad(avgHp - 30)) +
|
|
2720
|
-
0.24 * cos(deg2rad(2 * avgHp)) +
|
|
2721
|
-
0.32 * cos(deg2rad(3 * avgHp + 6)) -
|
|
2722
|
-
0.2 * cos(deg2rad(4 * avgHp - 63));
|
|
2723
|
-
let deltaHp = h2p - h1p;
|
|
2724
|
-
deltaHp =
|
|
2725
|
-
abs(deltaHp) <= 180
|
|
2726
|
-
? deltaHp
|
|
2727
|
-
: h2p <= h1p
|
|
2728
|
-
? deltaHp + 360
|
|
2729
|
-
: deltaHp - 360;
|
|
2730
|
-
deltaHp = 2 * sqrt(C1p * C2p) * sin(deg2rad(deltaHp) / 2);
|
|
2731
|
-
const deltaL = L2 - L1;
|
|
2732
|
-
const deltaCp = C2p - C1p;
|
|
2733
|
-
const sl = 1 + (0.015 * pow(avgL - 50, 2)) / sqrt(20 + pow(avgL - 50, 2));
|
|
2734
|
-
const sc = 1 + 0.045 * avgCp;
|
|
2735
|
-
const sh = 1 + 0.015 * avgCp * T;
|
|
2736
|
-
const deltaTheta = 30 * exp(-pow((avgHp - 275) / 25, 2));
|
|
2737
|
-
const Rc = 2 * sqrt(pow(avgCp, 7) / (pow(avgCp, 7) + pow(25, 7)));
|
|
2738
|
-
const Rt = -Rc * sin(2 * deg2rad(deltaTheta));
|
|
2739
|
-
const result = sqrt(
|
|
2740
|
-
pow(deltaL / (Kl * sl), 2) +
|
|
2741
|
-
pow(deltaCp / (Kc * sc), 2) +
|
|
2742
|
-
pow(deltaHp / (Kh * sh), 2) +
|
|
2743
|
-
Rt * (deltaCp / (Kc * sc)) * (deltaHp / (Kh * sh))
|
|
2744
|
-
);
|
|
2745
|
-
return max$1(0, min(100, result));
|
|
2746
|
-
}
|
|
2747
|
-
|
|
2748
|
-
// simple Euclidean distance
|
|
2749
|
-
function distance (a, b, mode = 'lab') {
|
|
2750
|
-
// Delta E (CIE 1976)
|
|
2751
|
-
// see http://www.brucelindbloom.com/index.html?Equations.html
|
|
2752
|
-
a = new Color(a);
|
|
2753
|
-
b = new Color(b);
|
|
2754
|
-
const l1 = a.get(mode);
|
|
2755
|
-
const l2 = b.get(mode);
|
|
2756
|
-
let sum_sq = 0;
|
|
2757
|
-
for (let i in l1) {
|
|
2758
|
-
const d = (l1[i] || 0) - (l2[i] || 0);
|
|
2759
|
-
sum_sq += d * d;
|
|
2760
|
-
}
|
|
2761
|
-
return Math.sqrt(sum_sq);
|
|
2762
|
-
}
|
|
2763
|
-
|
|
2764
|
-
const valid = (...args) => {
|
|
2765
|
-
try {
|
|
2766
|
-
new Color(...args);
|
|
2767
|
-
return true;
|
|
2768
|
-
// eslint-disable-next-line
|
|
2769
|
-
} catch (e) {
|
|
2770
|
-
return false;
|
|
2771
|
-
}
|
|
2772
|
-
};
|
|
2773
|
-
|
|
2774
|
-
// some pre-defined color scales:
|
|
2775
|
-
|
|
2776
|
-
const scales = {
|
|
2777
|
-
cool() {
|
|
2778
|
-
return scale([chroma.hsl(180, 1, 0.9), chroma.hsl(250, 0.7, 0.4)]);
|
|
2779
|
-
},
|
|
2780
|
-
hot() {
|
|
2781
|
-
return scale(['#000', '#f00', '#ff0', '#fff']).mode(
|
|
2782
|
-
'rgb'
|
|
2783
|
-
);
|
|
2784
|
-
}
|
|
2785
|
-
};
|
|
2786
|
-
|
|
2787
|
-
/**
|
|
2788
|
-
ColorBrewer colors for chroma.js
|
|
2789
|
-
|
|
2790
|
-
Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The
|
|
2791
|
-
Pennsylvania State University.
|
|
2792
|
-
|
|
2793
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
2794
|
-
you may not use this file except in compliance with the License.
|
|
2795
|
-
You may obtain a copy of the License at
|
|
2796
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
2797
|
-
|
|
2798
|
-
Unless required by applicable law or agreed to in writing, software distributed
|
|
2799
|
-
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
2800
|
-
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
2801
|
-
specific language governing permissions and limitations under the License.
|
|
2802
|
-
*/
|
|
2803
|
-
|
|
2804
|
-
const colorbrewer = {
|
|
2805
|
-
// sequential
|
|
2806
|
-
OrRd: ['#fff7ec', '#fee8c8', '#fdd49e', '#fdbb84', '#fc8d59', '#ef6548', '#d7301f', '#b30000', '#7f0000'],
|
|
2807
|
-
PuBu: ['#fff7fb', '#ece7f2', '#d0d1e6', '#a6bddb', '#74a9cf', '#3690c0', '#0570b0', '#045a8d', '#023858'],
|
|
2808
|
-
BuPu: ['#f7fcfd', '#e0ecf4', '#bfd3e6', '#9ebcda', '#8c96c6', '#8c6bb1', '#88419d', '#810f7c', '#4d004b'],
|
|
2809
|
-
Oranges: ['#fff5eb', '#fee6ce', '#fdd0a2', '#fdae6b', '#fd8d3c', '#f16913', '#d94801', '#a63603', '#7f2704'],
|
|
2810
|
-
BuGn: ['#f7fcfd', '#e5f5f9', '#ccece6', '#99d8c9', '#66c2a4', '#41ae76', '#238b45', '#006d2c', '#00441b'],
|
|
2811
|
-
YlOrBr: ['#ffffe5', '#fff7bc', '#fee391', '#fec44f', '#fe9929', '#ec7014', '#cc4c02', '#993404', '#662506'],
|
|
2812
|
-
YlGn: ['#ffffe5', '#f7fcb9', '#d9f0a3', '#addd8e', '#78c679', '#41ab5d', '#238443', '#006837', '#004529'],
|
|
2813
|
-
Reds: ['#fff5f0', '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a', '#ef3b2c', '#cb181d', '#a50f15', '#67000d'],
|
|
2814
|
-
RdPu: ['#fff7f3', '#fde0dd', '#fcc5c0', '#fa9fb5', '#f768a1', '#dd3497', '#ae017e', '#7a0177', '#49006a'],
|
|
2815
|
-
Greens: ['#f7fcf5', '#e5f5e0', '#c7e9c0', '#a1d99b', '#74c476', '#41ab5d', '#238b45', '#006d2c', '#00441b'],
|
|
2816
|
-
YlGnBu: ['#ffffd9', '#edf8b1', '#c7e9b4', '#7fcdbb', '#41b6c4', '#1d91c0', '#225ea8', '#253494', '#081d58'],
|
|
2817
|
-
Purples: ['#fcfbfd', '#efedf5', '#dadaeb', '#bcbddc', '#9e9ac8', '#807dba', '#6a51a3', '#54278f', '#3f007d'],
|
|
2818
|
-
GnBu: ['#f7fcf0', '#e0f3db', '#ccebc5', '#a8ddb5', '#7bccc4', '#4eb3d3', '#2b8cbe', '#0868ac', '#084081'],
|
|
2819
|
-
Greys: ['#ffffff', '#f0f0f0', '#d9d9d9', '#bdbdbd', '#969696', '#737373', '#525252', '#252525', '#000000'],
|
|
2820
|
-
YlOrRd: ['#ffffcc', '#ffeda0', '#fed976', '#feb24c', '#fd8d3c', '#fc4e2a', '#e31a1c', '#bd0026', '#800026'],
|
|
2821
|
-
PuRd: ['#f7f4f9', '#e7e1ef', '#d4b9da', '#c994c7', '#df65b0', '#e7298a', '#ce1256', '#980043', '#67001f'],
|
|
2822
|
-
Blues: ['#f7fbff', '#deebf7', '#c6dbef', '#9ecae1', '#6baed6', '#4292c6', '#2171b5', '#08519c', '#08306b'],
|
|
2823
|
-
PuBuGn: ['#fff7fb', '#ece2f0', '#d0d1e6', '#a6bddb', '#67a9cf', '#3690c0', '#02818a', '#016c59', '#014636'],
|
|
2824
|
-
Viridis: ['#440154', '#482777', '#3f4a8a', '#31678e', '#26838f', '#1f9d8a', '#6cce5a', '#b6de2b', '#fee825'],
|
|
2825
|
-
|
|
2826
|
-
// diverging
|
|
2827
|
-
Spectral: ['#9e0142', '#d53e4f', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#e6f598', '#abdda4', '#66c2a5', '#3288bd', '#5e4fa2'],
|
|
2828
|
-
RdYlGn: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee08b', '#ffffbf', '#d9ef8b', '#a6d96a', '#66bd63', '#1a9850', '#006837'],
|
|
2829
|
-
RdBu: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#f7f7f7', '#d1e5f0', '#92c5de', '#4393c3', '#2166ac', '#053061'],
|
|
2830
|
-
PiYG: ['#8e0152', '#c51b7d', '#de77ae', '#f1b6da', '#fde0ef', '#f7f7f7', '#e6f5d0', '#b8e186', '#7fbc41', '#4d9221', '#276419'],
|
|
2831
|
-
PRGn: ['#40004b', '#762a83', '#9970ab', '#c2a5cf', '#e7d4e8', '#f7f7f7', '#d9f0d3', '#a6dba0', '#5aae61', '#1b7837', '#00441b'],
|
|
2832
|
-
RdYlBu: ['#a50026', '#d73027', '#f46d43', '#fdae61', '#fee090', '#ffffbf', '#e0f3f8', '#abd9e9', '#74add1', '#4575b4', '#313695'],
|
|
2833
|
-
BrBG: ['#543005', '#8c510a', '#bf812d', '#dfc27d', '#f6e8c3', '#f5f5f5', '#c7eae5', '#80cdc1', '#35978f', '#01665e', '#003c30'],
|
|
2834
|
-
RdGy: ['#67001f', '#b2182b', '#d6604d', '#f4a582', '#fddbc7', '#ffffff', '#e0e0e0', '#bababa', '#878787', '#4d4d4d', '#1a1a1a'],
|
|
2835
|
-
PuOr: ['#7f3b08', '#b35806', '#e08214', '#fdb863', '#fee0b6', '#f7f7f7', '#d8daeb', '#b2abd2', '#8073ac', '#542788', '#2d004b'],
|
|
2836
|
-
|
|
2837
|
-
// qualitative
|
|
2838
|
-
Set2: ['#66c2a5', '#fc8d62', '#8da0cb', '#e78ac3', '#a6d854', '#ffd92f', '#e5c494', '#b3b3b3'],
|
|
2839
|
-
Accent: ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666'],
|
|
2840
|
-
Set1: ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3', '#ff7f00', '#ffff33', '#a65628', '#f781bf', '#999999'],
|
|
2841
|
-
Set3: ['#8dd3c7', '#ffffb3', '#bebada', '#fb8072', '#80b1d3', '#fdb462', '#b3de69', '#fccde5', '#d9d9d9', '#bc80bd', '#ccebc5', '#ffed6f'],
|
|
2842
|
-
Dark2: ['#1b9e77', '#d95f02', '#7570b3', '#e7298a', '#66a61e', '#e6ab02', '#a6761d', '#666666'],
|
|
2843
|
-
Paired: ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99', '#e31a1c', '#fdbf6f', '#ff7f00', '#cab2d6', '#6a3d9a', '#ffff99', '#b15928'],
|
|
2844
|
-
Pastel2: ['#b3e2cd', '#fdcdac', '#cbd5e8', '#f4cae4', '#e6f5c9', '#fff2ae', '#f1e2cc', '#cccccc'],
|
|
2845
|
-
Pastel1: ['#fbb4ae', '#b3cde3', '#ccebc5', '#decbe4', '#fed9a6', '#ffffcc', '#e5d8bd', '#fddaec', '#f2f2f2']
|
|
2846
|
-
};
|
|
2847
|
-
|
|
2848
|
-
const colorbrewerTypes = Object.keys(colorbrewer);
|
|
2849
|
-
const typeMap = new Map(colorbrewerTypes.map((key) => [key.toLowerCase(), key]));
|
|
2850
|
-
|
|
2851
|
-
// use Proxy to allow case-insensitive access to palettes
|
|
2852
|
-
const colorbrewerProxy =
|
|
2853
|
-
typeof Proxy === 'function'
|
|
2854
|
-
? new Proxy(colorbrewer, {
|
|
2855
|
-
get(target, prop) {
|
|
2856
|
-
const lower = prop.toLowerCase();
|
|
2857
|
-
if (typeMap.has(lower)) {
|
|
2858
|
-
return target[typeMap.get(lower)];
|
|
2859
|
-
}
|
|
2860
|
-
},
|
|
2861
|
-
getOwnPropertyNames() {
|
|
2862
|
-
return Object.getOwnPropertyNames(colorbrewerTypes);
|
|
2863
|
-
}
|
|
2864
|
-
})
|
|
2865
|
-
: colorbrewer;
|
|
2866
|
-
|
|
2867
|
-
const cmyk2rgb = (...args) => {
|
|
2868
|
-
args = unpack(args, 'cmyk');
|
|
2869
|
-
const [c, m, y, k] = args;
|
|
2870
|
-
const alpha = args.length > 4 ? args[4] : 1;
|
|
2871
|
-
if (k === 1) return [0, 0, 0, alpha];
|
|
2872
|
-
return [
|
|
2873
|
-
c >= 1 ? 0 : 255 * (1 - c) * (1 - k), // r
|
|
2874
|
-
m >= 1 ? 0 : 255 * (1 - m) * (1 - k), // g
|
|
2875
|
-
y >= 1 ? 0 : 255 * (1 - y) * (1 - k), // b
|
|
2876
|
-
alpha
|
|
2877
|
-
];
|
|
2878
|
-
};
|
|
2879
|
-
|
|
2880
|
-
const { max } = Math;
|
|
2881
|
-
|
|
2882
|
-
const rgb2cmyk = (...args) => {
|
|
2883
|
-
let [r, g, b] = unpack(args, 'rgb');
|
|
2884
|
-
r = r / 255;
|
|
2885
|
-
g = g / 255;
|
|
2886
|
-
b = b / 255;
|
|
2887
|
-
const k = 1 - max(r, max(g, b));
|
|
2888
|
-
const f = k < 1 ? 1 / (1 - k) : 0;
|
|
2889
|
-
const c = (1 - r - k) * f;
|
|
2890
|
-
const m = (1 - g - k) * f;
|
|
2891
|
-
const y = (1 - b - k) * f;
|
|
2892
|
-
return [c, m, y, k];
|
|
2893
|
-
};
|
|
2894
|
-
|
|
2895
|
-
Color.prototype.cmyk = function () {
|
|
2896
|
-
return rgb2cmyk(this._rgb);
|
|
2897
|
-
};
|
|
2898
|
-
|
|
2899
|
-
const cmyk = (...args) => new Color(...args, 'cmyk');
|
|
2900
|
-
Object.assign(chroma, { cmyk });
|
|
2901
|
-
|
|
2902
|
-
input.format.cmyk = cmyk2rgb;
|
|
2903
|
-
|
|
2904
|
-
input.autodetect.push({
|
|
2905
|
-
p: 2,
|
|
2906
|
-
test: (...args) => {
|
|
2907
|
-
args = unpack(args, 'cmyk');
|
|
2908
|
-
if (type(args) === 'array' && args.length === 4) {
|
|
2909
|
-
return 'cmyk';
|
|
2910
|
-
}
|
|
2911
|
-
}
|
|
2912
|
-
});
|
|
2913
|
-
|
|
2914
|
-
/*
|
|
2915
|
-
* supported arguments:
|
|
2916
|
-
* - hsl2css(h,s,l)
|
|
2917
|
-
* - hsl2css(h,s,l,a)
|
|
2918
|
-
* - hsl2css([h,s,l], mode)
|
|
2919
|
-
* - hsl2css([h,s,l,a], mode)
|
|
2920
|
-
* - hsl2css({h,s,l,a}, mode)
|
|
2921
|
-
*/
|
|
2922
|
-
const hsl2css = (...args) => {
|
|
2923
|
-
const hsla = unpack(args, 'hsla');
|
|
2924
|
-
let mode = last(args) || 'lsa';
|
|
2925
|
-
hsla[0] = rnd2(hsla[0] || 0) + 'deg';
|
|
2926
|
-
hsla[1] = rnd2(hsla[1] * 100) + '%';
|
|
2927
|
-
hsla[2] = rnd2(hsla[2] * 100) + '%';
|
|
2928
|
-
if (mode === 'hsla' || (hsla.length > 3 && hsla[3] < 1)) {
|
|
2929
|
-
hsla[3] = '/ ' + (hsla.length > 3 ? hsla[3] : 1);
|
|
2930
|
-
mode = 'hsla';
|
|
2931
|
-
} else {
|
|
2932
|
-
hsla.length = 3;
|
|
2933
|
-
}
|
|
2934
|
-
return `${mode.substr(0, 3)}(${hsla.join(' ')})`;
|
|
2935
|
-
};
|
|
2936
|
-
|
|
2937
|
-
/*
|
|
2938
|
-
* supported arguments:
|
|
2939
|
-
* - lab2css(l,a,b)
|
|
2940
|
-
* - lab2css(l,a,b,alpha)
|
|
2941
|
-
* - lab2css([l,a,b], mode)
|
|
2942
|
-
* - lab2css([l,a,b,alpha], mode)
|
|
2943
|
-
*/
|
|
2944
|
-
const lab2css = (...args) => {
|
|
2945
|
-
const laba = unpack(args, 'lab');
|
|
2946
|
-
let mode = last(args) || 'lab';
|
|
2947
|
-
laba[0] = rnd2(laba[0]) + '%';
|
|
2948
|
-
laba[1] = rnd2(laba[1]);
|
|
2949
|
-
laba[2] = rnd2(laba[2]);
|
|
2950
|
-
if (mode === 'laba' || (laba.length > 3 && laba[3] < 1)) {
|
|
2951
|
-
laba[3] = '/ ' + (laba.length > 3 ? laba[3] : 1);
|
|
2952
|
-
} else {
|
|
2953
|
-
laba.length = 3;
|
|
2954
|
-
}
|
|
2955
|
-
return `lab(${laba.join(' ')})`;
|
|
2956
|
-
};
|
|
2957
|
-
|
|
2958
|
-
/*
|
|
2959
|
-
* supported arguments:
|
|
2960
|
-
* - lab2css(l,a,b)
|
|
2961
|
-
* - lab2css(l,a,b,alpha)
|
|
2962
|
-
* - lab2css([l,a,b], mode)
|
|
2963
|
-
* - lab2css([l,a,b,alpha], mode)
|
|
2964
|
-
*/
|
|
2965
|
-
const lch2css = (...args) => {
|
|
2966
|
-
const lcha = unpack(args, 'lch');
|
|
2967
|
-
let mode = last(args) || 'lab';
|
|
2968
|
-
lcha[0] = rnd2(lcha[0]) + '%';
|
|
2969
|
-
lcha[1] = rnd2(lcha[1]);
|
|
2970
|
-
lcha[2] = isNaN(lcha[2]) ? 'none' : rnd2(lcha[2]) + 'deg'; // add deg unit to hue
|
|
2971
|
-
if (mode === 'lcha' || (lcha.length > 3 && lcha[3] < 1)) {
|
|
2972
|
-
lcha[3] = '/ ' + (lcha.length > 3 ? lcha[3] : 1);
|
|
2973
|
-
} else {
|
|
2974
|
-
lcha.length = 3;
|
|
2975
|
-
}
|
|
2976
|
-
return `lch(${lcha.join(' ')})`;
|
|
2977
|
-
};
|
|
2978
|
-
|
|
2979
|
-
const oklab2css = (...args) => {
|
|
2980
|
-
const laba = unpack(args, 'lab');
|
|
2981
|
-
laba[0] = rnd2(laba[0] * 100) + '%';
|
|
2982
|
-
laba[1] = rnd3(laba[1]);
|
|
2983
|
-
laba[2] = rnd3(laba[2]);
|
|
2984
|
-
if (laba.length > 3 && laba[3] < 1) {
|
|
2985
|
-
laba[3] = '/ ' + (laba.length > 3 ? laba[3] : 1);
|
|
2986
|
-
} else {
|
|
2987
|
-
laba.length = 3;
|
|
2988
|
-
}
|
|
2989
|
-
return `oklab(${laba.join(' ')})`;
|
|
2990
|
-
};
|
|
2991
|
-
|
|
2992
|
-
const rgb2oklch = (...args) => {
|
|
2993
|
-
const [r, g, b, ...rest] = unpack(args, 'rgb');
|
|
2994
|
-
const [l, a, b_] = rgb2oklab(r, g, b);
|
|
2995
|
-
const [L, c, h] = lab2lch(l, a, b_);
|
|
2996
|
-
return [L, c, h, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
|
|
2997
|
-
};
|
|
2998
|
-
|
|
2999
|
-
const oklch2css = (...args) => {
|
|
3000
|
-
const lcha = unpack(args, 'lch');
|
|
3001
|
-
lcha[0] = rnd2(lcha[0] * 100) + '%';
|
|
3002
|
-
lcha[1] = rnd3(lcha[1]);
|
|
3003
|
-
lcha[2] = isNaN(lcha[2]) ? 'none' : rnd2(lcha[2]) + 'deg'; // add deg unit to hue
|
|
3004
|
-
if (lcha.length > 3 && lcha[3] < 1) {
|
|
3005
|
-
lcha[3] = '/ ' + (lcha.length > 3 ? lcha[3] : 1);
|
|
3006
|
-
} else {
|
|
3007
|
-
lcha.length = 3;
|
|
3008
|
-
}
|
|
3009
|
-
return `oklch(${lcha.join(' ')})`;
|
|
3010
|
-
};
|
|
3011
|
-
|
|
3012
|
-
const { round: round$2 } = Math;
|
|
3013
|
-
|
|
3014
|
-
/*
|
|
3015
|
-
* supported arguments:
|
|
3016
|
-
* - rgb2css(r,g,b)
|
|
3017
|
-
* - rgb2css(r,g,b,a)
|
|
3018
|
-
* - rgb2css([r,g,b], mode)
|
|
3019
|
-
* - rgb2css([r,g,b,a], mode)
|
|
3020
|
-
* - rgb2css({r,g,b,a}, mode)
|
|
3021
|
-
*/
|
|
3022
|
-
const rgb2css = (...args) => {
|
|
3023
|
-
const rgba = unpack(args, 'rgba');
|
|
3024
|
-
let mode = last(args) || 'rgb';
|
|
3025
|
-
if (mode.substr(0, 3) === 'hsl') {
|
|
3026
|
-
return hsl2css(rgb2hsl$1(rgba), mode);
|
|
3027
|
-
}
|
|
3028
|
-
if (mode.substr(0, 3) === 'lab') {
|
|
3029
|
-
// change to D50 lab whitepoint since this is what W3C is using for CSS Lab colors
|
|
3030
|
-
const prevWhitePoint = getLabWhitePoint();
|
|
3031
|
-
setLabWhitePoint('d50');
|
|
3032
|
-
const cssColor = lab2css(rgb2lab(rgba), mode);
|
|
3033
|
-
setLabWhitePoint(prevWhitePoint);
|
|
3034
|
-
return cssColor;
|
|
3035
|
-
}
|
|
3036
|
-
if (mode.substr(0, 3) === 'lch') {
|
|
3037
|
-
// change to D50 lab whitepoint since this is what W3C is using for CSS Lab colors
|
|
3038
|
-
const prevWhitePoint = getLabWhitePoint();
|
|
3039
|
-
setLabWhitePoint('d50');
|
|
3040
|
-
const cssColor = lch2css(rgb2lch(rgba), mode);
|
|
3041
|
-
setLabWhitePoint(prevWhitePoint);
|
|
3042
|
-
return cssColor;
|
|
3043
|
-
}
|
|
3044
|
-
if (mode.substr(0, 5) === 'oklab') {
|
|
3045
|
-
return oklab2css(rgb2oklab(rgba));
|
|
3046
|
-
}
|
|
3047
|
-
if (mode.substr(0, 5) === 'oklch') {
|
|
3048
|
-
return oklch2css(rgb2oklch(rgba));
|
|
3049
|
-
}
|
|
3050
|
-
rgba[0] = round$2(rgba[0]);
|
|
3051
|
-
rgba[1] = round$2(rgba[1]);
|
|
3052
|
-
rgba[2] = round$2(rgba[2]);
|
|
3053
|
-
if (mode === 'rgba' || (rgba.length > 3 && rgba[3] < 1)) {
|
|
3054
|
-
rgba[3] = '/ ' + (rgba.length > 3 ? rgba[3] : 1);
|
|
3055
|
-
mode = 'rgba';
|
|
3056
|
-
}
|
|
3057
|
-
return `${mode.substr(0, 3)}(${rgba.slice(0, mode === 'rgb' ? 3 : 4).join(' ')})`;
|
|
3058
|
-
};
|
|
3059
|
-
|
|
3060
|
-
const oklch2rgb = (...args) => {
|
|
3061
|
-
args = unpack(args, 'lch');
|
|
3062
|
-
const [l, c, h, ...rest] = args;
|
|
3063
|
-
const [L, a, b_] = lch2lab(l, c, h);
|
|
3064
|
-
const [r, g, b] = oklab2rgb(L, a, b_);
|
|
3065
|
-
return [r, g, b, ...(rest.length > 0 && rest[0] < 1 ? [rest[0]] : [])];
|
|
3066
|
-
};
|
|
3067
|
-
|
|
3068
|
-
const INT_OR_PCT = /((?:-?\d+)|(?:-?\d+(?:\.\d+)?)%|none)/.source;
|
|
3069
|
-
const FLOAT_OR_PCT = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)%?)|none)/.source;
|
|
3070
|
-
const PCT = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)%)|none)/.source;
|
|
3071
|
-
const RE_S = /\s*/.source;
|
|
3072
|
-
const SEP = /\s+/.source;
|
|
3073
|
-
const COMMA = /\s*,\s*/.source;
|
|
3074
|
-
const ANLGE = /((?:-?(?:\d+(?:\.\d*)?|\.\d+)(?:deg)?)|none)/.source;
|
|
3075
|
-
const ALPHA = /\s*(?:\/\s*((?:[01]|[01]?\.\d+)|\d+(?:\.\d+)?%))?/.source;
|
|
3076
|
-
|
|
3077
|
-
// e.g. rgb(250 20 0), rgb(100% 50% 20%), rgb(100% 50% 20% / 0.5)
|
|
3078
|
-
const RE_RGB = new RegExp(
|
|
3079
|
-
'^rgba?\\(' +
|
|
3080
|
-
RE_S +
|
|
3081
|
-
[INT_OR_PCT, INT_OR_PCT, INT_OR_PCT].join(SEP) +
|
|
3082
|
-
ALPHA +
|
|
3083
|
-
'\\)$'
|
|
3084
|
-
);
|
|
3085
|
-
const RE_RGB_LEGACY = new RegExp(
|
|
3086
|
-
'^rgb\\(' +
|
|
3087
|
-
RE_S +
|
|
3088
|
-
[INT_OR_PCT, INT_OR_PCT, INT_OR_PCT].join(COMMA) +
|
|
3089
|
-
RE_S +
|
|
3090
|
-
'\\)$'
|
|
3091
|
-
);
|
|
3092
|
-
const RE_RGBA_LEGACY = new RegExp(
|
|
3093
|
-
'^rgba\\(' +
|
|
3094
|
-
RE_S +
|
|
3095
|
-
[INT_OR_PCT, INT_OR_PCT, INT_OR_PCT, FLOAT_OR_PCT].join(COMMA) +
|
|
3096
|
-
RE_S +
|
|
3097
|
-
'\\)$'
|
|
3098
|
-
);
|
|
3099
|
-
|
|
3100
|
-
const RE_HSL = new RegExp(
|
|
3101
|
-
'^hsla?\\(' + RE_S + [ANLGE, PCT, PCT].join(SEP) + ALPHA + '\\)$'
|
|
3102
|
-
);
|
|
3103
|
-
const RE_HSL_LEGACY = new RegExp(
|
|
3104
|
-
'^hsl?\\(' + RE_S + [ANLGE, PCT, PCT].join(COMMA) + RE_S + '\\)$'
|
|
3105
|
-
);
|
|
3106
|
-
const RE_HSLA_LEGACY =
|
|
3107
|
-
/^hsla\(\s*(-?\d+(?:\.\d+)?),\s*(-?\d+(?:\.\d+)?)%\s*,\s*(-?\d+(?:\.\d+)?)%\s*,\s*([01]|[01]?\.\d+)\)$/;
|
|
3108
|
-
|
|
3109
|
-
const RE_LAB = new RegExp(
|
|
3110
|
-
'^lab\\(' +
|
|
3111
|
-
RE_S +
|
|
3112
|
-
[FLOAT_OR_PCT, FLOAT_OR_PCT, FLOAT_OR_PCT].join(SEP) +
|
|
3113
|
-
ALPHA +
|
|
3114
|
-
'\\)$'
|
|
3115
|
-
);
|
|
3116
|
-
const RE_LCH = new RegExp(
|
|
3117
|
-
'^lch\\(' +
|
|
3118
|
-
RE_S +
|
|
3119
|
-
[FLOAT_OR_PCT, FLOAT_OR_PCT, ANLGE].join(SEP) +
|
|
3120
|
-
ALPHA +
|
|
3121
|
-
'\\)$'
|
|
3122
|
-
);
|
|
3123
|
-
const RE_OKLAB = new RegExp(
|
|
3124
|
-
'^oklab\\(' +
|
|
3125
|
-
RE_S +
|
|
3126
|
-
[FLOAT_OR_PCT, FLOAT_OR_PCT, FLOAT_OR_PCT].join(SEP) +
|
|
3127
|
-
ALPHA +
|
|
3128
|
-
'\\)$'
|
|
3129
|
-
);
|
|
3130
|
-
const RE_OKLCH = new RegExp(
|
|
3131
|
-
'^oklch\\(' +
|
|
3132
|
-
RE_S +
|
|
3133
|
-
[FLOAT_OR_PCT, FLOAT_OR_PCT, ANLGE].join(SEP) +
|
|
3134
|
-
ALPHA +
|
|
3135
|
-
'\\)$'
|
|
3136
|
-
);
|
|
3137
|
-
|
|
3138
|
-
const { round: round$1 } = Math;
|
|
3139
|
-
|
|
3140
|
-
const roundRGB = (rgb) => {
|
|
3141
|
-
return rgb.map((v, i) => (i <= 2 ? limit(round$1(v), 0, 255) : v));
|
|
3142
|
-
};
|
|
3143
|
-
|
|
3144
|
-
const percentToAbsolute = (pct, min = 0, max = 100, signed = false) => {
|
|
3145
|
-
if (typeof pct === 'string' && pct.endsWith('%')) {
|
|
3146
|
-
pct = parseFloat(pct.substring(0, pct.length - 1)) / 100;
|
|
3147
|
-
if (signed) {
|
|
3148
|
-
// signed percentages are in the range -100% to 100%
|
|
3149
|
-
pct = min + (pct + 1) * 0.5 * (max - min);
|
|
3150
|
-
} else {
|
|
3151
|
-
pct = min + pct * (max - min);
|
|
3152
|
-
}
|
|
3153
|
-
}
|
|
3154
|
-
return +pct;
|
|
3155
|
-
};
|
|
3156
|
-
|
|
3157
|
-
const noneToValue = (v, noneValue) => {
|
|
3158
|
-
return v === 'none' ? noneValue : v;
|
|
3159
|
-
};
|
|
3160
|
-
|
|
3161
|
-
const css2rgb = (css) => {
|
|
3162
|
-
css = css.toLowerCase().trim();
|
|
3163
|
-
|
|
3164
|
-
if (css === 'transparent') {
|
|
3165
|
-
return [0, 0, 0, 0];
|
|
3166
|
-
}
|
|
3167
|
-
|
|
3168
|
-
let m;
|
|
3169
|
-
|
|
3170
|
-
if (input.format.named) {
|
|
3171
|
-
try {
|
|
3172
|
-
return input.format.named(css);
|
|
3173
|
-
// eslint-disable-next-line
|
|
3174
|
-
} catch (e) {}
|
|
3175
|
-
}
|
|
3176
|
-
|
|
3177
|
-
// rgb(250 20 0) or rgb(250,20,0)
|
|
3178
|
-
if ((m = css.match(RE_RGB)) || (m = css.match(RE_RGB_LEGACY))) {
|
|
3179
|
-
let rgb = m.slice(1, 4);
|
|
3180
|
-
for (let i = 0; i < 3; i++) {
|
|
3181
|
-
rgb[i] = +percentToAbsolute(noneToValue(rgb[i], 0), 0, 255);
|
|
3182
|
-
}
|
|
3183
|
-
rgb = roundRGB(rgb);
|
|
3184
|
-
const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
|
|
3185
|
-
rgb[3] = alpha; // default alpha
|
|
3186
|
-
return rgb;
|
|
3187
|
-
}
|
|
3188
|
-
|
|
3189
|
-
// rgba(250,20,0,0.4)
|
|
3190
|
-
if ((m = css.match(RE_RGBA_LEGACY))) {
|
|
3191
|
-
const rgb = m.slice(1, 5);
|
|
3192
|
-
for (let i = 0; i < 4; i++) {
|
|
3193
|
-
rgb[i] = +percentToAbsolute(rgb[i], 0, 255);
|
|
3194
|
-
}
|
|
3195
|
-
return rgb;
|
|
3196
|
-
}
|
|
3197
|
-
|
|
3198
|
-
// hsl(0,100%,50%)
|
|
3199
|
-
if ((m = css.match(RE_HSL)) || (m = css.match(RE_HSL_LEGACY))) {
|
|
3200
|
-
const hsl = m.slice(1, 4);
|
|
3201
|
-
hsl[0] = +noneToValue(hsl[0].replace('deg', ''), 0);
|
|
3202
|
-
hsl[1] = +percentToAbsolute(noneToValue(hsl[1], 0), 0, 100) * 0.01;
|
|
3203
|
-
hsl[2] = +percentToAbsolute(noneToValue(hsl[2], 0), 0, 100) * 0.01;
|
|
3204
|
-
const rgb = roundRGB(hsl2rgb(hsl));
|
|
3205
|
-
const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
|
|
3206
|
-
rgb[3] = alpha;
|
|
3207
|
-
return rgb;
|
|
3208
|
-
}
|
|
3209
|
-
|
|
3210
|
-
// hsla(0,100%,50%,0.5)
|
|
3211
|
-
if ((m = css.match(RE_HSLA_LEGACY))) {
|
|
3212
|
-
const hsl = m.slice(1, 4);
|
|
3213
|
-
hsl[1] *= 0.01;
|
|
3214
|
-
hsl[2] *= 0.01;
|
|
3215
|
-
const rgb = hsl2rgb(hsl);
|
|
3216
|
-
for (let i = 0; i < 3; i++) {
|
|
3217
|
-
rgb[i] = round$1(rgb[i]);
|
|
3218
|
-
}
|
|
3219
|
-
rgb[3] = +m[4]; // default alpha = 1
|
|
3220
|
-
return rgb;
|
|
3221
|
-
}
|
|
3222
|
-
|
|
3223
|
-
if ((m = css.match(RE_LAB))) {
|
|
3224
|
-
const lab = m.slice(1, 4);
|
|
3225
|
-
lab[0] = percentToAbsolute(noneToValue(lab[0], 0), 0, 100);
|
|
3226
|
-
lab[1] = percentToAbsolute(noneToValue(lab[1], 0), -125, 125, true);
|
|
3227
|
-
lab[2] = percentToAbsolute(noneToValue(lab[2], 0), -125, 125, true);
|
|
3228
|
-
// convert to D50 Lab whitepoint
|
|
3229
|
-
const wp = getLabWhitePoint();
|
|
3230
|
-
setLabWhitePoint('d50');
|
|
3231
|
-
const rgb = roundRGB(lab2rgb(lab));
|
|
3232
|
-
// convert back to original Lab whitepoint
|
|
3233
|
-
setLabWhitePoint(wp);
|
|
3234
|
-
const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
|
|
3235
|
-
rgb[3] = alpha;
|
|
3236
|
-
return rgb;
|
|
3237
|
-
}
|
|
3238
|
-
|
|
3239
|
-
if ((m = css.match(RE_LCH))) {
|
|
3240
|
-
const lch = m.slice(1, 4);
|
|
3241
|
-
lch[0] = percentToAbsolute(lch[0], 0, 100);
|
|
3242
|
-
lch[1] = percentToAbsolute(noneToValue(lch[1], 0), 0, 150, false);
|
|
3243
|
-
lch[2] = +noneToValue(lch[2].replace('deg', ''), 0);
|
|
3244
|
-
// convert to D50 Lab whitepoint
|
|
3245
|
-
const wp = getLabWhitePoint();
|
|
3246
|
-
setLabWhitePoint('d50');
|
|
3247
|
-
const rgb = roundRGB(lch2rgb(lch));
|
|
3248
|
-
// convert back to original Lab whitepoint
|
|
3249
|
-
setLabWhitePoint(wp);
|
|
3250
|
-
const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
|
|
3251
|
-
rgb[3] = alpha;
|
|
3252
|
-
return rgb;
|
|
3253
|
-
}
|
|
3254
|
-
|
|
3255
|
-
if ((m = css.match(RE_OKLAB))) {
|
|
3256
|
-
const oklab = m.slice(1, 4);
|
|
3257
|
-
oklab[0] = percentToAbsolute(noneToValue(oklab[0], 0), 0, 1);
|
|
3258
|
-
oklab[1] = percentToAbsolute(noneToValue(oklab[1], 0), -0.4, 0.4, true);
|
|
3259
|
-
oklab[2] = percentToAbsolute(noneToValue(oklab[2], 0), -0.4, 0.4, true);
|
|
3260
|
-
const rgb = roundRGB(oklab2rgb(oklab));
|
|
3261
|
-
const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
|
|
3262
|
-
rgb[3] = alpha;
|
|
3263
|
-
return rgb;
|
|
3264
|
-
}
|
|
3265
|
-
|
|
3266
|
-
if ((m = css.match(RE_OKLCH))) {
|
|
3267
|
-
const oklch = m.slice(1, 4);
|
|
3268
|
-
oklch[0] = percentToAbsolute(noneToValue(oklch[0], 0), 0, 1);
|
|
3269
|
-
oklch[1] = percentToAbsolute(noneToValue(oklch[1], 0), 0, 0.4, false);
|
|
3270
|
-
oklch[2] = +noneToValue(oklch[2].replace('deg', ''), 0);
|
|
3271
|
-
const rgb = roundRGB(oklch2rgb(oklch));
|
|
3272
|
-
const alpha = m[4] !== undefined ? +percentToAbsolute(m[4], 0, 1) : 1;
|
|
3273
|
-
rgb[3] = alpha;
|
|
3274
|
-
return rgb;
|
|
3275
|
-
}
|
|
3276
|
-
};
|
|
3277
|
-
|
|
3278
|
-
css2rgb.test = (s) => {
|
|
3279
|
-
return (
|
|
3280
|
-
// modern
|
|
3281
|
-
RE_RGB.test(s) ||
|
|
3282
|
-
RE_HSL.test(s) ||
|
|
3283
|
-
RE_LAB.test(s) ||
|
|
3284
|
-
RE_LCH.test(s) ||
|
|
3285
|
-
RE_OKLAB.test(s) ||
|
|
3286
|
-
RE_OKLCH.test(s) ||
|
|
3287
|
-
// legacy
|
|
3288
|
-
RE_RGB_LEGACY.test(s) ||
|
|
3289
|
-
RE_RGBA_LEGACY.test(s) ||
|
|
3290
|
-
RE_HSL_LEGACY.test(s) ||
|
|
3291
|
-
RE_HSLA_LEGACY.test(s) ||
|
|
3292
|
-
s === 'transparent'
|
|
3293
|
-
);
|
|
3294
|
-
};
|
|
3295
|
-
|
|
3296
|
-
Color.prototype.css = function (mode) {
|
|
3297
|
-
return rgb2css(this._rgb, mode);
|
|
3298
|
-
};
|
|
3299
|
-
|
|
3300
|
-
const css = (...args) => new Color(...args, 'css');
|
|
3301
|
-
chroma.css = css;
|
|
3302
|
-
|
|
3303
|
-
input.format.css = css2rgb;
|
|
3304
|
-
|
|
3305
|
-
input.autodetect.push({
|
|
3306
|
-
p: 5,
|
|
3307
|
-
test: (h, ...rest) => {
|
|
3308
|
-
if (!rest.length && type(h) === 'string' && css2rgb.test(h)) {
|
|
3309
|
-
return 'css';
|
|
3310
|
-
}
|
|
3311
|
-
}
|
|
3312
|
-
});
|
|
3313
|
-
|
|
3314
|
-
input.format.gl = (...args) => {
|
|
3315
|
-
const rgb = unpack(args, 'rgba');
|
|
3316
|
-
rgb[0] *= 255;
|
|
3317
|
-
rgb[1] *= 255;
|
|
3318
|
-
rgb[2] *= 255;
|
|
3319
|
-
return rgb;
|
|
3320
|
-
};
|
|
3321
|
-
|
|
3322
|
-
const gl = (...args) => new Color(...args, 'gl');
|
|
3323
|
-
chroma.gl = gl;
|
|
3324
|
-
|
|
3325
|
-
Color.prototype.gl = function () {
|
|
3326
|
-
const rgb = this._rgb;
|
|
3327
|
-
return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, rgb[3]];
|
|
3328
|
-
};
|
|
3329
|
-
|
|
3330
|
-
Color.prototype.hex = function (mode) {
|
|
3331
|
-
return rgb2hex(this._rgb, mode);
|
|
3332
|
-
};
|
|
3333
|
-
|
|
3334
|
-
const hex = (...args) => new Color(...args, 'hex');
|
|
3335
|
-
chroma.hex = hex;
|
|
3336
|
-
|
|
3337
|
-
input.format.hex = hex2rgb;
|
|
3338
|
-
input.autodetect.push({
|
|
3339
|
-
p: 4,
|
|
3340
|
-
test: (h, ...rest) => {
|
|
3341
|
-
if (
|
|
3342
|
-
!rest.length &&
|
|
3343
|
-
type(h) === 'string' &&
|
|
3344
|
-
[3, 4, 5, 6, 7, 8, 9].indexOf(h.length) >= 0
|
|
3345
|
-
) {
|
|
3346
|
-
return 'hex';
|
|
3347
|
-
}
|
|
3348
|
-
}
|
|
3349
|
-
});
|
|
3350
|
-
|
|
3351
|
-
/*
|
|
3352
|
-
* Based on implementation by Neil Bartlett
|
|
3353
|
-
* https://github.com/neilbartlett/color-temperature
|
|
3354
|
-
*/
|
|
3355
|
-
|
|
3356
|
-
const { log } = Math;
|
|
3357
|
-
|
|
3358
|
-
const temperature2rgb = (kelvin) => {
|
|
3359
|
-
const temp = kelvin / 100;
|
|
3360
|
-
let r, g, b;
|
|
3361
|
-
if (temp < 66) {
|
|
3362
|
-
r = 255;
|
|
3363
|
-
g =
|
|
3364
|
-
temp < 6
|
|
3365
|
-
? 0
|
|
3366
|
-
: -155.25485562709179 -
|
|
3367
|
-
0.44596950469579133 * (g = temp - 2) +
|
|
3368
|
-
104.49216199393888 * log(g);
|
|
3369
|
-
b =
|
|
3370
|
-
temp < 20
|
|
3371
|
-
? 0
|
|
3372
|
-
: -254.76935184120902 +
|
|
3373
|
-
0.8274096064007395 * (b = temp - 10) +
|
|
3374
|
-
115.67994401066147 * log(b);
|
|
3375
|
-
} else {
|
|
3376
|
-
r =
|
|
3377
|
-
351.97690566805693 +
|
|
3378
|
-
0.114206453784165 * (r = temp - 55) -
|
|
3379
|
-
40.25366309332127 * log(r);
|
|
3380
|
-
g =
|
|
3381
|
-
325.4494125711974 +
|
|
3382
|
-
0.07943456536662342 * (g = temp - 50) -
|
|
3383
|
-
28.0852963507957 * log(g);
|
|
3384
|
-
b = 255;
|
|
3385
|
-
}
|
|
3386
|
-
return [r, g, b, 1];
|
|
3387
|
-
};
|
|
3388
|
-
|
|
3389
|
-
/*
|
|
3390
|
-
* Based on implementation by Neil Bartlett
|
|
3391
|
-
* https://github.com/neilbartlett/color-temperature
|
|
3392
|
-
**/
|
|
3393
|
-
const { round } = Math;
|
|
3394
|
-
|
|
3395
|
-
const rgb2temperature = (...args) => {
|
|
3396
|
-
const rgb = unpack(args, 'rgb');
|
|
3397
|
-
const r = rgb[0],
|
|
3398
|
-
b = rgb[2];
|
|
3399
|
-
let minTemp = 1000;
|
|
3400
|
-
let maxTemp = 40000;
|
|
3401
|
-
const eps = 0.4;
|
|
3402
|
-
let temp;
|
|
3403
|
-
while (maxTemp - minTemp > eps) {
|
|
3404
|
-
temp = (maxTemp + minTemp) * 0.5;
|
|
3405
|
-
const rgb = temperature2rgb(temp);
|
|
3406
|
-
if (rgb[2] / rgb[0] >= b / r) {
|
|
3407
|
-
maxTemp = temp;
|
|
3408
|
-
} else {
|
|
3409
|
-
minTemp = temp;
|
|
3410
|
-
}
|
|
3411
|
-
}
|
|
3412
|
-
return round(temp);
|
|
3413
|
-
};
|
|
3414
|
-
|
|
3415
|
-
Color.prototype.temp =
|
|
3416
|
-
Color.prototype.kelvin =
|
|
3417
|
-
Color.prototype.temperature =
|
|
3418
|
-
function () {
|
|
3419
|
-
return rgb2temperature(this._rgb);
|
|
3420
|
-
};
|
|
3421
|
-
|
|
3422
|
-
const temp = (...args) => new Color(...args, 'temp');
|
|
3423
|
-
Object.assign(chroma, { temp, kelvin: temp, temperature: temp });
|
|
3424
|
-
|
|
3425
|
-
input.format.temp =
|
|
3426
|
-
input.format.kelvin =
|
|
3427
|
-
input.format.temperature =
|
|
3428
|
-
temperature2rgb;
|
|
3429
|
-
|
|
3430
|
-
Color.prototype.oklch = function () {
|
|
3431
|
-
return rgb2oklch(this._rgb);
|
|
3432
|
-
};
|
|
3433
|
-
|
|
3434
|
-
const oklch = (...args) => new Color(...args, 'oklch');
|
|
3435
|
-
Object.assign(chroma, { oklch });
|
|
3436
|
-
|
|
3437
|
-
input.format.oklch = oklch2rgb;
|
|
3438
|
-
|
|
3439
|
-
input.autodetect.push({
|
|
3440
|
-
p: 2,
|
|
3441
|
-
test: (...args) => {
|
|
3442
|
-
args = unpack(args, 'oklch');
|
|
3443
|
-
if (type(args) === 'array' && args.length === 3) {
|
|
3444
|
-
return 'oklch';
|
|
3445
|
-
}
|
|
3446
|
-
}
|
|
3447
|
-
});
|
|
3448
|
-
|
|
3449
|
-
// feel free to comment out anything to rollup
|
|
3450
|
-
|
|
3451
|
-
Object.assign(chroma, {
|
|
3452
|
-
analyze,
|
|
3453
|
-
average,
|
|
3454
|
-
bezier: bezier$1,
|
|
3455
|
-
blend,
|
|
3456
|
-
brewer: colorbrewerProxy,
|
|
3457
|
-
Color,
|
|
3458
|
-
colors: w3cx11,
|
|
3459
|
-
contrast,
|
|
3460
|
-
contrastAPCA,
|
|
3461
|
-
cubehelix,
|
|
3462
|
-
deltaE,
|
|
3463
|
-
distance,
|
|
3464
|
-
input,
|
|
3465
|
-
interpolate: mix,
|
|
3466
|
-
limits,
|
|
3467
|
-
mix,
|
|
3468
|
-
random: random$1,
|
|
3469
|
-
scale,
|
|
3470
|
-
scales,
|
|
3471
|
-
valid
|
|
3472
|
-
});
|
|
3473
|
-
|
|
3474
|
-
const indexCss = "@import url(\"https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap\"); .tinting-wrapper *{font-family:\"Poppins\", sans-serif}.my-modal{box-shadow:1px 1px 1px #ccc;background-color:#fff;position:fixed;top:20px;left:50%;transform:translateX(-50%);max-width:1555px;width:90%;z-index:1000;text-align:center;padding:60px 40px;max-height:calc(100vh - 100px);overflow-y:auto;min-height:50vh}@media (max-width: 1024px){.my-modal{padding:40px 20px 20px}}.my-modal::-webkit-scrollbar{display:none}.my-modal .loader{display:flex;flex-direction:column;align-items:center;justify-content:center;height:300px}.my-modal__see-more{font-size:16px;display:flex;justify-content:left;align-items:center;font-weight:300;color:#575757;margin-top:12px;margin-bottom:0px}@media (max-width: 1024px){.my-modal__see-more{font-size:18px}}.my-modal__see-more img{width:45px;height:45px}@media (max-width: 1024px){.my-modal__see-more img{display:none}}.my-modal__see-more.big{font-size:20px;margin-bottom:8px}.my-modal__wrapper{display:flex;flex-direction:column;position:relative}.my-modal__wrapper .not-found{padding:100px 0px}.my-modal__wrapper .boxes{display:flex;flex-direction:column;flex-wrap:wrap}.my-modal__wrapper .boxes__list{display:flex;flex-wrap:wrap;gap:5px 5px}@media (max-width: 1024px){.my-modal__wrapper .boxes__list{justify-content:center}}.my-modal__wrapper .boxes__box-content{width:100%;margin-bottom:5px;height:500px;text-align:left;display:flex;flex-direction:row;justify-content:space-between;position:relative}.my-modal__wrapper .boxes__box-content .closebtn{position:absolute;right:10px;top:10px;width:53px;height:53px;cursor:pointer;object-fit:cover;z-index:9999}@media (max-width: 1024px){.my-modal__wrapper .boxes__box-content{flex-direction:column-reverse;height:auto}}@media (max-width: 768px){.my-modal__wrapper .boxes__box-content{margin:0 auto}}.my-modal__wrapper .boxes__box-content__info{width:40%;padding:50px 40px;position:relative}@media (max-width: 1024px){.my-modal__wrapper .boxes__box-content__info{width:100%;padding:15px;min-height:100px}}@media (max-width: 768px){.my-modal__wrapper .boxes__box-content__info{min-height:auto}}.my-modal__wrapper .boxes__box-content__info h2{font-size:35px;font-weight:normal;margin-bottom:30px;color:#232323}@media (max-width: 768px){.my-modal__wrapper .boxes__box-content__info h2{font-size:16px;text-align:center;margin-bottom:15px;margin-top:5px}}.my-modal__wrapper .boxes__box-content__info h4{margin-top:0px;margin-bottom:15px;font-size:16px;color:#4c4c4c}.my-modal__wrapper .boxes__box-content__info .divider{border:1px solid #4c4c4c;opacity:0.2;margin-bottom:20px}@media (max-width: 768px){.my-modal__wrapper .boxes__box-content__info .divider{margin:10px 0px;display:none}}.my-modal__wrapper .boxes__box-content__info__value{display:flex;flex-direction:row;justify-content:flex-start}@media (max-width: 1024px){.my-modal__wrapper .boxes__box-content__info__value{justify-content:flex-start}}@media (max-width: 768px){.my-modal__wrapper .boxes__box-content__info__value{flex-direction:column}}@media (max-width: 768px){.my-modal__wrapper .boxes__box-content__info__value-image{margin:0 auto;margin-bottom:10px}}.my-modal__wrapper .boxes__box-content__info__value-image img{width:114px;object-fit:cover}@media (max-width: 1024px){.my-modal__wrapper .boxes__box-content__info__value-image img{width:75px}}.my-modal__wrapper .boxes__box-content__info__value-product{color:#232323;margin-left:10px}@media (max-width: 1024px){.my-modal__wrapper .boxes__box-content__info__value-product h2{font-size:26px;margin:0;margin-right:10px}}@media (max-width: 768px){.my-modal__wrapper .boxes__box-content__info__value-product h2{font-size:16px}}.my-modal__wrapper .boxes__box-content__info__value-product p{font-size:20px;margin-top:0px;margin-bottom:0px}.my-modal__wrapper .boxes__box-content__info__value-product p:last-of-type{margin-bottom:20px}@media (max-width: 1024px){.my-modal__wrapper .boxes__box-content__info__value-product p:last-of-type{margin-bottom:0}}@media (max-width: 768px){.my-modal__wrapper .boxes__box-content__info__value-product p{font-size:10px}}@media (max-width: 1024px){.my-modal__wrapper .boxes__box-content__info__value-product>div{display:flex;justify-content:flex-start;align-items:center}}@media (max-width: 768px){.my-modal__wrapper .boxes__box-content__info__value-product>div{flex-direction:column}}.my-modal__wrapper .boxes__box-content__slider{width:60%;min-width:60%;max-width:60%;position:relative}@media (max-width: 1024px){.my-modal__wrapper .boxes__box-content__slider{width:100%;display:block;min-width:100%;max-width:100%}}.my-modal__wrapper .boxes__box-content__slider .color-big-image{width:100%;height:100%;object-fit:cover}@media (max-width: 1024px){.my-modal__wrapper .boxes__box-content__slider .color-big-image{height:300px}}.my-modal__wrapper .boxes__box-content__white *{color:#fff}.my-modal__wrapper .boxes__box-content__white h2{color:#fff}.my-modal__wrapper .pagination{margin:10px 0px;font-size:16px;display:flex;flex-direction:row;align-items:center;justify-content:center}.my-modal__wrapper .pagination>span{margin:0 3px;cursor:pointer;min-width:20px;padding:5px;box-shadow:1px 1px 1px #ccc}.my-modal__wrapper .pagination .current{background-color:wheat}.my-modal .categories{padding-bottom:20px;margin-bottom:20px;border-bottom:1px solid #dfdfdf;display:flex;flex-direction:column;align-items:flex-start}.my-modal .categories__container{display:flex;flex-wrap:nowrap;gap:5px 5px;overflow-x:auto;width:100%}@media (max-width: 1024px){.my-modal .categories__container{padding-bottom:5px}}.my-modal .categories__slide-information{display:flex;flex-direction:row;align-items:center;justify-content:space-between}.my-modal .categories__slide-information span{color:#4c4c4c;font-size:16px;font-weight:normal}.my-modal .categories__slide-information span:first-of-type{margin-left:7px}.my-modal .categories__slide-information span:last-of-type{margin-right:7px}.my-modal .button,.my-modal a{background-color:#fff;font-size:16px;box-shadow:0px 10px 20px rgba(0, 0, 0, 0.1);border-radius:22px;padding:10px 35px;color:#232323;text-decoration:none;display:block;text-align:center;transition:all 0.7s ease-in-out;border:none;cursor:pointer}.my-modal .button:hover,.my-modal a:hover{color:#fff;background-color:#232323}.my-modal .button.brown,.my-modal a.brown{background-color:#3c2114;color:#fff}.my-modal .button.brown:hover,.my-modal a.brown:hover{color:#fff;background-color:#232323}.my-modal .button.inverse,.my-modal a.inverse{background-color:#232323;color:#fff}.my-modal .button.inverse:hover,.my-modal a.inverse:hover{color:#232323;background-color:#fff}@media (max-width: 1024px){.my-modal .button,.my-modal a{max-width:150px;font-size:13px;padding:12px 25px}}@media (max-width: 768px){.my-modal .button,.my-modal a{margin:0 auto}}.my-modal>.button{margin:10px auto}";
|
|
3475
|
-
|
|
3476
|
-
const Modal = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
3477
|
-
constructor() {
|
|
3478
|
-
super();
|
|
3479
|
-
this.__registerHost();
|
|
3480
|
-
this.onSelectedColorEmit = createEvent(this, "onSelectedColorEmit", 7);
|
|
3481
|
-
this.clearSearchText = createEvent(this, "clearSearchText", 7);
|
|
3482
|
-
this.close = createEvent(this, "close", 7);
|
|
3483
|
-
this.readyToCLose = createEvent(this, "readyToCLose", 7);
|
|
3484
|
-
this.boxDesktopWidth = 130;
|
|
3485
|
-
this.boxMobileWidth = 70;
|
|
3486
|
-
this.desktopPadding = 75;
|
|
3487
|
-
this.mobilePadding = 35;
|
|
3488
|
-
this.mediumBreakpoint = 1024;
|
|
3489
|
-
this.clearInterval = () => {
|
|
3490
|
-
this.colorTimerInterval && clearInterval(this.colorTimerInterval);
|
|
3491
|
-
this.colorTimerInterval = undefined;
|
|
3492
|
-
};
|
|
3493
|
-
this.colorTimer = () => {
|
|
3494
|
-
if (this.currentColor && this.currentColor.id) {
|
|
3495
|
-
this.colorTimerInterval = setInterval(() => {
|
|
3496
|
-
var _a, _b;
|
|
3497
|
-
((_a = this.currentColor) === null || _a === void 0 ? void 0 : _a.name) &&
|
|
3498
|
-
setDataLayer({
|
|
3499
|
-
event: 'ColorTimer',
|
|
3500
|
-
shop: this.shop,
|
|
3501
|
-
product: this.product,
|
|
3502
|
-
color: (_b = this.currentColor) === null || _b === void 0 ? void 0 : _b.name,
|
|
3503
|
-
timer: '10',
|
|
3504
|
-
});
|
|
3505
|
-
}, 10000);
|
|
3506
|
-
}
|
|
3507
|
-
else {
|
|
3508
|
-
this.clearInterval();
|
|
3509
|
-
}
|
|
3510
|
-
};
|
|
3511
|
-
this.chunks = (xs, y = []) => {
|
|
3512
|
-
return xs.length === 0 ? y : this.chunks(xs.slice(this.chunksNum), y.concat([xs.slice(0, this.chunksNum)]));
|
|
3513
|
-
};
|
|
3514
|
-
this.calculateBoxCount = () => {
|
|
3515
|
-
var _a;
|
|
3516
|
-
const modalWidth = this.modalEl.children && this.modalEl.children[0] && ((_a = this.modalEl.children[0]) === null || _a === void 0 ? void 0 : _a.clientWidth) - this.padding;
|
|
3517
|
-
const boxWidth = this.boxWidth;
|
|
3518
|
-
const calc = Math.floor(modalWidth / boxWidth);
|
|
3519
|
-
const boxesCount = calc;
|
|
3520
|
-
if (!this.preloader)
|
|
3521
|
-
this.chunksNum = boxesCount;
|
|
3522
|
-
};
|
|
3523
|
-
this.displayForMobile = () => {
|
|
3524
|
-
if (window.innerWidth < this.mediumBreakpoint) {
|
|
3525
|
-
this.boxWidth = this.boxMobileWidth;
|
|
3526
|
-
this.padding = this.mobilePadding;
|
|
3527
|
-
this.isMobile = true;
|
|
3528
|
-
}
|
|
3529
|
-
else {
|
|
3530
|
-
this.isMobile = false;
|
|
3531
|
-
this.boxWidth = this.boxDesktopWidth;
|
|
3532
|
-
this.padding = this.desktopPadding;
|
|
3533
|
-
}
|
|
3534
|
-
};
|
|
3535
|
-
this.handleSampleSelect = (selectedSample) => {
|
|
3536
|
-
this.currentColor = null;
|
|
3537
|
-
this.selectedCategory = selectedSample.value;
|
|
3538
|
-
this.updateFilterAndFetch({ sampleId: selectedSample.value, colorFamily: '' });
|
|
3539
|
-
};
|
|
3540
|
-
this.shop = undefined;
|
|
3541
|
-
this.product = undefined;
|
|
3542
|
-
this.baselink = undefined;
|
|
3543
|
-
this.selectedcolor = undefined;
|
|
3544
|
-
this.arrowDown = 'arrow_down.png';
|
|
3545
|
-
this.chunksNum = 12;
|
|
3546
|
-
this.data = null;
|
|
3547
|
-
this.preloader = false;
|
|
3548
|
-
this.loading = false;
|
|
3549
|
-
this.currentColor = null;
|
|
3550
|
-
this.currentIndex = null;
|
|
3551
|
-
this.infoBoxWidth = null;
|
|
3552
|
-
this.boxWidth = this.boxDesktopWidth;
|
|
3553
|
-
this.padding = this.desktopPadding;
|
|
3554
|
-
this.isMobile = false;
|
|
3555
|
-
this.showRange = false;
|
|
3556
|
-
this.colorCategories = null;
|
|
3557
|
-
this.selectedCategory = null;
|
|
3558
|
-
this.page = 1;
|
|
3559
|
-
this.colorIsSelected = false;
|
|
3560
|
-
this.colorsList = [];
|
|
3561
|
-
this.hasMore = true;
|
|
3562
|
-
this.filters = {
|
|
3563
|
-
type: 'product',
|
|
3564
|
-
id: '',
|
|
3565
|
-
productId: '',
|
|
3566
|
-
page: 1,
|
|
3567
|
-
colorNumber: '',
|
|
3568
|
-
colorName: '',
|
|
3569
|
-
};
|
|
3570
|
-
this.debouncedSearchColorsHandler = debounce(this.searchColor.bind(this), 300);
|
|
3571
|
-
}
|
|
3572
|
-
setInfoBoxWidth(newValue) {
|
|
3573
|
-
this.infoBoxWidth = newValue * this.boxWidth;
|
|
3574
|
-
}
|
|
3575
|
-
watchPropHandler(newValue) {
|
|
3576
|
-
if (newValue) {
|
|
3577
|
-
this.filters = updateFilters(this.filters, { id: newValue.id, type: 'product' });
|
|
3578
|
-
this.fetchColorsData();
|
|
3579
|
-
}
|
|
3580
|
-
}
|
|
3581
|
-
async open() {
|
|
3582
|
-
this.modalEl.style.display = 'block';
|
|
3583
|
-
}
|
|
3584
|
-
closeModalHandler() {
|
|
3585
|
-
this.close.emit();
|
|
3586
|
-
}
|
|
3587
|
-
handleReadyToClose(value) {
|
|
3588
|
-
this.readyToCLose.emit({ observable: value });
|
|
3589
|
-
}
|
|
3590
|
-
closeInfoBoxHandler() {
|
|
3591
|
-
this.currentColor = null;
|
|
3592
|
-
this.currentIndex = null;
|
|
3593
|
-
}
|
|
3594
|
-
handleEmitColor(event) {
|
|
3595
|
-
this.onSelectedColorEmit.emit(event.detail);
|
|
3596
|
-
}
|
|
3597
|
-
handleResize() {
|
|
3598
|
-
this.calculateBoxCount();
|
|
3599
|
-
this.displayForMobile();
|
|
3600
|
-
}
|
|
3601
|
-
sortColorsBySimilarity(colors) {
|
|
3602
|
-
if (colors.length <= 1)
|
|
3603
|
-
return colors;
|
|
3604
|
-
const sortedColors = [];
|
|
3605
|
-
const remainingColors = [...colors];
|
|
3606
|
-
// Start with the first color
|
|
3607
|
-
sortedColors.push(remainingColors.shift());
|
|
3608
|
-
while (remainingColors.length > 0) {
|
|
3609
|
-
// Find the most similar color to the last color in sortedColors
|
|
3610
|
-
const lastColor = sortedColors[sortedColors.length - 1];
|
|
3611
|
-
let mostSimilarIndex = 0;
|
|
3612
|
-
let minDistance = Infinity;
|
|
3613
|
-
remainingColors.forEach((color, index) => {
|
|
3614
|
-
const distance = chroma.distance(lastColor.hex, color.hex, 'lab');
|
|
3615
|
-
if (distance < minDistance) {
|
|
3616
|
-
minDistance = distance;
|
|
3617
|
-
mostSimilarIndex = index;
|
|
3618
|
-
}
|
|
3619
|
-
});
|
|
3620
|
-
// Move the most similar color to sortedColors
|
|
3621
|
-
sortedColors.push(remainingColors.splice(mostSimilarIndex, 1)[0]);
|
|
3622
|
-
}
|
|
3623
|
-
return sortedColors;
|
|
3624
|
-
}
|
|
3625
|
-
getColorHueGroup(hex) {
|
|
3626
|
-
const color = chroma(hex);
|
|
3627
|
-
const hue = color.get('hsl.h');
|
|
3628
|
-
const saturation = color.get('hsl.s');
|
|
3629
|
-
const lightness = color.get('hsl.l');
|
|
3630
|
-
// Handle grayscale colors
|
|
3631
|
-
if (saturation < 0.1) {
|
|
3632
|
-
if (lightness < 0.2)
|
|
3633
|
-
return 'black';
|
|
3634
|
-
if (lightness > 0.8)
|
|
3635
|
-
return 'white';
|
|
3636
|
-
return 'gray';
|
|
3637
|
-
}
|
|
3638
|
-
// Group colors by hue ranges
|
|
3639
|
-
if (hue >= 330 || hue < 30)
|
|
3640
|
-
return 'red';
|
|
3641
|
-
if (hue >= 30 && hue < 90)
|
|
3642
|
-
return 'yellow';
|
|
3643
|
-
if (hue >= 90 && hue < 150)
|
|
3644
|
-
return 'green';
|
|
3645
|
-
if (hue >= 150 && hue < 210)
|
|
3646
|
-
return 'cyan';
|
|
3647
|
-
if (hue >= 210 && hue < 270)
|
|
3648
|
-
return 'blue';
|
|
3649
|
-
if (hue >= 270 && hue < 330)
|
|
3650
|
-
return 'magenta';
|
|
3651
|
-
return 'other';
|
|
3652
|
-
}
|
|
3653
|
-
sortColorsByHueAndSimilarity(colors) {
|
|
3654
|
-
if (colors.length <= 1)
|
|
3655
|
-
return colors;
|
|
3656
|
-
// Group colors by their hue family
|
|
3657
|
-
const colorGroups = {
|
|
3658
|
-
red: [],
|
|
3659
|
-
yellow: [],
|
|
3660
|
-
green: [],
|
|
3661
|
-
cyan: [],
|
|
3662
|
-
blue: [],
|
|
3663
|
-
magenta: [],
|
|
3664
|
-
gray: [],
|
|
3665
|
-
black: [],
|
|
3666
|
-
white: [],
|
|
3667
|
-
other: [],
|
|
3668
|
-
};
|
|
3669
|
-
// Sort colors into groups
|
|
3670
|
-
colors.forEach(color => {
|
|
3671
|
-
const group = this.getColorHueGroup(color.hex);
|
|
3672
|
-
colorGroups[group].push(color);
|
|
3673
|
-
});
|
|
3674
|
-
// Sort each group by similarity
|
|
3675
|
-
const sortedGroups = [];
|
|
3676
|
-
const groupOrder = ['red', 'magenta', 'blue', 'cyan', 'green', 'yellow', 'gray', 'black', 'white', 'other'];
|
|
3677
|
-
groupOrder.forEach(groupName => {
|
|
3678
|
-
if (colorGroups[groupName].length > 0) {
|
|
3679
|
-
sortedGroups.push(this.sortColorsBySimilarity(colorGroups[groupName]));
|
|
3680
|
-
}
|
|
3681
|
-
});
|
|
3682
|
-
// Combine all sorted groups
|
|
3683
|
-
return sortedGroups.flat();
|
|
3684
|
-
}
|
|
3685
|
-
async fetchColorsData({ reset = false } = {}) {
|
|
3686
|
-
if (this.loading && !reset)
|
|
3687
|
-
return;
|
|
3688
|
-
this.loading = true;
|
|
3689
|
-
try {
|
|
3690
|
-
const colors = await fetchColors(this.filters);
|
|
3691
|
-
if (reset) {
|
|
3692
|
-
// For new searches, sort all colors by hue and similarity
|
|
3693
|
-
this.colorsList = this.sortColorsByHueAndSimilarity(colors);
|
|
3694
|
-
}
|
|
3695
|
-
else {
|
|
3696
|
-
// For pagination, combine and sort all colors
|
|
3697
|
-
this.colorsList = this.sortColorsByHueAndSimilarity([...this.colorsList, ...colors]);
|
|
3698
|
-
}
|
|
3699
|
-
this.hasMore = colors.length >= limit$1;
|
|
3700
|
-
}
|
|
3701
|
-
catch (error) {
|
|
3702
|
-
console.error('Error fetching colors:', error);
|
|
3703
|
-
}
|
|
3704
|
-
finally {
|
|
3705
|
-
this.loading = false;
|
|
3706
|
-
}
|
|
3707
|
-
}
|
|
3708
|
-
async loadProductData() {
|
|
3709
|
-
this.preloader = true;
|
|
3710
|
-
const product = await fetchProductData({ shopName: this.shop, productName: this.product });
|
|
3711
|
-
if (product) {
|
|
3712
|
-
this.data = product;
|
|
3713
|
-
this.filters = updateFilters(this.filters, { type: 'product', id: product.id });
|
|
3714
|
-
// Fetch initial colors
|
|
3715
|
-
await this.fetchColorsData();
|
|
3716
|
-
}
|
|
3717
|
-
this.preloader = false;
|
|
3718
|
-
}
|
|
3719
|
-
async loadMoreColors() {
|
|
3720
|
-
if (this.loading || !this.hasMore)
|
|
3721
|
-
return; // Prevent spam loading
|
|
3722
|
-
this.filters = Object.assign(Object.assign({}, this.filters), { page: this.filters.page + 1 }); // Increase page for lazy loading
|
|
3723
|
-
await this.fetchColorsData({ reset: false }); // Append results
|
|
3724
|
-
}
|
|
3725
|
-
updateFilterAndFetch(newFilters) {
|
|
3726
|
-
var _a;
|
|
3727
|
-
if (!((_a = this.data) === null || _a === void 0 ? void 0 : _a.id))
|
|
3728
|
-
return;
|
|
3729
|
-
this.loading = true;
|
|
3730
|
-
this.filters = updateFilters(this.filters, Object.assign(Object.assign({ id: this.data.id, sampleId: this.filters.sampleId, colorName: this.filters.colorName }, newFilters), { page: 1 }));
|
|
3731
|
-
this.fetchColorsData({ reset: true }).finally(() => {
|
|
3732
|
-
this.loading = false;
|
|
3733
|
-
});
|
|
3734
|
-
}
|
|
3735
|
-
async searchColor(event) {
|
|
3736
|
-
var _a;
|
|
3737
|
-
const query = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.trim();
|
|
3738
|
-
this.updateFilterAndFetch({ colorName: query });
|
|
3739
|
-
}
|
|
3740
|
-
handleColorFamilySelected(event) {
|
|
3741
|
-
this.currentColor = null;
|
|
3742
|
-
if (event.detail === this.filters.colorFamily) {
|
|
3743
|
-
this.filters = updateFilters(this.filters, { colorFamily: '' });
|
|
3744
|
-
this.updateFilterAndFetch({ colorFamily: '' });
|
|
3745
|
-
}
|
|
3746
|
-
else {
|
|
3747
|
-
this.filters = updateFilters(this.filters, { colorFamily: event.detail });
|
|
3748
|
-
this.updateFilterAndFetch({ colorFamily: event.detail });
|
|
3749
|
-
}
|
|
3750
|
-
}
|
|
3751
|
-
searchColorsHandler(event) {
|
|
3752
|
-
this.loading = true;
|
|
3753
|
-
this.currentColor = null;
|
|
3754
|
-
this.debouncedSearchColorsHandler(event);
|
|
3755
|
-
}
|
|
3756
|
-
handleScroll(_event, modalContent) {
|
|
3757
|
-
if (this.loading || !this.hasMore)
|
|
3758
|
-
return;
|
|
3759
|
-
const scrollTop = modalContent.scrollTop;
|
|
3760
|
-
const scrollHeight = modalContent.scrollHeight;
|
|
3761
|
-
const clientHeight = modalContent.clientHeight;
|
|
3762
|
-
// Check if user scrolled to the bottom of the modal
|
|
3763
|
-
if (scrollTop + clientHeight >= scrollHeight - 50) {
|
|
3764
|
-
this.loadMoreColors();
|
|
3765
|
-
}
|
|
3766
|
-
}
|
|
3767
|
-
openSeletedColor() {
|
|
3768
|
-
var _a, _b;
|
|
3769
|
-
if (!this.colorsList || !this.selectedcolor)
|
|
3770
|
-
return;
|
|
3771
|
-
if (!this.colorIsSelected) {
|
|
3772
|
-
const result = this.chunks(this.colorsList)
|
|
3773
|
-
.map((innerArray, arrayIndex) => {
|
|
3774
|
-
const foundColor = innerArray.find(color => { var _a, _b, _c; return ((_a = color.name.trim()) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === ((_c = (_b = this.selectedcolor) === null || _b === void 0 ? void 0 : _b.trim()) === null || _c === void 0 ? void 0 : _c.toUpperCase()); });
|
|
3775
|
-
return foundColor ? { color: foundColor, index: arrayIndex } : null;
|
|
3776
|
-
})
|
|
3777
|
-
.filter(item => item !== null);
|
|
3778
|
-
this.currentColor = (_a = result[0]) === null || _a === void 0 ? void 0 : _a.color;
|
|
3779
|
-
this.currentIndex = (_b = result[0]) === null || _b === void 0 ? void 0 : _b.index;
|
|
3780
|
-
this.colorIsSelected = true;
|
|
3781
|
-
}
|
|
3782
|
-
}
|
|
3783
|
-
componentWillLoad() {
|
|
3784
|
-
this.preloader = true;
|
|
3785
|
-
setDataLayer({
|
|
3786
|
-
shop: this.shop,
|
|
3787
|
-
product: this.product,
|
|
3788
|
-
});
|
|
3789
|
-
this.loadProductData();
|
|
3790
|
-
}
|
|
3791
|
-
componentWillRender() {
|
|
3792
|
-
this.displayForMobile();
|
|
3793
|
-
this.calculateBoxCount();
|
|
3794
|
-
this.colorTimer();
|
|
3795
|
-
this.openSeletedColor();
|
|
3796
|
-
const modalContent = this.modalEl.querySelector('.my-modal');
|
|
3797
|
-
if (modalContent) {
|
|
3798
|
-
modalContent.addEventListener('scroll', event => this.handleScroll(event, modalContent));
|
|
3799
|
-
}
|
|
3800
|
-
}
|
|
3801
|
-
resetColors() {
|
|
3802
|
-
this.currentColor = null;
|
|
3803
|
-
this.currentIndex = null;
|
|
3804
|
-
this.colorIsSelected = false;
|
|
3805
|
-
}
|
|
3806
|
-
resetAllFilters() {
|
|
3807
|
-
var _a;
|
|
3808
|
-
// Reset current color selection
|
|
3809
|
-
this.resetColors();
|
|
3810
|
-
// Reset filters to initial state
|
|
3811
|
-
this.filters = {
|
|
3812
|
-
type: 'product',
|
|
3813
|
-
id: ((_a = this.data) === null || _a === void 0 ? void 0 : _a.id) || '',
|
|
3814
|
-
productId: '',
|
|
3815
|
-
page: 1,
|
|
3816
|
-
colorNumber: '',
|
|
3817
|
-
colorName: '',
|
|
3818
|
-
colorFamily: '',
|
|
3819
|
-
sampleId: '',
|
|
3820
|
-
};
|
|
3821
|
-
// Reset selected category
|
|
3822
|
-
this.selectedCategory = null;
|
|
3823
|
-
// Clear search text
|
|
3824
|
-
this.clearSearchText.emit();
|
|
3825
|
-
// Fetch colors with reset filters
|
|
3826
|
-
this.fetchColorsData({ reset: true });
|
|
3827
|
-
}
|
|
3828
|
-
resetSelectedCategory() {
|
|
3829
|
-
this.resetColors();
|
|
3830
|
-
this.colorIsSelected = false;
|
|
3831
|
-
this.selectedCategory = null;
|
|
3832
|
-
this.filters = updateFilters(this.filters, { sampleId: '' });
|
|
3833
|
-
this.fetchColorsData({ reset: true });
|
|
3834
|
-
}
|
|
3835
|
-
render() {
|
|
3836
|
-
var _a;
|
|
3837
|
-
return (h("div", { class: `my-modal`, onMouseEnter: () => this.handleReadyToClose(false), onMouseLeave: () => this.handleReadyToClose(true) }, this.preloader && (h("div", { class: 'loader' }, h("my-loader", null))), !this.preloader && this.data && (h("modal-header", { modalName: this.data.modalName, modalLogo: this.data.modalLogo ? `${APIURL}/assets/${this.data.modalLogo}?access_token=${accessToken}` : null, modalDescription: this.data.modalDescription, shop: this.shop, productName: this.data.name, productSamples: this.data.productSamples, selectedColorFamily: this.filters.colorFamily, isMobile: this.isMobile, onCloseModal: () => this.closeModalHandler(), onSampleSelected: event => this.handleSampleSelect(event.detail), onOnLogoClick: () => this.resetAllFilters(), onOnResetCategory: () => this.resetSelectedCategory() })), h("div", { class: 'my-modal__wrapper' }, !this.preloader && (h("div", { class: 'container_boxes' }, !this.loading && this.colorsList.length === 0 && (h("div", { class: "not-found" }, h("p", null, "Nie zaleziono wynik\u00F3w wyszukiwania pod danym has\u0142em."), h("p", null, " Wpisz inn\u0105 nazw\u0119 b\u0105d\u017A numer koloru lub skorzystaj z kolekcji kolorystycznych."))), ((_a = this.colorsList) === null || _a === void 0 ? void 0 : _a.length) > 0 &&
|
|
3838
|
-
this.chunks(this.colorsList).map((color, index) => {
|
|
3839
|
-
var _a;
|
|
3840
|
-
return (h("div", { key: index, class: "boxes" }, h("div", { class: "boxes__list" }, color.map((c) => {
|
|
3841
|
-
var _a;
|
|
3842
|
-
return (h("my-colorbox", { key: c.id, onClick: () => {
|
|
3843
|
-
var _a;
|
|
3844
|
-
if (((_a = this.currentColor) === null || _a === void 0 ? void 0 : _a.id) === c.id) {
|
|
3845
|
-
this.currentColor = null;
|
|
3846
|
-
}
|
|
3847
|
-
else {
|
|
3848
|
-
this.currentColor = c;
|
|
3849
|
-
}
|
|
3850
|
-
this.currentIndex = index;
|
|
3851
|
-
setDataLayer({
|
|
3852
|
-
event: 'ColorClick',
|
|
3853
|
-
shop: this.shop,
|
|
3854
|
-
product: this.product,
|
|
3855
|
-
color: c.name,
|
|
3856
|
-
});
|
|
3857
|
-
this.clearInterval();
|
|
3858
|
-
}, color: c.hex, name: c.name, isActive: ((_a = this.currentColor) === null || _a === void 0 ? void 0 : _a.id) === c.id, shop: this.shop, product: this.product, isImageInsteadHex: {
|
|
3859
|
-
isImageInsteadHex: c.imageInsteadHex,
|
|
3860
|
-
bigImage: c.bigImage,
|
|
3861
|
-
} }));
|
|
3862
|
-
})), ((_a = this.currentColor) === null || _a === void 0 ? void 0 : _a.id) && index === this.currentIndex && (h("my-colorinfo", { currentColor: this.currentColor, shop: this.shop, product: this.product, data: this.data, isMobile: this.isMobile, infoBoxWidth: this.infoBoxWidth, baselink: this.baselink }))));
|
|
3863
|
-
}))), this.loading && h("my-loader", null)), !this.preloader && this.isMobile && (h("button", { class: "button", onClick: () => this.closeModalHandler() }, "Zamknij"))));
|
|
3864
|
-
}
|
|
3865
|
-
static get assetsDirs() { return ["assets"]; }
|
|
3866
|
-
get modalEl() { return this; }
|
|
3867
|
-
static get watchers() { return {
|
|
3868
|
-
"chunksNum": ["setInfoBoxWidth"],
|
|
3869
|
-
"data": ["watchPropHandler"]
|
|
3870
|
-
}; }
|
|
3871
|
-
static get style() { return indexCss; }
|
|
3872
|
-
}, [0, "my-modal", {
|
|
3873
|
-
"shop": [1],
|
|
3874
|
-
"product": [1],
|
|
3875
|
-
"baselink": [1],
|
|
3876
|
-
"selectedcolor": [1],
|
|
3877
|
-
"arrowDown": [1, "arrow-down"],
|
|
3878
|
-
"chunksNum": [32],
|
|
3879
|
-
"data": [32],
|
|
3880
|
-
"preloader": [32],
|
|
3881
|
-
"loading": [32],
|
|
3882
|
-
"currentColor": [32],
|
|
3883
|
-
"currentIndex": [32],
|
|
3884
|
-
"infoBoxWidth": [32],
|
|
3885
|
-
"boxWidth": [32],
|
|
3886
|
-
"padding": [32],
|
|
3887
|
-
"isMobile": [32],
|
|
3888
|
-
"showRange": [32],
|
|
3889
|
-
"colorCategories": [32],
|
|
3890
|
-
"selectedCategory": [32],
|
|
3891
|
-
"page": [32],
|
|
3892
|
-
"colorIsSelected": [32],
|
|
3893
|
-
"colorsList": [32],
|
|
3894
|
-
"hasMore": [32],
|
|
3895
|
-
"filters": [32],
|
|
3896
|
-
"open": [64]
|
|
3897
|
-
}, [[0, "closeInfoBox", "closeInfoBoxHandler"], [0, "onCurrentColor", "handleEmitColor"], [9, "resize", "handleResize"], [0, "colorFamilySelected", "handleColorFamilySelected"], [0, "searchColors", "searchColorsHandler"]]]);
|
|
3898
|
-
function defineCustomElement() {
|
|
3899
|
-
if (typeof customElements === "undefined") {
|
|
3900
|
-
return;
|
|
3901
|
-
}
|
|
3902
|
-
const components = ["my-modal", "modal-header", "my-colorbox", "my-colorinfo", "my-loader", "my-search", "my-select", "my-slider"];
|
|
3903
|
-
components.forEach(tagName => { switch (tagName) {
|
|
3904
|
-
case "my-modal":
|
|
3905
|
-
if (!customElements.get(tagName)) {
|
|
3906
|
-
customElements.define(tagName, Modal);
|
|
3907
|
-
}
|
|
3908
|
-
break;
|
|
3909
|
-
case "modal-header":
|
|
3910
|
-
if (!customElements.get(tagName)) {
|
|
3911
|
-
defineCustomElement$7();
|
|
3912
|
-
}
|
|
3913
|
-
break;
|
|
3914
|
-
case "my-colorbox":
|
|
3915
|
-
if (!customElements.get(tagName)) {
|
|
3916
|
-
defineCustomElement$6();
|
|
3917
|
-
}
|
|
3918
|
-
break;
|
|
3919
|
-
case "my-colorinfo":
|
|
3920
|
-
if (!customElements.get(tagName)) {
|
|
3921
|
-
defineCustomElement$5();
|
|
3922
|
-
}
|
|
3923
|
-
break;
|
|
3924
|
-
case "my-loader":
|
|
3925
|
-
if (!customElements.get(tagName)) {
|
|
3926
|
-
defineCustomElement$4();
|
|
3927
|
-
}
|
|
3928
|
-
break;
|
|
3929
|
-
case "my-search":
|
|
3930
|
-
if (!customElements.get(tagName)) {
|
|
3931
|
-
defineCustomElement$3();
|
|
3932
|
-
}
|
|
3933
|
-
break;
|
|
3934
|
-
case "my-select":
|
|
3935
|
-
if (!customElements.get(tagName)) {
|
|
3936
|
-
defineCustomElement$2();
|
|
3937
|
-
}
|
|
3938
|
-
break;
|
|
3939
|
-
case "my-slider":
|
|
3940
|
-
if (!customElements.get(tagName)) {
|
|
3941
|
-
defineCustomElement$1();
|
|
3942
|
-
}
|
|
3943
|
-
break;
|
|
3944
|
-
} });
|
|
3945
|
-
}
|
|
3946
|
-
|
|
3947
|
-
export { Modal as M, defineCustomElement as d };
|
|
3948
|
-
|
|
3949
|
-
//# sourceMappingURL=index11.js.map
|