toosoon-utils 4.2.3 → 4.3.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 +501 -603
- package/lib/colors.d.ts +147 -66
- package/lib/colors.js +149 -63
- package/lib/constants.js +1 -1
- package/lib/dom.d.ts +1 -1
- package/lib/dom.js +1 -1
- package/lib/extras/colors/Color.d.ts +406 -0
- package/lib/extras/colors/Color.js +546 -0
- package/lib/extras/colors/ColorPalette.d.ts +105 -0
- package/lib/extras/colors/ColorPalette.js +124 -0
- package/lib/extras/colors/ColorScale.d.ts +257 -0
- package/lib/extras/colors/ColorScale.js +347 -0
- package/lib/extras/colors/_ColorScale.d.ts +62 -0
- package/lib/extras/colors/_ColorScale.js +156 -0
- package/lib/extras/colors/index.d.ts +3 -0
- package/lib/extras/colors/index.js +3 -0
- package/lib/extras/frame-rate/FrameRate.d.ts +12 -9
- package/lib/extras/frame-rate/FrameRate.js +10 -7
- package/lib/extras/geometry/Vector.d.ts +1 -1
- package/lib/extras/geometry/Vector2.d.ts +17 -11
- package/lib/extras/geometry/Vector2.js +29 -23
- package/lib/extras/geometry/Vector3.d.ts +5 -5
- package/lib/extras/geometry/Vector3.js +10 -10
- package/lib/extras/paths/Path.d.ts +3 -3
- package/lib/extras/paths/Path.js +10 -10
- package/lib/extras/paths/PathContext.d.ts +7 -10
- package/lib/extras/paths/PathContext.js +79 -102
- package/lib/extras/paths/PathSVG.d.ts +31 -25
- package/lib/extras/paths/PathSVG.js +36 -39
- package/lib/extras/paths/index.d.ts +1 -1
- package/lib/geometry.d.ts +7 -7
- package/lib/geometry.js +13 -13
- package/lib/maths.d.ts +19 -13
- package/lib/maths.js +23 -17
- package/lib/prng.d.ts +4 -4
- package/lib/prng.js +4 -4
- package/lib/random.d.ts +4 -4
- package/lib/random.js +4 -4
- package/lib/strings.d.ts +14 -8
- package/lib/strings.js +14 -8
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types.d.ts +15 -8
- package/package.json +14 -14
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
import { W3CX11 } from '../../constants';
|
|
2
|
+
import { lerp, triLerp } from '../../maths';
|
|
3
|
+
import { normalizeColor, normalizeHslString, hexToRgb, hslToRgb, hsbToRgb, labToRgb, hclToRgb, rgbToHex, rgbToHexString, rgbToHsl, rgbToHsb, rgbToLab, rgbToHcl } from '../../colors';
|
|
4
|
+
/**
|
|
5
|
+
* Utility class for manipulating colors
|
|
6
|
+
*
|
|
7
|
+
* @exports
|
|
8
|
+
* @class Color
|
|
9
|
+
*/
|
|
10
|
+
export default class Color {
|
|
11
|
+
isColor = true;
|
|
12
|
+
type = 'Color';
|
|
13
|
+
/**
|
|
14
|
+
* Red value of this color in the RGB color space
|
|
15
|
+
*/
|
|
16
|
+
r;
|
|
17
|
+
/**
|
|
18
|
+
* Green value of this color in the RGB color space
|
|
19
|
+
*/
|
|
20
|
+
g;
|
|
21
|
+
/**
|
|
22
|
+
* Blue value of this color in the RGB color space
|
|
23
|
+
*/
|
|
24
|
+
b;
|
|
25
|
+
*[Symbol.iterator]() {
|
|
26
|
+
yield this.r;
|
|
27
|
+
yield this.g;
|
|
28
|
+
yield this.b;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* @param {ColorRepresentation} [color=0x000000] Color representation of this color
|
|
32
|
+
*/
|
|
33
|
+
constructor(color = 0x000000) {
|
|
34
|
+
const [r, g, b] = normalizeColor(color);
|
|
35
|
+
this.r = r;
|
|
36
|
+
this.g = g;
|
|
37
|
+
this.b = b;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Set this color RGB values
|
|
41
|
+
*
|
|
42
|
+
* @param {Color|ColorRepresentation} color Color to set
|
|
43
|
+
* @returns {this}
|
|
44
|
+
*/
|
|
45
|
+
set(color) {
|
|
46
|
+
if (color instanceof Color) {
|
|
47
|
+
return this.copy(color);
|
|
48
|
+
}
|
|
49
|
+
const [r, g, b] = normalizeColor(color);
|
|
50
|
+
this.r = r;
|
|
51
|
+
this.g = g;
|
|
52
|
+
this.b = b;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Set this color values from a given color name
|
|
57
|
+
*
|
|
58
|
+
* @param {ColorName} colorName Color name of the color to set
|
|
59
|
+
* @returns {this}
|
|
60
|
+
*/
|
|
61
|
+
setColorName(colorName) {
|
|
62
|
+
const hex = W3CX11[colorName];
|
|
63
|
+
return this.setHex(hex);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Set this color values from a given RGB color
|
|
67
|
+
*
|
|
68
|
+
* Note:
|
|
69
|
+
* - RGB values are contained in the interval [0, 1]
|
|
70
|
+
*
|
|
71
|
+
* @param {ColorRgb} rgb RGB color
|
|
72
|
+
* @returns {this}
|
|
73
|
+
*/
|
|
74
|
+
setRgb([r, g, b]) {
|
|
75
|
+
this.r = r;
|
|
76
|
+
this.g = g;
|
|
77
|
+
this.b = b;
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Set this color values from a given hexadecimal color
|
|
82
|
+
*
|
|
83
|
+
* @param {ColorHex} hex Hexadecimal color
|
|
84
|
+
* @returns {this}
|
|
85
|
+
*/
|
|
86
|
+
setHex(hex) {
|
|
87
|
+
const rgb = hexToRgb(hex);
|
|
88
|
+
return this.setRgb(rgb);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Set this color values from a given HSL color
|
|
92
|
+
*
|
|
93
|
+
* Note:
|
|
94
|
+
* - HSL values are contained in the intervals:
|
|
95
|
+
* - Hue: [0, 360]
|
|
96
|
+
* - Saturation: [0, 1]
|
|
97
|
+
* - Lightness: [0, 1]
|
|
98
|
+
*
|
|
99
|
+
* @param {ColorHsl|string} hsl HSL color
|
|
100
|
+
* @returns {this}
|
|
101
|
+
*/
|
|
102
|
+
setHsl(hsl) {
|
|
103
|
+
if (typeof hsl === 'string') {
|
|
104
|
+
hsl = normalizeHslString(hsl);
|
|
105
|
+
}
|
|
106
|
+
const rgb = hslToRgb(hsl);
|
|
107
|
+
return this.setRgb(rgb);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Set this color values from a given HSB color
|
|
111
|
+
*
|
|
112
|
+
* Note:
|
|
113
|
+
* - HSB values are contained in the intervals:
|
|
114
|
+
* - Hue: [0, 360]
|
|
115
|
+
* - Saturation: [0, 1]
|
|
116
|
+
* - Brightness: [0, 1]
|
|
117
|
+
*
|
|
118
|
+
* @param {ColorHsb} hsb HSB color
|
|
119
|
+
* @returns {this}
|
|
120
|
+
*/
|
|
121
|
+
setHsb(hsb) {
|
|
122
|
+
const rgb = hsbToRgb(hsb);
|
|
123
|
+
return this.setRgb(rgb);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Set this color values from a given L*a*b* color
|
|
127
|
+
*
|
|
128
|
+
* Note:
|
|
129
|
+
* - L*a*b* values are contained in the intervals:
|
|
130
|
+
* - Lightness: [0 à 100]
|
|
131
|
+
* - a (green, red): [~-128, ~+128]
|
|
132
|
+
* - b (blue, yellow): [~-128, ~+128]
|
|
133
|
+
*
|
|
134
|
+
* @param {ColorLab} lab L*a*b* color
|
|
135
|
+
* @returns {this}
|
|
136
|
+
*/
|
|
137
|
+
setLab(lab) {
|
|
138
|
+
const rgb = labToRgb(lab);
|
|
139
|
+
return this.setRgb(rgb);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Set this color values from a given HCL color
|
|
143
|
+
*
|
|
144
|
+
* Note:
|
|
145
|
+
* - HCL values are contained in the intervals:
|
|
146
|
+
* - Hue: [0, 360]
|
|
147
|
+
* - Chroma: [0, ~150]
|
|
148
|
+
* - Lightness: [0, 100]
|
|
149
|
+
*
|
|
150
|
+
* @param {ColorHcl} hcl HCL color
|
|
151
|
+
* @returns {this}
|
|
152
|
+
*/
|
|
153
|
+
setHcl(hcl) {
|
|
154
|
+
const rgb = hclToRgb(hcl);
|
|
155
|
+
return this.setRgb(rgb);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Linearly interpolate this color values to given color values
|
|
159
|
+
*
|
|
160
|
+
* @param {number} t Normalized time value to interpolate
|
|
161
|
+
* @param {Color|ColorRgb} color Color to interpolate values towards
|
|
162
|
+
* @returns {this}
|
|
163
|
+
*/
|
|
164
|
+
lerp(t, [r, g, b]) {
|
|
165
|
+
this.r += (r - this.r) * t;
|
|
166
|
+
this.g += (g - this.g) * t;
|
|
167
|
+
this.b += (b - this.b) * t;
|
|
168
|
+
return this;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Linearly interpolate this color RGB values towards given RGB values
|
|
172
|
+
*
|
|
173
|
+
* @param {number} t Normalized time value to interpolate
|
|
174
|
+
* @param {ColorRgb} rgb RGB values to interpolate towards
|
|
175
|
+
* @param {object} [params] Interpolation parameters
|
|
176
|
+
* @param {number} [params.power] Interpolation exponent
|
|
177
|
+
* @returns {this}
|
|
178
|
+
*/
|
|
179
|
+
lerpRgb(t, rgb, params) {
|
|
180
|
+
return this.setRgb(Color.lerpRgb(t, this.rgb, rgb, params));
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Linearly interpolate this color HSL values towards given HSL values
|
|
184
|
+
*
|
|
185
|
+
* @param {number} t Normalized time value to interpolate
|
|
186
|
+
* @param {ColorHsl} hsl HSL values to interpolate towards
|
|
187
|
+
* @param {object} [params] Interpolation parameters
|
|
188
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : [h, s, l]
|
|
189
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
190
|
+
* @returns {this}
|
|
191
|
+
*/
|
|
192
|
+
lerpHsl(t, hsl, params) {
|
|
193
|
+
return this.setHsl(Color.lerpHsl(t, this.hsl, hsl));
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Linearly interpolate this color HSB values towards given HSB values
|
|
197
|
+
*
|
|
198
|
+
* @param {number} t Normalized time value to interpolate
|
|
199
|
+
* @param {ColorHsb} hsb HSB values to interpolate towards
|
|
200
|
+
* @param {object} [params] Interpolation parameters
|
|
201
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : [h, s, b]
|
|
202
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
203
|
+
* @returns {this}
|
|
204
|
+
*/
|
|
205
|
+
lerpHsb(t, hsb, params) {
|
|
206
|
+
return this.setHsb(Color.lerpHsb(t, this.hsb, hsb, params));
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Interpolate this color HCL values towards given HCL values following HCL Qualitative color palettes algorithm
|
|
210
|
+
*
|
|
211
|
+
* @param {number} t Normalized time value to interpolate
|
|
212
|
+
* @param {ColorHcl} hcl HCL values to interpolate towards
|
|
213
|
+
* @param {object} [params] Interpolation parameters
|
|
214
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
215
|
+
* @returns {this}
|
|
216
|
+
*/
|
|
217
|
+
interpolateQualitative(t, hcl, params) {
|
|
218
|
+
return this.setHcl(Color.interpolateQualitative(t, this.hcl, hcl, params));
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Interpolate this color HCL values towards given HCL values following HCL Sequential color palettes algorithm
|
|
222
|
+
*
|
|
223
|
+
* @param {number} t Normalized time value to interpolate
|
|
224
|
+
* @param {ColorHcl} hcl HCL values to interpolate towards
|
|
225
|
+
* @param {object} [params] Interpolation parameters
|
|
226
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : [c, l]
|
|
227
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
228
|
+
* @param {number} [params.chromaMax] Maximum chroma value
|
|
229
|
+
* @returns {this}
|
|
230
|
+
*/
|
|
231
|
+
interpolateSequential(t, hcl, params) {
|
|
232
|
+
return this.setHcl(Color.interpolateSequential(t, this.hcl, hcl, params));
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Interpolate this color HCL values towards given HCL values following HCL Diverging color palettes algorithm
|
|
236
|
+
*
|
|
237
|
+
* @param {number} t Normalized time value to interpolate
|
|
238
|
+
* @param {ColorHcl} hcl HCL values to interpolate towards
|
|
239
|
+
* @param {object} [params] Interpolation parameters
|
|
240
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : ([c, l])
|
|
241
|
+
* @returns {this}
|
|
242
|
+
*/
|
|
243
|
+
interpolateDiverging(t, hcl, params) {
|
|
244
|
+
return this.setHcl(Color.interpolateDiverging(t, this.hcl, hcl, params));
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Check if this color is equal with a given color
|
|
248
|
+
*
|
|
249
|
+
* @param {Color|ColorRgb} color Color to check
|
|
250
|
+
* @returns {boolean} True if this color is equal with the given color, false otherwise
|
|
251
|
+
*/
|
|
252
|
+
equals(color) {
|
|
253
|
+
return Color.equals(this, color);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Return this color RGB values into an array
|
|
257
|
+
*
|
|
258
|
+
* @returns {ColorRgb}
|
|
259
|
+
*/
|
|
260
|
+
toArray() {
|
|
261
|
+
return this.rgb;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Set this color RGB values from a given array
|
|
265
|
+
*
|
|
266
|
+
* @param {number[]} values Values to set
|
|
267
|
+
* @returns {this}
|
|
268
|
+
*/
|
|
269
|
+
fromArray([r, g, b]) {
|
|
270
|
+
this.r = r;
|
|
271
|
+
this.g = g;
|
|
272
|
+
this.b = b;
|
|
273
|
+
return this;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Copy the RGB values of a given color to this color
|
|
277
|
+
*
|
|
278
|
+
* @param {Color|ColorRgb} color Color to copy values from
|
|
279
|
+
* @returns {this}
|
|
280
|
+
*/
|
|
281
|
+
copy([r, g, b]) {
|
|
282
|
+
this.r = r;
|
|
283
|
+
this.g = g;
|
|
284
|
+
this.b = b;
|
|
285
|
+
return this;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Create a new color with copied RGB values from this color
|
|
289
|
+
*
|
|
290
|
+
* @returns {Color}
|
|
291
|
+
*/
|
|
292
|
+
clone() {
|
|
293
|
+
return new Color(this.rgb);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* RGB values of this color
|
|
297
|
+
*/
|
|
298
|
+
set rgb(rgb) {
|
|
299
|
+
this.setRgb(rgb);
|
|
300
|
+
}
|
|
301
|
+
get rgb() {
|
|
302
|
+
return [this.r, this.g, this.b];
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Hexadecimal value of this color
|
|
306
|
+
*/
|
|
307
|
+
set hex(hex) {
|
|
308
|
+
this.setHex(hex);
|
|
309
|
+
}
|
|
310
|
+
get hex() {
|
|
311
|
+
return rgbToHex(this.rgb);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Hexadecimal string representing this color
|
|
315
|
+
*/
|
|
316
|
+
get hexString() {
|
|
317
|
+
return rgbToHexString(this.rgb);
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* HSL values of this color
|
|
321
|
+
*/
|
|
322
|
+
set hsl(hsl) {
|
|
323
|
+
this.setHsl(hsl);
|
|
324
|
+
}
|
|
325
|
+
get hsl() {
|
|
326
|
+
return rgbToHsl(this.rgb);
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* HSL string representing this color (format: 'hsl(360, 100%, 100%)')
|
|
330
|
+
*/
|
|
331
|
+
get hslString() {
|
|
332
|
+
const [h, s, l] = this.hsl;
|
|
333
|
+
return `hsl(${h}, ${s * 100}%, ${l * 100}%)`;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* HSB values of this color
|
|
337
|
+
*/
|
|
338
|
+
set hsb(hsb) {
|
|
339
|
+
this.setHsb(hsb);
|
|
340
|
+
}
|
|
341
|
+
get hsb() {
|
|
342
|
+
return rgbToHsb(this.rgb);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* L*a*b* values of this color
|
|
346
|
+
*/
|
|
347
|
+
set lab(lab) {
|
|
348
|
+
this.setLab(lab);
|
|
349
|
+
}
|
|
350
|
+
get lab() {
|
|
351
|
+
return rgbToLab(this.rgb);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* HCL values of this color
|
|
355
|
+
*/
|
|
356
|
+
set hcl(hcl) {
|
|
357
|
+
this.setHcl(hcl);
|
|
358
|
+
}
|
|
359
|
+
get hcl() {
|
|
360
|
+
return rgbToHcl(this.rgb);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Linearly interpolate a color between two colors in the RGB color space
|
|
364
|
+
*
|
|
365
|
+
* @param {number} t Normalized time value to interpolate
|
|
366
|
+
* @param {Color|ColorRgb} rgb1 Start color
|
|
367
|
+
* @param {Color|ColorRgb} rgb2 End color
|
|
368
|
+
* @param {object} [params] Interpolation parameters
|
|
369
|
+
* @param {number} [params.power=1] Interpolation exponent
|
|
370
|
+
* @returns {ColorRgb} Interpolated RGB color
|
|
371
|
+
*/
|
|
372
|
+
static lerpRgb(t, [r1, g1, b1], [r2, g2, b2], { power = 1 } = {}) {
|
|
373
|
+
const tp = Math.pow(t, power);
|
|
374
|
+
const r = lerp(tp, r1, r2);
|
|
375
|
+
const g = lerp(tp, g1, g2);
|
|
376
|
+
const b = lerp(tp, b1, b2);
|
|
377
|
+
return [r, g, b];
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Linearly interpolate a color between two colors in the HSL color space
|
|
381
|
+
*
|
|
382
|
+
* @param {number} t Normalized time value to interpolate
|
|
383
|
+
* @param {ColorHsl} hsl1 Start color
|
|
384
|
+
* @param {ColorHsl} hsl2 End color
|
|
385
|
+
* @param {object} [params] Interpolation parameters
|
|
386
|
+
* @param {number|number[]} [params.power=1] Interpolation exponent(s) : [h, s, l]
|
|
387
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
388
|
+
* @returns {ColorHsl} Interpolated HSL color
|
|
389
|
+
*/
|
|
390
|
+
static lerpHsl(t, [h1, s1, l1], [h2, s2, l2], { power = 1, hueMode } = {}) {
|
|
391
|
+
const ph = Array.isArray(power) ? power[0] : power;
|
|
392
|
+
const ps = Array.isArray(power) ? power[1] : power;
|
|
393
|
+
const pl = Array.isArray(power) ? power[2] : power;
|
|
394
|
+
const th = Math.pow(t, ph);
|
|
395
|
+
const ts = Math.pow(t, ps);
|
|
396
|
+
const tl = Math.pow(t, pl);
|
|
397
|
+
const h = Color.lerpHue(th, h1, h2, hueMode);
|
|
398
|
+
const s = lerp(ts, s1, s2);
|
|
399
|
+
const l = lerp(tl, l1, l2);
|
|
400
|
+
return [h, s, l];
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Linearly interpolate a color between two colors in the HSB color space
|
|
404
|
+
*
|
|
405
|
+
* @param {number} t Normalized time value to interpolate
|
|
406
|
+
* @param {ColorHsb} hsb1 Start color
|
|
407
|
+
* @param {ColorHsb} hsb2 End color
|
|
408
|
+
* @param {object} [params] Interpolation parameters
|
|
409
|
+
* @param {number|number[]} [params.power=1] Interpolation exponent(s) : [h, s, b]
|
|
410
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
411
|
+
* @returns {ColorHsb} Interpolated HSB color
|
|
412
|
+
*/
|
|
413
|
+
static lerpHsb(t, [h1, s1, b1], [h2, s2, b2], { power = 1, hueMode } = {}) {
|
|
414
|
+
const ph = Array.isArray(power) ? power[0] : power;
|
|
415
|
+
const ps = Array.isArray(power) ? power[1] : power;
|
|
416
|
+
const pb = Array.isArray(power) ? power[2] : power;
|
|
417
|
+
const th = Math.pow(t, ph);
|
|
418
|
+
const ts = Math.pow(t, ps);
|
|
419
|
+
const tb = Math.pow(t, pb);
|
|
420
|
+
const h = Color.lerpHue(th, h1, h2, hueMode);
|
|
421
|
+
const s = lerp(ts, s1, s2);
|
|
422
|
+
const b = lerp(tb, b1, b2);
|
|
423
|
+
return [h, s, b];
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Interpolate a color between 2 colors following HCL Qualitative color palettes algorithm
|
|
427
|
+
* -> https://colorspace.r-forge.r-project.org/articles/hcl_palettes.html#qualitative-palettes
|
|
428
|
+
*
|
|
429
|
+
* Qualitative color palettes:
|
|
430
|
+
* - Hue: Linear
|
|
431
|
+
* - Chroma: Constant
|
|
432
|
+
* - Luminance: Constant
|
|
433
|
+
*
|
|
434
|
+
* Designed for coding categorical information,
|
|
435
|
+
* where no particular ordering of categories is available
|
|
436
|
+
* and every color should receive the same perceptual weight.
|
|
437
|
+
*
|
|
438
|
+
* @param {number} t Normalized time value to interpolate
|
|
439
|
+
* @param {ColorHcl} hcl1 Start color
|
|
440
|
+
* @param {ColorHcl} hcl2 End color
|
|
441
|
+
* @param {object} [params] Interpolation parameters
|
|
442
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
443
|
+
* @returns {ColorHcl} Interpolated HCL color
|
|
444
|
+
*/
|
|
445
|
+
static interpolateQualitative(t, [h1, c1, l1], [h2], { hueMode } = {}) {
|
|
446
|
+
const h = Color.lerpHue(t, h1, h2, hueMode);
|
|
447
|
+
const c = c1;
|
|
448
|
+
const l = l1;
|
|
449
|
+
return [h, c, l];
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Interpolate a color between 2 colors following HCL Sequential color palettes algorithm
|
|
453
|
+
* -> https://colorspace.r-forge.r-project.org/articles/hcl_palettes.html#sequential-palettes-single-hue
|
|
454
|
+
* -> https://colorspace.r-forge.r-project.org/articles/hcl_palettes.html#sequential-palettes-multi-hue
|
|
455
|
+
*
|
|
456
|
+
* Sequential color palettes:
|
|
457
|
+
* - Hue: Constant | Linear
|
|
458
|
+
* - Chroma: Linear (+power) | Triangular (+power)
|
|
459
|
+
* - Luminance: Linear (+power)
|
|
460
|
+
*
|
|
461
|
+
* Designed for coding ordered/numeric information,
|
|
462
|
+
* going from high to low (or vice versa).
|
|
463
|
+
*
|
|
464
|
+
* @param {number} t Normalized time value to interpolate
|
|
465
|
+
* @param {ColorHcl} hcl1 Start color
|
|
466
|
+
* @param {ColorHcl} hcl2 End color
|
|
467
|
+
* @param {object} [params] Interpolation parameters
|
|
468
|
+
* @param {number|number[]} [params.power=1] Interpolation exponent(s) : [c, l]
|
|
469
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
470
|
+
* @param {number} [params.chromaMax] Maximum chroma value
|
|
471
|
+
* @returns {ColorHcl} Interpolated HCL color
|
|
472
|
+
*/
|
|
473
|
+
static interpolateSequential(t, [h1, c1, l1], [h2, c2, l2], { power = 1, hueMode, chromaMax } = {}) {
|
|
474
|
+
const pc = Array.isArray(power) ? power[0] : power;
|
|
475
|
+
const pl = Array.isArray(power) ? power[1] : power;
|
|
476
|
+
const tc = Math.pow(t, pc);
|
|
477
|
+
const tl = Math.pow(t, pl);
|
|
478
|
+
const h = Color.lerpHue(t, h1, h2, hueMode);
|
|
479
|
+
const c = tlerp(tc, c1, c2, chromaMax);
|
|
480
|
+
const l = lerp(tl, l1, l2);
|
|
481
|
+
return [h, c, l];
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Interpolate a color between 2 colors following HCL Diverging color palettes algorithm
|
|
485
|
+
* -> https://colorspace.r-forge.r-project.org/articles/hcl_palettes.html#diverging-palettes
|
|
486
|
+
*
|
|
487
|
+
* Diverging color palettes:
|
|
488
|
+
* - Hue: Constants (x2)
|
|
489
|
+
* - Chroma: Linear (+power) | Triangular (+power)
|
|
490
|
+
* - Luminance: Linear (+power)
|
|
491
|
+
*
|
|
492
|
+
* Designed for coding ordered/numeric information around a central neutral value,
|
|
493
|
+
* where colors diverge from neutral to two extremes.
|
|
494
|
+
*
|
|
495
|
+
* @param {number} t Normalized time value to interpolate
|
|
496
|
+
* @param {ColorHcl} hcl1 Start color
|
|
497
|
+
* @param {ColorHcl} hcl2 End color
|
|
498
|
+
* @param {object} [params] Interpolation parameters
|
|
499
|
+
* @param {number|number[]} [params.power=1] Interpolation exponent(s) : ([c, l])
|
|
500
|
+
* @returns {ColorHcl} Interpolated HCL color
|
|
501
|
+
*/
|
|
502
|
+
static interpolateDiverging(t, [h1, c1, l1], [h2, c2, l2], { power = 1 } = {}) {
|
|
503
|
+
const pc = Array.isArray(power) ? power[0] : power;
|
|
504
|
+
const pl = Array.isArray(power) ? power[1] : power;
|
|
505
|
+
const tc = Math.pow(t, pc);
|
|
506
|
+
const tl = Math.pow(t, pl);
|
|
507
|
+
const h = tc < 0.5 ? h1 : tc > 0.5 ? h2 : 0;
|
|
508
|
+
const c = tc === 0.5 ? 0 : tlerp(tc, c1, c2, 0);
|
|
509
|
+
const l = lerp(tl, l1, l2);
|
|
510
|
+
return [h, c, l];
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Interpolate a hue between two hue angles
|
|
514
|
+
*
|
|
515
|
+
* @param {number} t Normalized time value to interpolate
|
|
516
|
+
* @param {number} h1 Start hue angle (in degrees)
|
|
517
|
+
* @param {number} h2 End hue angle (in degrees)
|
|
518
|
+
* @param {string} [mode='direct'] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
519
|
+
* @returns {number} Interpolated hue
|
|
520
|
+
*/
|
|
521
|
+
static lerpHue(t, h1, h2, mode = 'direct') {
|
|
522
|
+
if (mode === 'direct')
|
|
523
|
+
return lerp(t, h1, h2);
|
|
524
|
+
let delta = ((h2 - h1 + 540) % 360) - 180;
|
|
525
|
+
if (mode === 'longest')
|
|
526
|
+
delta = delta > 0 ? delta - 360 : delta + 360;
|
|
527
|
+
return (h1 + t * delta + 360) % 360;
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Check if two colors are equal to each other
|
|
531
|
+
*
|
|
532
|
+
* @param {Color|ColorRgb} color1 First color
|
|
533
|
+
* @param {Color|ColorRgb} color2 Second color
|
|
534
|
+
* @returns {boolean} True if the given colors are equal, false otherwise
|
|
535
|
+
*/
|
|
536
|
+
static equals([r1, g1, b1], [r2, g2, b2]) {
|
|
537
|
+
return r1 === r2 && g1 === g2 && b1 === b2;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
/** Utils */
|
|
541
|
+
function tlerp(t, min, max, peak) {
|
|
542
|
+
// prettier-ignore
|
|
543
|
+
return typeof peak === 'number' ?
|
|
544
|
+
triLerp(t, min, max, peak) :
|
|
545
|
+
lerp(t, min, max);
|
|
546
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { ColorRepresentation } from '../../types';
|
|
2
|
+
import Color, { type ColorInterpolationsParameters, type ColorInterpolation } from './Color';
|
|
3
|
+
import ColorScale, { type ColorScaleProcessingParameters } from './ColorScale';
|
|
4
|
+
/**
|
|
5
|
+
* Parameters used for color palette generation
|
|
6
|
+
*/
|
|
7
|
+
export type ColorPaletteGenerationParameters = {
|
|
8
|
+
/**
|
|
9
|
+
* Pre-processing parameters, for processing the color palette base color before generation
|
|
10
|
+
*/
|
|
11
|
+
preprocessing?: ColorScaleProcessingParameters;
|
|
12
|
+
/**
|
|
13
|
+
* Post-processing parameters, for processing the generated color scale after generation
|
|
14
|
+
*/
|
|
15
|
+
postprocessing?: ColorScaleProcessingParameters;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Interface representing a color palette generator
|
|
19
|
+
*/
|
|
20
|
+
export type ColorPaletteGenerator<I extends ColorInterpolation = ColorInterpolation> = {
|
|
21
|
+
/**
|
|
22
|
+
* Type of interpolation used for generation
|
|
23
|
+
*/
|
|
24
|
+
interpolation: I;
|
|
25
|
+
/**
|
|
26
|
+
* Amount of colors to generate
|
|
27
|
+
*/
|
|
28
|
+
length: number;
|
|
29
|
+
/**
|
|
30
|
+
* Target color to interpolate towards
|
|
31
|
+
*/
|
|
32
|
+
target?: Color | null;
|
|
33
|
+
/**
|
|
34
|
+
* Target color processing parameters, for processing the target color before generation
|
|
35
|
+
*/
|
|
36
|
+
processing?: ColorScaleProcessingParameters;
|
|
37
|
+
/**
|
|
38
|
+
* Generation parameters & Interpolation parameters
|
|
39
|
+
*/
|
|
40
|
+
params?: ColorPaletteGenerationParameters & ColorInterpolationsParameters[I];
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Utility class for generating color palettes
|
|
44
|
+
*
|
|
45
|
+
* @exports
|
|
46
|
+
* @class ColorPalette
|
|
47
|
+
*/
|
|
48
|
+
export default class ColorPalette {
|
|
49
|
+
readonly isColorPalette = true;
|
|
50
|
+
readonly type: string;
|
|
51
|
+
protected _base: Color;
|
|
52
|
+
/**
|
|
53
|
+
* Object containing this color palette color scales
|
|
54
|
+
*/
|
|
55
|
+
scales: Record<string, ColorScale>;
|
|
56
|
+
/**
|
|
57
|
+
* Object containing this color palette generators
|
|
58
|
+
*/
|
|
59
|
+
generators: Record<string, ColorPaletteGenerator>;
|
|
60
|
+
/**
|
|
61
|
+
* @param {Color|ColorRepresentation} color Base color
|
|
62
|
+
* @param {object} generators Object containing generators
|
|
63
|
+
*/
|
|
64
|
+
constructor(color: Color | ColorRepresentation, generators?: Record<string, ColorPaletteGenerator>);
|
|
65
|
+
/**
|
|
66
|
+
* Pick an interpolated color from one of this color palette color scale
|
|
67
|
+
*
|
|
68
|
+
* @param {string} key Name of the color scale
|
|
69
|
+
* @param {number} t Normalized time value to interpolate
|
|
70
|
+
* @returns {Color} Interpolated color
|
|
71
|
+
*/
|
|
72
|
+
getColor(key: string, t: number): Color;
|
|
73
|
+
/**
|
|
74
|
+
* Add a given generator to this color palette
|
|
75
|
+
*
|
|
76
|
+
* @param {string} key Name of the generator
|
|
77
|
+
* @param {ColorPaletteGenerator} generator Generator to add
|
|
78
|
+
*/
|
|
79
|
+
subscribe<I extends ColorInterpolation>(key: string, generator: ColorPaletteGenerator<I>): void;
|
|
80
|
+
/**
|
|
81
|
+
* Generate a color scale
|
|
82
|
+
*
|
|
83
|
+
* @param {ColorPaletteGenerator} generator Generator interface to use for generation
|
|
84
|
+
* @param {ColorInterpolation} generator.interpolation Type of interpolation used for generation
|
|
85
|
+
* @param {number} generator.length Amount of colors to generate
|
|
86
|
+
* @param {Color} [generator.target] Target color to interpolate towards
|
|
87
|
+
* @param {ColorScaleProcessingParameters} [generator.processing] Target color processing parameters, for processing the target color before generation
|
|
88
|
+
* @param {object} [generator.params] Interpolation parameters
|
|
89
|
+
* @returns {ColorScale} Generated color scale
|
|
90
|
+
*/
|
|
91
|
+
generate(generator: ColorPaletteGenerator): ColorScale;
|
|
92
|
+
/**
|
|
93
|
+
* Update this color palette color scales
|
|
94
|
+
*/
|
|
95
|
+
update(): void;
|
|
96
|
+
/**
|
|
97
|
+
* Base color of this color palette
|
|
98
|
+
*/
|
|
99
|
+
set base(color: Color | ColorRepresentation);
|
|
100
|
+
get base(): Color;
|
|
101
|
+
}
|
|
102
|
+
export declare const LightScaleGenerator: ColorPaletteGenerator;
|
|
103
|
+
export declare const DarkScaleGenerator: ColorPaletteGenerator;
|
|
104
|
+
export declare const SequentialLightGenerator: ColorPaletteGenerator;
|
|
105
|
+
export declare const SequentialDarkGenerator: ColorPaletteGenerator;
|