toosoon-utils 1.5.0 → 2.1.0
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/package.json +9 -6
- package/tsconfig.json +1 -3
- package/lib/classes/_pool.d.ts +0 -56
- package/lib/classes/_pool.js +0 -92
- package/lib/classes/color-scale.d.ts +0 -52
- package/lib/classes/color-scale.js +0 -160
- package/lib/classes/frame-rate.d.ts +0 -25
- package/lib/classes/frame-rate.js +0 -48
- package/lib/colors.d.ts +0 -155
- package/lib/colors.js +0 -367
- package/lib/constants.d.ts +0 -162
- package/lib/constants.js +0 -170
- package/lib/dom.d.ts +0 -25
- package/lib/dom.js +0 -47
- package/lib/files.d.ts +0 -14
- package/lib/files.js +0 -38
- package/lib/functions.d.ts +0 -22
- package/lib/functions.js +0 -53
- package/lib/geometry.d.ts +0 -89
- package/lib/geometry.js +0 -128
- package/lib/index.d.ts +0 -10
- package/lib/index.js +0 -39
- package/lib/maths.d.ts +0 -161
- package/lib/maths.js +0 -219
- package/lib/now.d.ts +0 -5
- package/lib/now.js +0 -28
- package/lib/prng.d.ts +0 -124
- package/lib/prng.js +0 -234
- package/lib/random.d.ts +0 -91
- package/lib/random.js +0 -162
- package/lib/strings.d.ts +0 -14
- package/lib/strings.js +0 -18
- package/lib/tsconfig.tsbuildinfo +0 -1
- package/lib/types.d.ts +0 -18
- package/lib/types.js +0 -1
- package/src/classes/_pool.ts +0 -92
- package/src/classes/color-scale.ts +0 -181
- package/src/classes/frame-rate.ts +0 -49
- package/src/colors.ts +0 -389
- package/src/constants.ts +0 -172
- package/src/dom.ts +0 -50
- package/src/files.ts +0 -42
- package/src/functions.ts +0 -56
- package/src/geometry.ts +0 -160
- package/src/maths.ts +0 -241
- package/src/prng.ts +0 -249
- package/src/random.ts +0 -162
- package/src/strings.ts +0 -19
- package/src/types.ts +0 -33
package/src/colors.ts
DELETED
|
@@ -1,389 +0,0 @@
|
|
|
1
|
-
import { W3CX11 } from './constants';
|
|
2
|
-
import { toDegrees, toRadians } from './geometry';
|
|
3
|
-
import { clamp } from './maths';
|
|
4
|
-
import { ColorName, ColorRepresentation } from './types';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Normalize a color representation into RGB
|
|
8
|
-
*
|
|
9
|
-
* @param {ColorRepresentation} color Color representation
|
|
10
|
-
* @returns {[number,number,number]} Normalized RGB color
|
|
11
|
-
*/
|
|
12
|
-
export function normalizeColor(color: ColorRepresentation): [number, number, number] {
|
|
13
|
-
if (typeof color === 'string') {
|
|
14
|
-
return hexToRgb(W3CX11[color as ColorName] ?? color);
|
|
15
|
-
} else if (typeof color === 'number') {
|
|
16
|
-
return hexToRgb(color);
|
|
17
|
-
} else {
|
|
18
|
-
return color;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// ******************************************
|
|
23
|
-
// RGB & Hexadecimal color spaces
|
|
24
|
-
// ******************************************
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Normalize an hexadecimal string
|
|
28
|
-
*
|
|
29
|
-
* @param {string} hex Hexadecimal string
|
|
30
|
-
* @returns {string} Normalized hexadecimal string
|
|
31
|
-
*/
|
|
32
|
-
export function normalizeHexString(hex: string): string {
|
|
33
|
-
let match: RegExpMatchArray | null;
|
|
34
|
-
let result: string = '000000';
|
|
35
|
-
hex = hex.toLocaleLowerCase();
|
|
36
|
-
|
|
37
|
-
if ((match = hex.match(/(#|0x)?([a-f0-9]{6})/i))) {
|
|
38
|
-
result = match[2];
|
|
39
|
-
} else if ((match = hex.match(/^#?([a-f0-9])([a-f0-9])([a-f0-9])$/i))) {
|
|
40
|
-
result = match[1] + match[1] + match[2] + match[2] + match[3] + match[3];
|
|
41
|
-
} else if ((match = hex.match(/rgb\(\s*(\d*)\s*,\s*(\d*)\s*,\s*(\d*)\s*\)/))) {
|
|
42
|
-
result =
|
|
43
|
-
parseInt(match[1]).toString(16).padStart(2, '0') +
|
|
44
|
-
parseInt(match[2]).toString(16).padStart(2, '0') +
|
|
45
|
-
parseInt(match[3]).toString(16).padStart(2, '0');
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return `#${result}`;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Convert RGB to hexadecimal
|
|
53
|
-
* Note: rgb values are contained in the interval [0, 1]
|
|
54
|
-
*
|
|
55
|
-
* @param {[number, number, number]} rgb RGB color
|
|
56
|
-
* @returns {number} Hexadecimal color
|
|
57
|
-
*/
|
|
58
|
-
export function rgbToHex([r, g, b]: [number, number, number]): number {
|
|
59
|
-
return ((r * 255) << 16) ^ ((g * 255) << 8) ^ ((b * 255) << 0);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Convert RGB to hexadecimal string
|
|
64
|
-
* Note: rgb values are contained in the interval [0, 1]
|
|
65
|
-
*
|
|
66
|
-
* @param {[number, number, number]} rgb RGB color
|
|
67
|
-
* @returns {string} Hexadecimal string
|
|
68
|
-
*/
|
|
69
|
-
export function rgbToHexString([r, g, b]: [number, number, number]): string {
|
|
70
|
-
r = clamp(Math.round(r * 255), 0, 255);
|
|
71
|
-
g = clamp(Math.round(g * 255), 0, 255);
|
|
72
|
-
b = clamp(Math.round(b * 255), 0, 255);
|
|
73
|
-
|
|
74
|
-
const result = (b | (g << 8) | (r << 16) | (1 << 24)).toString(16).slice(1);
|
|
75
|
-
return `#${result}`;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Convert hexadecimal to RGB
|
|
80
|
-
* Note: rgb values are contained in the interval [0, 1]
|
|
81
|
-
*
|
|
82
|
-
* @param {(number|string)} hex Hexadecimal color
|
|
83
|
-
* @returns {[number, number, number]} RGB color
|
|
84
|
-
*/
|
|
85
|
-
export function hexToRgb(hex: number | string): [number, number, number] {
|
|
86
|
-
if (typeof hex === 'number') {
|
|
87
|
-
hex = Math.floor(hex);
|
|
88
|
-
} else if (typeof hex === 'string') {
|
|
89
|
-
hex = normalizeHexString(hex).replace(/^#/, '');
|
|
90
|
-
hex = parseInt(hex, 16);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const r = ((hex >> 16) & 255) / 255;
|
|
94
|
-
const g = ((hex >> 8) & 255) / 255;
|
|
95
|
-
const b = (hex & 255) / 255;
|
|
96
|
-
|
|
97
|
-
return [r, g, b];
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Lighten a color
|
|
102
|
-
*
|
|
103
|
-
* @param {string} hex Hexadecimal string
|
|
104
|
-
* @param {number} [amount=0] Amount of the color offset
|
|
105
|
-
* @returns {string} Computed hexadecimal
|
|
106
|
-
*/
|
|
107
|
-
export function lighten(hex: string, amount: number = 0): string {
|
|
108
|
-
let prefix = '';
|
|
109
|
-
|
|
110
|
-
if (hex[0] === '#') {
|
|
111
|
-
hex = hex.slice(1);
|
|
112
|
-
prefix = '#';
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const value = parseInt(hex, 16);
|
|
116
|
-
|
|
117
|
-
const r = clamp((value >> 16) + amount, 0, 255);
|
|
118
|
-
const b = clamp(((value >> 8) & 0x00ff) + amount, 0, 255);
|
|
119
|
-
const g = clamp((value & 0x0000ff) + amount, 0, 255);
|
|
120
|
-
|
|
121
|
-
let result: number | string = g | (b << 8) | (r << 16);
|
|
122
|
-
if (r === 0 && g === 0 && b === 0 && amount !== 0) {
|
|
123
|
-
result = '000000';
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return prefix + result.toString(16);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Darken a color
|
|
131
|
-
*
|
|
132
|
-
* @param {string} hex Hexadecimal string
|
|
133
|
-
* @param {number} [amount=0] Amount of the color offset
|
|
134
|
-
* @returns {string} Computed hexadecimal
|
|
135
|
-
*/
|
|
136
|
-
export function darken(hex: string, amount: number = 0): string {
|
|
137
|
-
return lighten(hex, -amount);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// ***************************************************
|
|
141
|
-
// RGB & Hue-Saturation-Lightness (HSL) color spaces
|
|
142
|
-
// ***************************************************
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Normalize an HSL string
|
|
146
|
-
* Note: hsl values are contained in the intervals H: [0, 360], S: [0, 1], L: [0, 1]
|
|
147
|
-
*
|
|
148
|
-
* @param {string} hsl HSL string (format: 'hsl(360, 100%, 100%)')
|
|
149
|
-
* @returns {[number, number, number]} Normalized HSL color
|
|
150
|
-
*/
|
|
151
|
-
export function normalizeHslString(hsl: string): [number, number, number] {
|
|
152
|
-
const [h, s, l] = hsl.match(/\d+/g)?.map(Number) ?? [0, 0, 0];
|
|
153
|
-
return [h, s / 100, l / 100];
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Convert RGB to HSL
|
|
158
|
-
* Notes:
|
|
159
|
-
* - rgb values are contained in the interval [0, 1]
|
|
160
|
-
* - hsl values are contained in the intervals H: [0, 360], S: [0, 1], L: [0, 1]
|
|
161
|
-
*
|
|
162
|
-
* @param {[number, number, number]} rgb RGB color
|
|
163
|
-
* @returns {[number, number, number]} HSL color
|
|
164
|
-
*/
|
|
165
|
-
export function rgbToHsl([r, g, b]: [number, number, number]): [number, number, number] {
|
|
166
|
-
const l = Math.max(r, g, b);
|
|
167
|
-
const s = l - Math.min(r, g, b);
|
|
168
|
-
const h = s ? (l === r ? (g - b) / s : l === g ? 2 + (b - r) / s : 4 + (r - g) / s) : 0;
|
|
169
|
-
|
|
170
|
-
return [
|
|
171
|
-
60 * h < 0 ? 60 * h + 360 : 60 * h,
|
|
172
|
-
s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0,
|
|
173
|
-
(2 * l - s) / 2
|
|
174
|
-
];
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Convert HSL to RGB
|
|
179
|
-
* Notes:
|
|
180
|
-
* - rgb values are contained in the interval [0, 1]
|
|
181
|
-
* - hsl values are contained in the intervals H: [0, 360], S: [0, 1], L: [0, 1]
|
|
182
|
-
*
|
|
183
|
-
* @param {[number, number, number]} hsl HSL color
|
|
184
|
-
* @returns {[number, number, number]} RGB color
|
|
185
|
-
*/
|
|
186
|
-
export function hslToRgb([h, s, l]: [number, number, number]): [number, number, number] {
|
|
187
|
-
const a = s * Math.min(l, 1 - l);
|
|
188
|
-
const k = (v: number) => (v + h / 30) % 12;
|
|
189
|
-
const f = (v: number) => l - a * Math.max(-1, Math.min(k(v) - 3, Math.min(9 - k(v), 1)));
|
|
190
|
-
return [f(0), f(8), f(4)];
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// ***************************************************
|
|
194
|
-
// RGB & Hue-Saturation-Brightness (HSB) color spaces
|
|
195
|
-
// ***************************************************
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Convert RGB to HSB
|
|
199
|
-
* Notes:
|
|
200
|
-
* - rgb values are contained in the interval [0, 1]
|
|
201
|
-
* - hsb values are contained in the intervals H: [0, 360], S: [0, 1], B: [0, 1]
|
|
202
|
-
*
|
|
203
|
-
* @param {[number, number, number]} rgb RGB color
|
|
204
|
-
* @returns {[number, number, number]} HSB color
|
|
205
|
-
*/
|
|
206
|
-
export function rgbToHsb([r, g, b]: [number, number, number]): [number, number, number] {
|
|
207
|
-
const max = Math.max(r, g, b);
|
|
208
|
-
const min = Math.min(r, g, b);
|
|
209
|
-
const delta = max - min;
|
|
210
|
-
const h =
|
|
211
|
-
delta === 0 ? 0 : delta && max === r ? (g - b) / delta : max === g ? 2 + (b - r) / delta : 4 + (r - g) / delta;
|
|
212
|
-
return [60 * (h < 0 ? h + 6 : h), max && delta / max, max];
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Convert HSB to RGB
|
|
217
|
-
* Notes:
|
|
218
|
-
* - rgb values are contained in the interval [0, 1]
|
|
219
|
-
* - hsb values are contained in the intervals H: [0, 360], S: [0, 1], B: [0, 1]
|
|
220
|
-
*
|
|
221
|
-
* @param {[number, number, number]} hsb HSB color
|
|
222
|
-
* @returns {[number, number, number]} RGB color
|
|
223
|
-
*/
|
|
224
|
-
export function hsbToRgb([h, s, b]: [number, number, number]): [number, number, number] {
|
|
225
|
-
const k = (v: number) => (v + h / 60) % 6;
|
|
226
|
-
const f = (v: number) => b * (1 - s * Math.max(0, Math.min(k(v), 4 - k(v), 1)));
|
|
227
|
-
return [f(5), f(3), f(1)];
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// *********************************************
|
|
231
|
-
// LAB & Hue-Chroma-Luminance (HCL) color spaces
|
|
232
|
-
// *********************************************
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Convert LAB to HCL
|
|
236
|
-
* -> http://www.brucelindbloom.com/index.html?Eqn_Lab_to_LCH.html
|
|
237
|
-
*
|
|
238
|
-
* @param {[number, number, number]} lab LAB color
|
|
239
|
-
* @returns {[number, number, number]} HCL color
|
|
240
|
-
*/
|
|
241
|
-
export function labToHcl([l, a, b]: [number, number, number]): [number, number, number] {
|
|
242
|
-
const c = Math.sqrt(a * a + b * b);
|
|
243
|
-
const h = abToHue(a, b);
|
|
244
|
-
return [h, c, l];
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Convert HCL to LAB
|
|
249
|
-
* -> http://www.brucelindbloom.com/index.html?Eqn_LCH_to_Lab.html
|
|
250
|
-
*
|
|
251
|
-
* @param {[number, number, number]} hcl HCL color
|
|
252
|
-
* @returns {[number, number, number]} LAB color space
|
|
253
|
-
*/
|
|
254
|
-
export function hclToLab([h, c, l]: [number, number, number]): [number, number, number] {
|
|
255
|
-
const a = c * Math.cos(toRadians(h));
|
|
256
|
-
const b = c * Math.sin(toRadians(h));
|
|
257
|
-
return [l, a, b];
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Convert A and B of LAB to Hue of LCH
|
|
262
|
-
* -> https://stackoverflow.com/questions/53733379/conversion-of-cielab-to-cielchab-not-yielding-correct-result
|
|
263
|
-
*
|
|
264
|
-
* @param {number} a A value of LAB color
|
|
265
|
-
* @param {number} b B value of LAB color
|
|
266
|
-
* @returns {number} Hue value
|
|
267
|
-
*/
|
|
268
|
-
function abToHue(a: number, b: number): number {
|
|
269
|
-
if (a >= 0 && b === 0) {
|
|
270
|
-
return 0;
|
|
271
|
-
}
|
|
272
|
-
if (a < 0 && b === 0) {
|
|
273
|
-
return 180;
|
|
274
|
-
}
|
|
275
|
-
if (a === 0 && b > 0) {
|
|
276
|
-
return 90;
|
|
277
|
-
}
|
|
278
|
-
if (a === 0 && b < 0) {
|
|
279
|
-
return 270;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
let xBias = 0;
|
|
283
|
-
if (a > 0 && b > 0) {
|
|
284
|
-
xBias = 0;
|
|
285
|
-
} else if (a < 0) {
|
|
286
|
-
xBias = 180;
|
|
287
|
-
} else if (a > 0 && b < 0) {
|
|
288
|
-
xBias = 360;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return toDegrees(Math.atan(b / a)) + xBias;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// ******************************************
|
|
295
|
-
// LAB & RGB color spaces
|
|
296
|
-
// ******************************************
|
|
297
|
-
const f1 = (v: number) => (v * v * v > 0.008856 ? v * v * v : (v - 16 / 116) / 7.787);
|
|
298
|
-
const f2 = (v: number) => (v > 0.0031308 ? 1.055 * Math.pow(v, 1 / 2.4) - 0.055 : 12.92 * v);
|
|
299
|
-
const f3 = (v: number) => (v > 0.04045 ? Math.pow((v + 0.055) / 1.055, 2.4) : v / 12.92);
|
|
300
|
-
const f4 = (v: number) => (v > 0.008856 ? Math.pow(v, 1 / 3) : 7.787 * v + 16 / 116);
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Converts LAB to RGB
|
|
304
|
-
*
|
|
305
|
-
* @param {[number, number, number]} lab LAB color
|
|
306
|
-
* @returns {[number, number, number]} RGB color
|
|
307
|
-
*/
|
|
308
|
-
export function labToRgb([l, a, b]: [number, number, number]): [number, number, number] {
|
|
309
|
-
let y = (l + 16) / 116;
|
|
310
|
-
let x = a / 500 + y;
|
|
311
|
-
let z = y - b / 200;
|
|
312
|
-
|
|
313
|
-
x = 0.95047 * f1(x);
|
|
314
|
-
y = 1.0 * f1(y);
|
|
315
|
-
z = 1.08883 * f1(z);
|
|
316
|
-
|
|
317
|
-
return [
|
|
318
|
-
clamp(f2(x * 3.2406 + y * -1.5372 + z * -0.4986)),
|
|
319
|
-
clamp(f2(x * -0.9689 + y * 1.8758 + z * 0.0415)),
|
|
320
|
-
clamp(f2(x * 0.0557 + y * -0.204 + z * 1.057))
|
|
321
|
-
];
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Converts RGB to LAB
|
|
326
|
-
*
|
|
327
|
-
* @param {[number, number, number]} rgb RGB color
|
|
328
|
-
* @returns {[number, number, number]} LAB color
|
|
329
|
-
*/
|
|
330
|
-
export function rgbToLab([r, g, b]: [number, number, number]): [number, number, number] {
|
|
331
|
-
r = f3(r);
|
|
332
|
-
g = f3(g);
|
|
333
|
-
b = f3(b);
|
|
334
|
-
|
|
335
|
-
let x = f4((r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047);
|
|
336
|
-
let y = f4((r * 0.2126 + g * 0.7152 + b * 0.0722) / 1);
|
|
337
|
-
let z = f4((r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883);
|
|
338
|
-
|
|
339
|
-
return [116 * y - 16, 500 * (x - y), 200 * (y - z)];
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* Get the delta from two LAB colors
|
|
344
|
-
*
|
|
345
|
-
* @param {[number, number, number]} labA First LAB color
|
|
346
|
-
* @param {[number, number, number]} labB Second LAB color
|
|
347
|
-
* @returns {number} Delta
|
|
348
|
-
*/
|
|
349
|
-
export function deltaE(labA: [number, number, number], labB: [number, number, number]): number {
|
|
350
|
-
const deltaL = labA[0] - labB[0];
|
|
351
|
-
const deltaA = labA[1] - labB[1];
|
|
352
|
-
const deltaB = labA[2] - labB[2];
|
|
353
|
-
const c1 = Math.sqrt(labA[1] * labA[1] + labA[2] * labA[2]);
|
|
354
|
-
const c2 = Math.sqrt(labB[1] * labB[1] + labB[2] * labB[2]);
|
|
355
|
-
const deltaC = c1 - c2;
|
|
356
|
-
let deltaH = deltaA * deltaA + deltaB * deltaB - deltaC * deltaC;
|
|
357
|
-
deltaH = deltaH < 0 ? 0 : Math.sqrt(deltaH);
|
|
358
|
-
const sc = 1.0 + 0.045 * c1;
|
|
359
|
-
const sh = 1.0 + 0.015 * c1;
|
|
360
|
-
const deltaLKlsl = deltaL / 1;
|
|
361
|
-
const deltaCkcsc = deltaC / sc;
|
|
362
|
-
const deltaHkhsh = deltaH / sh;
|
|
363
|
-
const i = deltaLKlsl * deltaLKlsl + deltaCkcsc * deltaCkcsc + deltaHkhsh * deltaHkhsh;
|
|
364
|
-
return i < 0 ? 0 : Math.sqrt(i);
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// *********************************************
|
|
368
|
-
// RGB & Hue-Chroma-Luminance (HCL) color spaces
|
|
369
|
-
// *********************************************
|
|
370
|
-
|
|
371
|
-
/**
|
|
372
|
-
* Convert RGB to HCL
|
|
373
|
-
*
|
|
374
|
-
* @param {[number, number, number]} rgb RGB color
|
|
375
|
-
* @returns {[number, number, number]} HCL color
|
|
376
|
-
*/
|
|
377
|
-
export function rgbToHcl([r, g, b]: [number, number, number]): [number, number, number] {
|
|
378
|
-
return labToHcl(rgbToLab([r, g, b]));
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
* Converts HCL to RGB
|
|
383
|
-
*
|
|
384
|
-
* @param {[number, number, number]} hcl RGB color
|
|
385
|
-
* @returns {[number, number, number]} RGB color
|
|
386
|
-
*/
|
|
387
|
-
export function hclToRgb([h, c, l]: [number, number, number]): [number, number, number] {
|
|
388
|
-
return labToRgb(hclToLab([h, c, l]));
|
|
389
|
-
}
|
package/src/constants.ts
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
// *********************
|
|
2
|
-
// Maths
|
|
3
|
-
// *********************
|
|
4
|
-
export const EPSILON = 1e-10;
|
|
5
|
-
export const PI = Math.PI;
|
|
6
|
-
export const TWO_PI = Math.PI * 2;
|
|
7
|
-
export const HALF_PI = Math.PI / 2;
|
|
8
|
-
export const QUARTER_PI = Math.PI / 4;
|
|
9
|
-
|
|
10
|
-
// *********************
|
|
11
|
-
// Colors
|
|
12
|
-
// *********************
|
|
13
|
-
|
|
14
|
-
// X11 colors
|
|
15
|
-
// -> https://www.w3.org/TR/css-color-3/#svg-color
|
|
16
|
-
export const W3CX11 = {
|
|
17
|
-
aliceblue: 0xf0f8ff,
|
|
18
|
-
antiquewhite: 0xfaebd7,
|
|
19
|
-
aqua: 0x00ffff,
|
|
20
|
-
aquamarine: 0x7fffd4,
|
|
21
|
-
azure: 0xf0ffff,
|
|
22
|
-
beige: 0xf5f5dc,
|
|
23
|
-
bisque: 0xffe4c4,
|
|
24
|
-
black: 0x000000,
|
|
25
|
-
blanchedalmond: 0xffebcd,
|
|
26
|
-
blue: 0x0000ff,
|
|
27
|
-
blueviolet: 0x8a2be2,
|
|
28
|
-
brown: 0xa52a2a,
|
|
29
|
-
burlywood: 0xdeb887,
|
|
30
|
-
cadetblue: 0x5f9ea0,
|
|
31
|
-
chartreuse: 0x7fff00,
|
|
32
|
-
chocolate: 0xd2691e,
|
|
33
|
-
coral: 0xff7f50,
|
|
34
|
-
cornflower: 0x6495ed,
|
|
35
|
-
cornflowerblue: 0x6495ed,
|
|
36
|
-
cornsilk: 0xfff8dc,
|
|
37
|
-
crimson: 0xdc143c,
|
|
38
|
-
cyan: 0x00ffff,
|
|
39
|
-
darkblue: 0x00008b,
|
|
40
|
-
darkcyan: 0x008b8b,
|
|
41
|
-
darkgoldenrod: 0xb8860b,
|
|
42
|
-
darkgray: 0xa9a9a9,
|
|
43
|
-
darkgreen: 0x006400,
|
|
44
|
-
darkgrey: 0xa9a9a9,
|
|
45
|
-
darkkhaki: 0xbdb76b,
|
|
46
|
-
darkmagenta: 0x8b008b,
|
|
47
|
-
darkolivegreen: 0x556b2f,
|
|
48
|
-
darkorange: 0xff8c00,
|
|
49
|
-
darkorchid: 0x9932cc,
|
|
50
|
-
darkred: 0x8b0000,
|
|
51
|
-
darksalmon: 0xe9967a,
|
|
52
|
-
darkseagreen: 0x8fbc8f,
|
|
53
|
-
darkslateblue: 0x483d8b,
|
|
54
|
-
darkslategray: 0x2f4f4f,
|
|
55
|
-
darkslategrey: 0x2f4f4f,
|
|
56
|
-
darkturquoise: 0x00ced1,
|
|
57
|
-
darkviolet: 0x9400d3,
|
|
58
|
-
deeppink: 0xff1493,
|
|
59
|
-
deepskyblue: 0x00bfff,
|
|
60
|
-
dimgray: 0x696969,
|
|
61
|
-
dimgrey: 0x696969,
|
|
62
|
-
dodgerblue: 0x1e90ff,
|
|
63
|
-
firebrick: 0xb22222,
|
|
64
|
-
floralwhite: 0xfffaf0,
|
|
65
|
-
forestgreen: 0x228b22,
|
|
66
|
-
fuchsia: 0xff00ff,
|
|
67
|
-
gainsboro: 0xdcdcdc,
|
|
68
|
-
ghostwhite: 0xf8f8ff,
|
|
69
|
-
gold: 0xffd700,
|
|
70
|
-
goldenrod: 0xdaa520,
|
|
71
|
-
gray: 0x808080,
|
|
72
|
-
green: 0x008000,
|
|
73
|
-
greenyellow: 0xadff2f,
|
|
74
|
-
grey: 0x808080,
|
|
75
|
-
honeydew: 0xf0fff0,
|
|
76
|
-
hotpink: 0xff69b4,
|
|
77
|
-
indianred: 0xcd5c5c,
|
|
78
|
-
indigo: 0x4b0082,
|
|
79
|
-
ivory: 0xfffff0,
|
|
80
|
-
khaki: 0xf0e68c,
|
|
81
|
-
laserlemon: 0xffff54,
|
|
82
|
-
lavender: 0xe6e6fa,
|
|
83
|
-
lavenderblush: 0xfff0f5,
|
|
84
|
-
lawngreen: 0x7cfc00,
|
|
85
|
-
lemonchiffon: 0xfffacd,
|
|
86
|
-
lightblue: 0xadd8e6,
|
|
87
|
-
lightcoral: 0xf08080,
|
|
88
|
-
lightcyan: 0xe0ffff,
|
|
89
|
-
lightgoldenrod: 0xfafad2,
|
|
90
|
-
lightgoldenrodyellow: 0xfafad2,
|
|
91
|
-
lightgray: 0xd3d3d3,
|
|
92
|
-
lightgreen: 0x90ee90,
|
|
93
|
-
lightgrey: 0xd3d3d3,
|
|
94
|
-
lightpink: 0xffb6c1,
|
|
95
|
-
lightsalmon: 0xffa07a,
|
|
96
|
-
lightseagreen: 0x20b2aa,
|
|
97
|
-
lightskyblue: 0x87cefa,
|
|
98
|
-
lightslategray: 0x778899,
|
|
99
|
-
lightslategrey: 0x778899,
|
|
100
|
-
lightsteelblue: 0xb0c4de,
|
|
101
|
-
lightyellow: 0xffffe0,
|
|
102
|
-
lime: 0x00ff00,
|
|
103
|
-
limegreen: 0x32cd32,
|
|
104
|
-
linen: 0xfaf0e6,
|
|
105
|
-
magenta: 0xff00ff,
|
|
106
|
-
maroon: 0x800000,
|
|
107
|
-
maroon2: 0x7f0000,
|
|
108
|
-
maroon3: 0xb03060,
|
|
109
|
-
mediumaquamarine: 0x66cdaa,
|
|
110
|
-
mediumblue: 0x0000cd,
|
|
111
|
-
mediumorchid: 0xba55d3,
|
|
112
|
-
mediumpurple: 0x9370db,
|
|
113
|
-
mediumseagreen: 0x3cb371,
|
|
114
|
-
mediumslateblue: 0x7b68ee,
|
|
115
|
-
mediumspringgreen: 0x00fa9a,
|
|
116
|
-
mediumturquoise: 0x48d1cc,
|
|
117
|
-
mediumvioletred: 0xc71585,
|
|
118
|
-
midnightblue: 0x191970,
|
|
119
|
-
mintcream: 0xf5fffa,
|
|
120
|
-
mistyrose: 0xffe4e1,
|
|
121
|
-
moccasin: 0xffe4b5,
|
|
122
|
-
navajowhite: 0xffdead,
|
|
123
|
-
navy: 0x000080,
|
|
124
|
-
oldlace: 0xfdf5e6,
|
|
125
|
-
olive: 0x808000,
|
|
126
|
-
olivedrab: 0x6b8e23,
|
|
127
|
-
orange: 0xffa500,
|
|
128
|
-
orangered: 0xff4500,
|
|
129
|
-
orchid: 0xda70d6,
|
|
130
|
-
palegoldenrod: 0xeee8aa,
|
|
131
|
-
palegreen: 0x98fb98,
|
|
132
|
-
paleturquoise: 0xafeeee,
|
|
133
|
-
palevioletred: 0xdb7093,
|
|
134
|
-
papayawhip: 0xffefd5,
|
|
135
|
-
peachpuff: 0xffdab9,
|
|
136
|
-
peru: 0xcd853f,
|
|
137
|
-
pink: 0xffc0cb,
|
|
138
|
-
plum: 0xdda0dd,
|
|
139
|
-
powderblue: 0xb0e0e6,
|
|
140
|
-
purple: 0x800080,
|
|
141
|
-
purple2: 0x7f007f,
|
|
142
|
-
purple3: 0xa020f0,
|
|
143
|
-
rebeccapurple: 0x663399,
|
|
144
|
-
red: 0xff0000,
|
|
145
|
-
rosybrown: 0xbc8f8f,
|
|
146
|
-
royalblue: 0x4169e1,
|
|
147
|
-
saddlebrown: 0x8b4513,
|
|
148
|
-
salmon: 0xfa8072,
|
|
149
|
-
sandybrown: 0xf4a460,
|
|
150
|
-
seagreen: 0x2e8b57,
|
|
151
|
-
seashell: 0xfff5ee,
|
|
152
|
-
sienna: 0xa0522d,
|
|
153
|
-
silver: 0xc0c0c0,
|
|
154
|
-
skyblue: 0x87ceeb,
|
|
155
|
-
slateblue: 0x6a5acd,
|
|
156
|
-
slategray: 0x708090,
|
|
157
|
-
slategrey: 0x708090,
|
|
158
|
-
snow: 0xfffafa,
|
|
159
|
-
springgreen: 0x00ff7f,
|
|
160
|
-
steelblue: 0x4682b4,
|
|
161
|
-
tan: 0xd2b48c,
|
|
162
|
-
teal: 0x008080,
|
|
163
|
-
thistle: 0xd8bfd8,
|
|
164
|
-
tomato: 0xff6347,
|
|
165
|
-
turquoise: 0x40e0d0,
|
|
166
|
-
violet: 0xee82ee,
|
|
167
|
-
wheat: 0xf5deb3,
|
|
168
|
-
white: 0xffffff,
|
|
169
|
-
whitesmoke: 0xf5f5f5,
|
|
170
|
-
yellow: 0xffff00,
|
|
171
|
-
yellowgreen: 0x9acd32
|
|
172
|
-
};
|
package/src/dom.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
const DOCUMENT_NODE_TYPE = 9;
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Find the closest parent that matches a selector
|
|
5
|
-
*
|
|
6
|
-
* @param {Element} element Target element
|
|
7
|
-
* @param {(Element|string)} selector Selector or parent to match
|
|
8
|
-
* @returns {Element|null}
|
|
9
|
-
*/
|
|
10
|
-
export function closest(element: Element, selector: Element | string): Element | null {
|
|
11
|
-
let current: Element | null = element;
|
|
12
|
-
while (current && current.nodeType !== DOCUMENT_NODE_TYPE) {
|
|
13
|
-
if ((typeof selector === 'string' && current.matches(selector)) || current === selector) {
|
|
14
|
-
return current;
|
|
15
|
-
}
|
|
16
|
-
current = element.parentNode as Element | null;
|
|
17
|
-
}
|
|
18
|
-
return current;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Create a canvas and 2d context
|
|
23
|
-
*
|
|
24
|
-
* @param {Number} width Width of the canvas
|
|
25
|
-
* @param {Number} height Height of the canvas
|
|
26
|
-
* @returns {{ canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D }}
|
|
27
|
-
*/
|
|
28
|
-
export function createCanvas(
|
|
29
|
-
width: number,
|
|
30
|
-
height: number
|
|
31
|
-
): { canvas: HTMLCanvasElement; ctx: CanvasRenderingContext2D } {
|
|
32
|
-
const canvas = document.createElement('canvas');
|
|
33
|
-
canvas.width = width;
|
|
34
|
-
canvas.height = height;
|
|
35
|
-
const ctx = canvas.getContext('2d') ?? new CanvasRenderingContext2D();
|
|
36
|
-
return { canvas, ctx };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Inject CSS styles in `document.head`
|
|
41
|
-
*
|
|
42
|
-
* @param {string} styles CSS styles to inject
|
|
43
|
-
*/
|
|
44
|
-
export function injectStyles(styles: string): void {
|
|
45
|
-
const $style = document.createElement('style');
|
|
46
|
-
$style.innerHTML = styles;
|
|
47
|
-
const $before = document.querySelector('head link[rel=stylesheet], head style');
|
|
48
|
-
if ($before) document.head.insertBefore($style, $before);
|
|
49
|
-
else document.head.appendChild($style);
|
|
50
|
-
}
|
package/src/files.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
type InputChangeEvent = Event & { target: (EventTarget & { files?: FileList }) | null };
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Download a Blob object into user files
|
|
5
|
-
*
|
|
6
|
-
* @param {Blob} blob Blob object to download
|
|
7
|
-
* @param {string} filename Downloaded file name
|
|
8
|
-
*/
|
|
9
|
-
export function download(blob: Blob, filename: string): void {
|
|
10
|
-
const link = document.createElement('a');
|
|
11
|
-
link.setAttribute('href', URL.createObjectURL(blob));
|
|
12
|
-
link.setAttribute('download', filename);
|
|
13
|
-
|
|
14
|
-
document.body.appendChild(link);
|
|
15
|
-
link.click();
|
|
16
|
-
document.body.removeChild(link);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Upload a file from user files
|
|
21
|
-
*
|
|
22
|
-
* @param {Function} onLoad Callback called once the file is loaded
|
|
23
|
-
* @param {string} [accept=''] MIME type the file input should accept
|
|
24
|
-
*/
|
|
25
|
-
export function upload(onLoad: (dataUrl: string) => void, accept: string = ''): void {
|
|
26
|
-
const input = document.createElement('input');
|
|
27
|
-
input.setAttribute('type', 'file');
|
|
28
|
-
input.setAttribute('accept', accept);
|
|
29
|
-
|
|
30
|
-
input.addEventListener('change', (event: InputChangeEvent) => {
|
|
31
|
-
const file = event.target?.files?.[0];
|
|
32
|
-
if (file) {
|
|
33
|
-
const fileReader = new FileReader();
|
|
34
|
-
fileReader.addEventListener('load', () => onLoad(URL.createObjectURL(file)));
|
|
35
|
-
fileReader.readAsDataURL(file);
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
document.body.appendChild(input);
|
|
40
|
-
input.click();
|
|
41
|
-
document.body.removeChild(input);
|
|
42
|
-
}
|
package/src/functions.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { Deferred } from './types';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* No-op function
|
|
5
|
-
*/
|
|
6
|
-
export const noop: () => void = () => {};
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Promise wrapped setTimeout
|
|
10
|
-
*
|
|
11
|
-
* @param {number} [timeout=0] Time to wait (in milliseconds)
|
|
12
|
-
* @returns {Promise}
|
|
13
|
-
*/
|
|
14
|
-
export function wait(timeout: number = 0): Promise<void> {
|
|
15
|
-
return new Promise((resolve) => setTimeout(resolve, timeout));
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Deferred promise implementation
|
|
20
|
-
*
|
|
21
|
-
* @returns {Deferred}
|
|
22
|
-
*/
|
|
23
|
-
export function defer<T = void>(): Deferred<T> {
|
|
24
|
-
let resolve!: (value: T | PromiseLike<T>) => void;
|
|
25
|
-
let reject!: (reason?: unknown) => void;
|
|
26
|
-
const promise = new Promise<T>((_resolve, _reject) => {
|
|
27
|
-
resolve = _resolve;
|
|
28
|
-
reject = _reject;
|
|
29
|
-
});
|
|
30
|
-
return { promise, resolve, reject };
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Polyfill for `now()` functions
|
|
35
|
-
*/
|
|
36
|
-
export let now: () => number;
|
|
37
|
-
|
|
38
|
-
// In node.js, use `process.hrtime`
|
|
39
|
-
if (typeof process !== 'undefined' && process.hrtime) {
|
|
40
|
-
now = function () {
|
|
41
|
-
// Convert [seconds, nanoseconds] to milliseconds
|
|
42
|
-
const time = process.hrtime();
|
|
43
|
-
return time[0] * 1000 + time[1] / 1000000;
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
// In a browser use `performance` or `Date`
|
|
47
|
-
else if (typeof performance !== 'undefined') {
|
|
48
|
-
// This must be bound, because directly assigning this function leads to an invocation exception in Chrome
|
|
49
|
-
now = performance.now.bind(performance);
|
|
50
|
-
} else if (typeof Date.now !== 'undefined') {
|
|
51
|
-
now = Date.now;
|
|
52
|
-
} else {
|
|
53
|
-
now = function () {
|
|
54
|
-
return new Date().getTime();
|
|
55
|
-
};
|
|
56
|
-
}
|