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,347 @@
|
|
|
1
|
+
import { clamp, lerp } from '../../maths';
|
|
2
|
+
import Color from './Color';
|
|
3
|
+
/**
|
|
4
|
+
* Utility class for generating and processing color scales
|
|
5
|
+
*
|
|
6
|
+
* @exports
|
|
7
|
+
* @class ColorScale
|
|
8
|
+
*/
|
|
9
|
+
export default class ColorScale {
|
|
10
|
+
isColorScale = true;
|
|
11
|
+
type = 'ColorScale';
|
|
12
|
+
/**
|
|
13
|
+
* Array of colors composing this color scale
|
|
14
|
+
*/
|
|
15
|
+
colors = [];
|
|
16
|
+
*[Symbol.iterator]() {
|
|
17
|
+
yield* this.colors;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Pick an interpolated color from this color scale
|
|
21
|
+
*
|
|
22
|
+
* @param {number} t Normalized time value to interpolate
|
|
23
|
+
* @returns {Color} Interpolated color on this scale
|
|
24
|
+
*/
|
|
25
|
+
getColor(t) {
|
|
26
|
+
const index = lerp(t, 0, this.length - 1);
|
|
27
|
+
return this.colors[index];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Set this color scale colors to an array of interpolated colors
|
|
31
|
+
*
|
|
32
|
+
* @param {ColorInterpolation} interpolation Type of interpolation used for generation
|
|
33
|
+
* @param {number} length Amount of colors to generate
|
|
34
|
+
* @param {Color} color1 Start color
|
|
35
|
+
* @param {Color} color2 End color
|
|
36
|
+
* @param {object} [params] Interpolation parameters
|
|
37
|
+
* @returns {this}
|
|
38
|
+
*/
|
|
39
|
+
generate(interpolation, length, color1, color2, params) {
|
|
40
|
+
this.colors = ColorScale.generate(interpolation, length, color1, color2, params);
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Set this color scale colors to an array of interpolated colors in the RGB color space
|
|
45
|
+
*
|
|
46
|
+
* @param {number} length Amount of colors to generate
|
|
47
|
+
* @param {Color} color1 Start color
|
|
48
|
+
* @param {Color} color2 End color
|
|
49
|
+
* @param {object} [params] Interpolation parameters
|
|
50
|
+
* @param {number} [params.power] Interpolation exponent
|
|
51
|
+
* @returns {this}
|
|
52
|
+
*/
|
|
53
|
+
generateRgb(length, color1, color2, params) {
|
|
54
|
+
this.colors = ColorScale.generateRgb(length, color1, color2, params);
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Set this color scale colors to an array of interpolated colors in the HSL color space
|
|
59
|
+
*
|
|
60
|
+
* @param {number} length Amount of colors to generate
|
|
61
|
+
* @param {Color} color1 Start color
|
|
62
|
+
* @param {Color} color2 End color
|
|
63
|
+
* @param {object} [params] Interpolation parameters
|
|
64
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : [h, s, l]
|
|
65
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
66
|
+
* @returns {this}
|
|
67
|
+
*/
|
|
68
|
+
generateHsl(length, color1, color2, params) {
|
|
69
|
+
this.colors = ColorScale.generateHsl(length, color1, color2, params);
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Set this color scale colors to an array of interpolated colors in the HSB color space
|
|
74
|
+
*
|
|
75
|
+
* @param {number} length Amount of colors to generate
|
|
76
|
+
* @param {Color} color1 Start color
|
|
77
|
+
* @param {Color} color2 End color
|
|
78
|
+
* @param {object} [params] Interpolation parameters
|
|
79
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : [h, s, b]
|
|
80
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
81
|
+
* @returns {this}
|
|
82
|
+
*/
|
|
83
|
+
generateHsb(length, color1, color2, params) {
|
|
84
|
+
this.colors = ColorScale.generateHsb(length, color1, color2, params);
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Set this color scale colors to an array of interpolated colors following HCL Qualitative color palettes algorithm
|
|
89
|
+
*
|
|
90
|
+
* @param {number} length Amount of colors to generate
|
|
91
|
+
* @param {Color} color1 Start color
|
|
92
|
+
* @param {Color} color2 End color
|
|
93
|
+
* @param {object} [params] Interpolation parameters
|
|
94
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
95
|
+
* @returns {this}
|
|
96
|
+
*/
|
|
97
|
+
generateQualitative(length, color1, color2, params) {
|
|
98
|
+
this.colors = ColorScale.generateQualitative(length, color1, color2, params);
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Set this color scale colors to an array of interpolated colors following HCL Sequential color palettes algorithm
|
|
103
|
+
*
|
|
104
|
+
* @param {number} length Amount of colors to generate
|
|
105
|
+
* @param {Color} color1 Start color
|
|
106
|
+
* @param {Color} color2 End color
|
|
107
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : [c, l]
|
|
108
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
109
|
+
* @param {number} [params.chromaMax] Maximum chroma value
|
|
110
|
+
* @returns {this}
|
|
111
|
+
*/
|
|
112
|
+
generateSequential(length, color1, color2, params) {
|
|
113
|
+
this.colors = ColorScale.generateSequential(length, color1, color2, params);
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Set this color scale colors to an array of interpolated colors following HCL Diverging color palettes algorithm
|
|
118
|
+
*
|
|
119
|
+
* @param {number} length Amount of colors to generate
|
|
120
|
+
* @param {Color} color1 Start color
|
|
121
|
+
* @param {Color} color2 End color
|
|
122
|
+
* @param {object} [params] Interpolation parameters
|
|
123
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : ([c, l])
|
|
124
|
+
* @returns {this}
|
|
125
|
+
*/
|
|
126
|
+
generateDiverging(length, color1, color2, params) {
|
|
127
|
+
this.colors = ColorScale.generateDiverging(length, color1, color2, params);
|
|
128
|
+
return this;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Process all colors composing this scale
|
|
132
|
+
*
|
|
133
|
+
* @param {ColorScaleProcessingParameters} [params] Processing parameters
|
|
134
|
+
* @returns {this}
|
|
135
|
+
*/
|
|
136
|
+
process(params) {
|
|
137
|
+
ColorScale.process(this, params);
|
|
138
|
+
return this;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Amount of colors composing this color scale
|
|
142
|
+
*/
|
|
143
|
+
get length() {
|
|
144
|
+
return this.colors.length;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Generate an array of interpolated colors
|
|
148
|
+
*
|
|
149
|
+
* @param {ColorInterpolation} interpolation Type of interpolation used for generation
|
|
150
|
+
* @param {number} length Amount of colors to generate
|
|
151
|
+
* @param {Color} color1 Start color
|
|
152
|
+
* @param {Color} color2 End color
|
|
153
|
+
* @param {object} [params] Interpolation parameters
|
|
154
|
+
* @returns {Color[]} Generated color scale
|
|
155
|
+
*/
|
|
156
|
+
static generate(interpolation, length, color1, color2, params) {
|
|
157
|
+
const interpolate = ColorScale._getInterpolateFunction(interpolation, color1, color2, params);
|
|
158
|
+
const colors = [];
|
|
159
|
+
for (let i = 0; i < length; i++) {
|
|
160
|
+
const t = i / (length - 1);
|
|
161
|
+
const color = interpolate(t);
|
|
162
|
+
colors.push(color);
|
|
163
|
+
}
|
|
164
|
+
return colors;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Generate an array of interpolated colors in the RGB color space
|
|
168
|
+
*
|
|
169
|
+
* @param {number} length Amount of colors to generate
|
|
170
|
+
* @param {Color} color1 Start color
|
|
171
|
+
* @param {Color} color2 End color
|
|
172
|
+
* @param {object} [params] Interpolation parameters
|
|
173
|
+
* @param {number} [params.power] Interpolation exponent
|
|
174
|
+
* @returns {Color[]} Generated RGB color scale
|
|
175
|
+
*/
|
|
176
|
+
static generateRgb(length, color1, color2, params) {
|
|
177
|
+
return ColorScale.generate('rgb', length, color1, color2, params);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Generate an array of interpolated colors in the HSL color space
|
|
181
|
+
*
|
|
182
|
+
* @param {number} length Amount of colors to generate
|
|
183
|
+
* @param {Color} color1 Start color
|
|
184
|
+
* @param {Color} color2 End color
|
|
185
|
+
* @param {object} [params] Interpolation parameters
|
|
186
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : [h, s, l]
|
|
187
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
188
|
+
* @returns {Color[]} Generated HSL color scale
|
|
189
|
+
*/
|
|
190
|
+
static generateHsl(length, color1, color2, params) {
|
|
191
|
+
return ColorScale.generate('hsl', length, color1, color2, params);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Generate an array of interpolated colors in the HSB color space
|
|
195
|
+
*
|
|
196
|
+
* @param {number} length Amount of colors to generate
|
|
197
|
+
* @param {Color} color1 Start color
|
|
198
|
+
* @param {Color} color2 End color
|
|
199
|
+
* @param {object} [params] Interpolation parameters
|
|
200
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : [h, s, b]
|
|
201
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
202
|
+
* @returns {Color[]} Generated HSB color scale
|
|
203
|
+
*/
|
|
204
|
+
static generateHsb(length, color1, color2, params) {
|
|
205
|
+
return ColorScale.generate('hsb', length, color1, color2, params);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Generate an array of interpolated colors following HCL Qualitative color palettes algorithm
|
|
209
|
+
*
|
|
210
|
+
* @param {number} length Amount of colors to generate
|
|
211
|
+
* @param {Color} color1 Start color
|
|
212
|
+
* @param {Color} color2 End color
|
|
213
|
+
* @param {object} [params] Interpolation parameters
|
|
214
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
215
|
+
* @returns {Color[]} Generated qualitative color scale
|
|
216
|
+
*/
|
|
217
|
+
static generateQualitative(length, color1, color2, params) {
|
|
218
|
+
return ColorScale.generate('qualitative', length, color1, color2, params);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Generate an array of interpolated colors following HCL Sequential color palettes algorithm
|
|
222
|
+
*
|
|
223
|
+
* @param {number} length Amount of colors to generate
|
|
224
|
+
* @param {Color} color1 Start color
|
|
225
|
+
* @param {Color} color2 End color
|
|
226
|
+
* @param {object} [params] Interpolation parameters
|
|
227
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : [c, l]
|
|
228
|
+
* @param {string} [params.hueMode] Hue interpolation mode. Can be 'direct' | 'shortest' | 'longest'
|
|
229
|
+
* @param {number} [params.chromaMax] Maximum chroma value
|
|
230
|
+
* @returns {Color[]} Generated sequential color scale
|
|
231
|
+
*/
|
|
232
|
+
static generateSequential(length, color1, color2, params) {
|
|
233
|
+
return ColorScale.generate('sequential', length, color1, color2, params);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Generate an array of interpolated colors following HCL Diverging color palettes algorithm
|
|
237
|
+
*
|
|
238
|
+
* @param {number} length Amount of colors to generate
|
|
239
|
+
* @param {Color} color1 Start color
|
|
240
|
+
* @param {Color} color2 End color
|
|
241
|
+
* @param {object} [params] Interpolation parameters
|
|
242
|
+
* @param {number|number[]} [params.power] Interpolation exponent(s) : ([c, l])
|
|
243
|
+
* @returns {Color[]} Generated diverging color scale
|
|
244
|
+
*/
|
|
245
|
+
static generateDiverging(length, color1, color2, params) {
|
|
246
|
+
return ColorScale.generate('diverging', length, color1, color2, params);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Process a given value
|
|
250
|
+
*
|
|
251
|
+
* @param {number} value Value to process
|
|
252
|
+
* @param {ColorScaleProcessingTarget} [target] Processing target
|
|
253
|
+
* @returns {number} Processed value
|
|
254
|
+
*/
|
|
255
|
+
static processValue(value, target) {
|
|
256
|
+
if (typeof target === 'undefined')
|
|
257
|
+
return value;
|
|
258
|
+
if (typeof target === 'number')
|
|
259
|
+
return target;
|
|
260
|
+
if (Array.isArray(target))
|
|
261
|
+
return clamp(value, target[0], target[1]);
|
|
262
|
+
return value;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Process a given color
|
|
266
|
+
*
|
|
267
|
+
* @param {Color} color Color to process
|
|
268
|
+
* @param {ColorScaleProcessingParameters} [params] Processing parameters
|
|
269
|
+
* @returns {Color} Processed color
|
|
270
|
+
*/
|
|
271
|
+
static processColor(color, params = {}) {
|
|
272
|
+
if (params.hsl) {
|
|
273
|
+
let [h, s, l] = color.hsl;
|
|
274
|
+
h = this.processValue(h, params.hsl.hue);
|
|
275
|
+
s = this.processValue(s, params.hsl.saturation);
|
|
276
|
+
l = this.processValue(l, params.hsl.lightness);
|
|
277
|
+
color.setHsl([h, s, l]);
|
|
278
|
+
}
|
|
279
|
+
if (params.hsb) {
|
|
280
|
+
let [h, s, b] = color.hsb;
|
|
281
|
+
h = this.processValue(h, params.hsb.hue);
|
|
282
|
+
s = this.processValue(s, params.hsb.saturation);
|
|
283
|
+
b = this.processValue(b, params.hsb.brightness);
|
|
284
|
+
color.setHsb([h, s, b]);
|
|
285
|
+
}
|
|
286
|
+
if (params.hcl) {
|
|
287
|
+
let [h, c, l] = color.hcl;
|
|
288
|
+
h = this.processValue(h, params.hcl.hue);
|
|
289
|
+
c = this.processValue(c, params.hcl.chroma);
|
|
290
|
+
l = this.processValue(l, params.hcl.luminance);
|
|
291
|
+
color.setHcl([h, c, l]);
|
|
292
|
+
}
|
|
293
|
+
return color;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Process all colors composing a given scale
|
|
297
|
+
*
|
|
298
|
+
* @param {ColorScale} scale Color scale to process
|
|
299
|
+
* @param {ColorScaleProcessingParameters} [params] Processing parameters
|
|
300
|
+
* @returns {ColorScale} Processed color scale
|
|
301
|
+
*/
|
|
302
|
+
static process(scale, params = {}) {
|
|
303
|
+
scale.colors.forEach((color) => this.processColor(color, params));
|
|
304
|
+
return scale;
|
|
305
|
+
}
|
|
306
|
+
static _getInterpolateFunction(interpolation, color1, color2, params) {
|
|
307
|
+
switch (interpolation) {
|
|
308
|
+
case 'rgb':
|
|
309
|
+
default:
|
|
310
|
+
return (t) => {
|
|
311
|
+
const rgb = Color.lerpRgb(t, color1.rgb, color2.rgb, params);
|
|
312
|
+
const color = new Color().setRgb(rgb);
|
|
313
|
+
return color;
|
|
314
|
+
};
|
|
315
|
+
case 'hsl':
|
|
316
|
+
return (t) => {
|
|
317
|
+
const hsl = Color.lerpHsl(t, color1.hsl, color2.hsl, params);
|
|
318
|
+
const color = new Color().setHsl(hsl);
|
|
319
|
+
return color;
|
|
320
|
+
};
|
|
321
|
+
case 'hsb':
|
|
322
|
+
return (t) => {
|
|
323
|
+
const hsb = Color.lerpHsb(t, color1.hsb, color2.hsb, params);
|
|
324
|
+
const color = new Color().setHsb(hsb);
|
|
325
|
+
return color;
|
|
326
|
+
};
|
|
327
|
+
case 'qualitative':
|
|
328
|
+
return (t) => {
|
|
329
|
+
const hcl = Color.interpolateQualitative(t, color1.hcl, color2.hcl, params);
|
|
330
|
+
const color = new Color().setHcl(hcl);
|
|
331
|
+
return color;
|
|
332
|
+
};
|
|
333
|
+
case 'sequential':
|
|
334
|
+
return (t) => {
|
|
335
|
+
const hcl = Color.interpolateSequential(t, color1.hcl, color2.hcl, params);
|
|
336
|
+
const color = new Color().setHcl(hcl);
|
|
337
|
+
return color;
|
|
338
|
+
};
|
|
339
|
+
case 'diverging':
|
|
340
|
+
return (t) => {
|
|
341
|
+
const hcl = Color.interpolateDiverging(t, color1.hcl, color2.hcl, params);
|
|
342
|
+
const color = new Color().setHcl(hcl);
|
|
343
|
+
return color;
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ColorRepresentation } from '../../types';
|
|
2
|
+
export type ColorScaleSettings = {
|
|
3
|
+
colorSpace: 'rgb';
|
|
4
|
+
} | {
|
|
5
|
+
colorSpace: 'hsl';
|
|
6
|
+
hueOffset?: number;
|
|
7
|
+
saturationOffset?: number;
|
|
8
|
+
lightnessOffset?: number;
|
|
9
|
+
} | {
|
|
10
|
+
colorSpace: 'hsb';
|
|
11
|
+
hueOffset?: number;
|
|
12
|
+
saturationOffset?: number;
|
|
13
|
+
brightnessOffset?: number;
|
|
14
|
+
} | {
|
|
15
|
+
colorSpace: 'hcl';
|
|
16
|
+
mode?: 'qualitative' | 'sequential' | 'diverging';
|
|
17
|
+
triangular?: number;
|
|
18
|
+
powerStrength?: number;
|
|
19
|
+
hueOffset?: number;
|
|
20
|
+
chromaOffset?: number;
|
|
21
|
+
luminanceOffset?: number;
|
|
22
|
+
};
|
|
23
|
+
export declare const defaultSettings: Required<ColorScaleSettings>;
|
|
24
|
+
/**
|
|
25
|
+
* Utility class for generating color scales and interpolating between colors
|
|
26
|
+
*
|
|
27
|
+
* @exports
|
|
28
|
+
* @class ColorScale
|
|
29
|
+
*/
|
|
30
|
+
export default class ColorScale {
|
|
31
|
+
/**
|
|
32
|
+
* Array of colors composing the color scale
|
|
33
|
+
*/
|
|
34
|
+
colors: Array<[number, number, number]>;
|
|
35
|
+
/**
|
|
36
|
+
* @param {ColorRepresentation} input Input color representation
|
|
37
|
+
* @param {ColorRepresentation} target Target color representation
|
|
38
|
+
* @param {number} [length=5] Amount of colors composing the color scale
|
|
39
|
+
* @param {ColorScaleSettings} [settings] Color scale generation settings
|
|
40
|
+
*/
|
|
41
|
+
constructor(input: ColorRepresentation, target: ColorRepresentation, length?: number, settings?: ColorScaleSettings);
|
|
42
|
+
/**
|
|
43
|
+
* Generate a color scale
|
|
44
|
+
*
|
|
45
|
+
* @param {ColorRepresentation} input Input color representation
|
|
46
|
+
* @param {ColorRepresentation} target Target color representation
|
|
47
|
+
* @param {number} length Amount of colors composing the color scale
|
|
48
|
+
* @param {ColorScaleSettings} [settings] Color scale generation settings
|
|
49
|
+
* @returns {Array<[number, number, number]>} Color scale colors
|
|
50
|
+
*/
|
|
51
|
+
static generate(input: ColorRepresentation, target: ColorRepresentation, length: number, settings?: ColorScaleSettings): Array<[number, number, number]>;
|
|
52
|
+
/**
|
|
53
|
+
* Interpolate between colors
|
|
54
|
+
*
|
|
55
|
+
* @param {[number,number,number]} inputColor Input color
|
|
56
|
+
* @param {[number,number,number]} targetColor Target color
|
|
57
|
+
* @param {number} value Interpolation normalized value
|
|
58
|
+
* @param {ColorScaleSettings} [settings] Color scale settings
|
|
59
|
+
* @returns {[number,number,number]} Interpolated color
|
|
60
|
+
*/
|
|
61
|
+
static interpolate(inputColor: [number, number, number], targetColor: [number, number, number], value: number, settings?: ColorScaleSettings): [number, number, number];
|
|
62
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { lerp, triLerp } from '../../maths';
|
|
2
|
+
import { hclToRgb, hsbToRgb, hslToRgb, normalizeColor, rgbToHcl, rgbToHsb, rgbToHsl } from '../../colors';
|
|
3
|
+
export const defaultSettings = {
|
|
4
|
+
colorSpace: 'rgb'
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Utility class for generating color scales and interpolating between colors
|
|
8
|
+
*
|
|
9
|
+
* @exports
|
|
10
|
+
* @class ColorScale
|
|
11
|
+
*/
|
|
12
|
+
export default class ColorScale {
|
|
13
|
+
/**
|
|
14
|
+
* Array of colors composing the color scale
|
|
15
|
+
*/
|
|
16
|
+
colors = [];
|
|
17
|
+
/**
|
|
18
|
+
* @param {ColorRepresentation} input Input color representation
|
|
19
|
+
* @param {ColorRepresentation} target Target color representation
|
|
20
|
+
* @param {number} [length=5] Amount of colors composing the color scale
|
|
21
|
+
* @param {ColorScaleSettings} [settings] Color scale generation settings
|
|
22
|
+
*/
|
|
23
|
+
constructor(input, target, length = 5, settings = { ...defaultSettings }) {
|
|
24
|
+
this.colors = ColorScale.generate(input, target, length, settings);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generate a color scale
|
|
28
|
+
*
|
|
29
|
+
* @param {ColorRepresentation} input Input color representation
|
|
30
|
+
* @param {ColorRepresentation} target Target color representation
|
|
31
|
+
* @param {number} length Amount of colors composing the color scale
|
|
32
|
+
* @param {ColorScaleSettings} [settings] Color scale generation settings
|
|
33
|
+
* @returns {Array<[number, number, number]>} Color scale colors
|
|
34
|
+
*/
|
|
35
|
+
static generate(input, target, length, settings = { ...defaultSettings }) {
|
|
36
|
+
const colors = [];
|
|
37
|
+
const inputColor = normalizeColor(input);
|
|
38
|
+
const targetColor = normalizeColor(target);
|
|
39
|
+
for (let i = 0; i < length; i++) {
|
|
40
|
+
const value = i / Math.floor(length);
|
|
41
|
+
colors.push(ColorScale.interpolate(inputColor, targetColor, value, settings));
|
|
42
|
+
}
|
|
43
|
+
return colors;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Interpolate between colors
|
|
47
|
+
*
|
|
48
|
+
* @param {[number,number,number]} inputColor Input color
|
|
49
|
+
* @param {[number,number,number]} targetColor Target color
|
|
50
|
+
* @param {number} value Interpolation normalized value
|
|
51
|
+
* @param {ColorScaleSettings} [settings] Color scale settings
|
|
52
|
+
* @returns {[number,number,number]} Interpolated color
|
|
53
|
+
*/
|
|
54
|
+
static interpolate(inputColor, targetColor, value, settings = { ...defaultSettings }) {
|
|
55
|
+
switch (settings.colorSpace) {
|
|
56
|
+
case 'rgb': {
|
|
57
|
+
const r = lerp(value, inputColor[0], targetColor[0]);
|
|
58
|
+
const g = lerp(value, inputColor[1], targetColor[1]);
|
|
59
|
+
const b = lerp(value, inputColor[2], targetColor[2]);
|
|
60
|
+
return [r, g, b];
|
|
61
|
+
}
|
|
62
|
+
case 'hsl': {
|
|
63
|
+
const inputHsl = rgbToHsl(inputColor);
|
|
64
|
+
const targetHsl = rgbToHsl(targetColor);
|
|
65
|
+
const h1 = inputHsl[0];
|
|
66
|
+
const s1 = inputHsl[1];
|
|
67
|
+
const l1 = inputHsl[2];
|
|
68
|
+
const h2 = targetHsl[0] + (settings.hueOffset ?? 0);
|
|
69
|
+
const s2 = targetHsl[1] + (settings.saturationOffset ?? 0);
|
|
70
|
+
const l2 = targetHsl[2] + (settings.lightnessOffset ?? 0);
|
|
71
|
+
const h = lerp(value, h1, h2);
|
|
72
|
+
const s = lerp(value, s1, s2);
|
|
73
|
+
const l = lerp(value, l1, l2);
|
|
74
|
+
return hslToRgb([h, s, l]);
|
|
75
|
+
}
|
|
76
|
+
case 'hsb': {
|
|
77
|
+
const inputHsb = rgbToHsb(inputColor);
|
|
78
|
+
const targetHsb = rgbToHsb(targetColor);
|
|
79
|
+
const h1 = inputHsb[0];
|
|
80
|
+
const s1 = inputHsb[1];
|
|
81
|
+
const b1 = inputHsb[2];
|
|
82
|
+
const h2 = targetHsb[0] + (settings.hueOffset ?? 0);
|
|
83
|
+
const s2 = targetHsb[1] + (settings.saturationOffset ?? 0);
|
|
84
|
+
const b2 = targetHsb[2] + (settings.brightnessOffset ?? 0);
|
|
85
|
+
const h = lerp(value, h1, h2);
|
|
86
|
+
const s = lerp(value, s1, s2);
|
|
87
|
+
const b = lerp(value, b1, b2);
|
|
88
|
+
return hsbToRgb([h, s, b]);
|
|
89
|
+
}
|
|
90
|
+
case 'hcl':
|
|
91
|
+
const inputHcl = rgbToHcl(inputColor);
|
|
92
|
+
const targetHcl = rgbToHcl(targetColor);
|
|
93
|
+
const powerValue = Math.pow(value, settings.powerStrength ?? 1);
|
|
94
|
+
const h1 = inputHcl[0];
|
|
95
|
+
const c1 = inputHcl[1];
|
|
96
|
+
const l1 = inputHcl[2];
|
|
97
|
+
const h2 = targetHcl[0] + (settings.hueOffset ?? 0);
|
|
98
|
+
const c2 = targetHcl[1] + (settings.chromaOffset ?? 0);
|
|
99
|
+
const l2 = targetHcl[2] + (settings.luminanceOffset ?? 0);
|
|
100
|
+
let h, c, l;
|
|
101
|
+
// HCL color palettes
|
|
102
|
+
// -> https://colorspace.r-forge.r-project.org/articles/hcl_palettes.html
|
|
103
|
+
switch (settings.mode) {
|
|
104
|
+
/**
|
|
105
|
+
* Qualitative
|
|
106
|
+
* Designed for coding categorical information,
|
|
107
|
+
* where no particular ordering of categories is available
|
|
108
|
+
* and every color should receive the same perceptual weight.
|
|
109
|
+
*
|
|
110
|
+
* - Hue: Linear
|
|
111
|
+
* - Chroma: Constant
|
|
112
|
+
* - Luminance: Constant
|
|
113
|
+
*/
|
|
114
|
+
case 'qualitative': {
|
|
115
|
+
h = lerp(value, h1, h2);
|
|
116
|
+
c = c1;
|
|
117
|
+
l = l1;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Sequential
|
|
121
|
+
* Designed for coding ordered/numeric information,
|
|
122
|
+
* going from high to low (or vice versa).
|
|
123
|
+
*
|
|
124
|
+
* - Hue: Constant | Linear
|
|
125
|
+
* - Chroma: Linear (+power) | Triangular (+power)
|
|
126
|
+
* - Luminance: Linear (+power)
|
|
127
|
+
*/
|
|
128
|
+
case 'sequential': {
|
|
129
|
+
h = lerp(value, h1, h2);
|
|
130
|
+
c = settings.triangular ? triLerp(powerValue, c1, c2, settings.triangular) : lerp(powerValue, c1, c2);
|
|
131
|
+
l = lerp(powerValue, l1, l2);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Diverging
|
|
135
|
+
* Designed for coding ordered/numeric information around a central neutral value,
|
|
136
|
+
* where colors diverge from neutral to two extremes.
|
|
137
|
+
*
|
|
138
|
+
* - Hue: Constants (x2)
|
|
139
|
+
* - Chroma: Linear (+power) | Triangular (+power)
|
|
140
|
+
* - Luminance: Linear (+power)
|
|
141
|
+
*/
|
|
142
|
+
case 'diverging': {
|
|
143
|
+
h = value < 0.5 ? h1 : value > 0.5 ? h2 : lerp(0.5, h1, h2);
|
|
144
|
+
c = settings.triangular ? triLerp(powerValue, c1, c2, settings.triangular) : lerp(powerValue, c1, c2);
|
|
145
|
+
l = lerp(powerValue, l1, l2);
|
|
146
|
+
}
|
|
147
|
+
default: {
|
|
148
|
+
h = lerp(value, h1, h2);
|
|
149
|
+
c = lerp(value, c1, c2);
|
|
150
|
+
l = lerp(value, l1, l2);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return hclToRgb([h, c, l]);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { default as Color, type ColorInterpolationsParameters, type ColorInterpolation, type HueInterpolationMode } from './Color';
|
|
2
|
+
export { default as ColorScale, type ColorScaleProcessingTarget, type ColorScaleProcessingParameters } from './ColorScale';
|
|
3
|
+
export { default as ColorPalette, type ColorPaletteGenerationParameters, type ColorPaletteGenerator, LightScaleGenerator, DarkScaleGenerator, SequentialLightGenerator, SequentialDarkGenerator } from './ColorPalette';
|
|
@@ -5,21 +5,24 @@
|
|
|
5
5
|
* @class FrameRate
|
|
6
6
|
*/
|
|
7
7
|
export default class FrameRate {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
protected _fps: number;
|
|
9
|
+
protected _interval: number;
|
|
10
|
+
protected _time: number;
|
|
11
|
+
protected _elapsedTime: number;
|
|
12
|
+
protected _lastUpdate: number;
|
|
13
13
|
/**
|
|
14
|
-
* @param {number} [fps=
|
|
14
|
+
* @param {number} [fps=60] Frame per second limit
|
|
15
15
|
*/
|
|
16
16
|
constructor(fps?: number);
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Check if elapsed time since last update is higher than current FPS
|
|
19
19
|
*
|
|
20
|
-
* @returns {boolean}
|
|
20
|
+
* @returns {boolean} True if elapsed time since last update is higher than current FPS, false otherwise
|
|
21
21
|
*/
|
|
22
22
|
update(): boolean;
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Frame per second limit
|
|
25
|
+
*/
|
|
24
26
|
set fps(fps: number);
|
|
27
|
+
get fps(): number;
|
|
25
28
|
}
|
|
@@ -12,15 +12,15 @@ export default class FrameRate {
|
|
|
12
12
|
_elapsedTime = 0;
|
|
13
13
|
_lastUpdate = 0;
|
|
14
14
|
/**
|
|
15
|
-
* @param {number} [fps=
|
|
15
|
+
* @param {number} [fps=60] Frame per second limit
|
|
16
16
|
*/
|
|
17
|
-
constructor(fps =
|
|
17
|
+
constructor(fps = 60) {
|
|
18
18
|
this.fps = fps;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* Check if elapsed time since last update is higher than current FPS
|
|
22
22
|
*
|
|
23
|
-
* @returns {boolean}
|
|
23
|
+
* @returns {boolean} True if elapsed time since last update is higher than current FPS, false otherwise
|
|
24
24
|
*/
|
|
25
25
|
update() {
|
|
26
26
|
this._time = now();
|
|
@@ -31,11 +31,14 @@ export default class FrameRate {
|
|
|
31
31
|
this._lastUpdate = this._time - (this._elapsedTime % this._interval);
|
|
32
32
|
return true;
|
|
33
33
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Frame per second limit
|
|
36
|
+
*/
|
|
37
37
|
set fps(fps) {
|
|
38
38
|
this._fps = fps;
|
|
39
39
|
this._interval = 1000 / fps;
|
|
40
40
|
}
|
|
41
|
+
get fps() {
|
|
42
|
+
return this._fps;
|
|
43
|
+
}
|
|
41
44
|
}
|