muigui 0.0.10 → 0.0.13
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 +349 -42
- package/package.json +20 -5
- package/src/controllers/Button.js +3 -0
- package/src/controllers/Canvas.js +2 -2
- package/src/controllers/ColorChooser.js +44 -3
- package/src/controllers/Container.js +2 -2
- package/src/controllers/Folder.js +1 -0
- package/src/controllers/PopDownController.js +18 -2
- package/src/controllers/Text.js +1 -1
- package/src/controllers/TextNumber.js +1 -1
- package/src/controllers/create-controller.js +3 -0
- package/src/{esm.js → esm.ts} +8 -0
- package/src/libs/color-utils.js +276 -12
- package/src/libs/elem.js +6 -1
- package/src/libs/graph.js +42 -0
- package/src/libs/keyboard.js +2 -2
- package/src/libs/monitor.js +5 -0
- package/src/libs/touch.js +4 -4
- package/src/libs/wheel.js +1 -1
- package/src/muigui.js +16 -3
- package/src/styles/muigui.css.js +131 -28
- package/src/views/ColorChooserView.js +128 -31
- package/src/views/NumberView.js +10 -3
- package/src/views/RadioGridView.js +3 -2
- package/src/views/TextView.js +6 -2
- package/src/views/{View.js → View.ts} +15 -13
package/src/libs/color-utils.js
CHANGED
|
@@ -9,6 +9,11 @@ const hexToUint32RGB = v => (parseInt(v.substring(1, 3), 16) << 16) |
|
|
|
9
9
|
(parseInt(v.substring(3, 5), 16) << 8 ) |
|
|
10
10
|
(parseInt(v.substring(5, 7), 16) );
|
|
11
11
|
const uint32RGBToHex = v => `#${(Math.round(v)).toString(16).padStart(6, '0')}`;
|
|
12
|
+
const hexToUint32RGBA = v => (parseInt(v.substring(1, 3), 16) * 2 ** 24) +
|
|
13
|
+
(parseInt(v.substring(3, 5), 16) * 2 ** 16) +
|
|
14
|
+
(parseInt(v.substring(5, 7), 16) * 2 ** 8) +
|
|
15
|
+
(parseInt(v.substring(7, 9), 16) );
|
|
16
|
+
const uint32RGBAToHex = v => `#${(Math.round(v)).toString(16).padStart(8, '0')}`;
|
|
12
17
|
|
|
13
18
|
export const hexToUint8RGB = v => [
|
|
14
19
|
parseInt(v.substring(1, 3), 16),
|
|
@@ -17,16 +22,35 @@ export const hexToUint8RGB = v => [
|
|
|
17
22
|
];
|
|
18
23
|
export const uint8RGBToHex = v => `#${Array.from(v).map(v => v.toString(16).padStart(2, '0')).join('')}`;
|
|
19
24
|
|
|
25
|
+
export const hexToUint8RGBA = v => [
|
|
26
|
+
parseInt(v.substring(1, 3), 16),
|
|
27
|
+
parseInt(v.substring(3, 5), 16),
|
|
28
|
+
parseInt(v.substring(5, 7), 16),
|
|
29
|
+
parseInt(v.substring(7, 9), 16),
|
|
30
|
+
];
|
|
31
|
+
export const uint8RGBAToHex = v => `#${Array.from(v).map(v => v.toString(16).padStart(2, '0')).join('')}`;
|
|
32
|
+
|
|
20
33
|
export const hexToFloatRGB = v => hexToUint8RGB(v).map(v => f3(v / 255));
|
|
21
34
|
export const floatRGBToHex = v => uint8RGBToHex(Array.from(v).map(v => Math.round(clamp(v * 255, 0, 255))));
|
|
22
35
|
|
|
36
|
+
export const hexToFloatRGBA = v => hexToUint8RGBA(v).map(v => f3(v / 255));
|
|
37
|
+
export const floatRGBAToHex = v => uint8RGBAToHex(Array.from(v).map(v => Math.round(clamp(v * 255, 0, 255))));
|
|
38
|
+
|
|
39
|
+
const scaleAndClamp = v => clamp(Math.round(v * 255), 0, 255).toString(16).padStart(2, '0');
|
|
40
|
+
|
|
23
41
|
const hexToObjectRGB = v => ({
|
|
24
42
|
r: parseInt(v.substring(1, 3), 16) / 255,
|
|
25
43
|
g: parseInt(v.substring(3, 5), 16) / 255,
|
|
26
44
|
b: parseInt(v.substring(5, 7), 16) / 255,
|
|
27
45
|
});
|
|
28
|
-
const scaleAndClamp = v => clamp(Math.round(v * 255), 0, 255).toString(16).padStart(2, '0');
|
|
29
46
|
const objectRGBToHex = v => `#${scaleAndClamp(v.r)}${scaleAndClamp(v.g)}${scaleAndClamp(v.b)}`;
|
|
47
|
+
const hexToObjectRGBA = v => ({
|
|
48
|
+
r: parseInt(v.substring(1, 3), 16) / 255,
|
|
49
|
+
g: parseInt(v.substring(3, 5), 16) / 255,
|
|
50
|
+
b: parseInt(v.substring(5, 7), 16) / 255,
|
|
51
|
+
a: parseInt(v.substring(7, 9), 16) / 255,
|
|
52
|
+
});
|
|
53
|
+
const objectRGBAToHex = v => `#${scaleAndClamp(v.r)}${scaleAndClamp(v.g)}${scaleAndClamp(v.b)}${scaleAndClamp(v.a)}`;
|
|
30
54
|
|
|
31
55
|
const hexToCssRGB = v => `rgb(${hexToUint8RGB(v).join(', ')})`;
|
|
32
56
|
const cssRGBRegex = /^\s*rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)\s*$/;
|
|
@@ -34,14 +58,23 @@ const cssRGBToHex = v => {
|
|
|
34
58
|
const m = cssRGBRegex.exec(v);
|
|
35
59
|
return uint8RGBToHex([m[1], m[2], m[3]].map(v => parseInt(v)));
|
|
36
60
|
};
|
|
37
|
-
const
|
|
61
|
+
const hexToCssRGBA = v => `rgba(${hexToUint8RGBA(v).map((v, i) => i === 3 ? v / 255 : v).join(', ')})`;
|
|
62
|
+
const cssRGBARegex = /^\s*rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+\.\d+|\d+)\s*\)\s*$/;
|
|
63
|
+
const cssRGBAToHex = v => {
|
|
64
|
+
const m = cssRGBARegex.exec(v);
|
|
65
|
+
return uint8RGBAToHex([m[1], m[2], m[3], m[4]].map((v, i) => i === 3 ? (parseFloat(v) * 255 | 0) : parseInt(v)));
|
|
66
|
+
};
|
|
38
67
|
|
|
39
68
|
const hexToCssHSL = v => {
|
|
40
69
|
const hsl = rgbUint8ToHsl(hexToUint8RGB(v)).map(v => f0(v));
|
|
41
70
|
return `hsl(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%)`;
|
|
42
71
|
};
|
|
43
|
-
const
|
|
44
|
-
const
|
|
72
|
+
const hexToCssHSLA = v => {
|
|
73
|
+
const hsla = rgbaUint8ToHsla(hexToUint8RGBA(v)).map((v, i) => i === 3 ? f3(v) : f0(v));
|
|
74
|
+
return `hsl(${hsla[0]} ${hsla[1]}% ${hsla[2]}% / ${hsla[3]})`;
|
|
75
|
+
};
|
|
76
|
+
const cssHSLRegex = /^\s*hsl\(\s*(\d+)(?:deg|)\s*(?:,|)\s*(\d+)%\s*(?:,|)\s*(\d+)%\s*\)\s*$/;
|
|
77
|
+
const cssHSLARegex = /^\s*hsl\(\s*(\d+)(?:deg|)\s*(?:,|)\s*(\d+)%\s*(?:,|)\s*(\d+)%\s*\/\s*(\d+\.\d+|\d+)\s*\)\s*$/;
|
|
45
78
|
|
|
46
79
|
const hex3DigitTo6Digit = v => `${v[0]}${v[0]}${v[1]}${v[1]}${v[2]}${v[2]}`;
|
|
47
80
|
const cssHSLToHex = v => {
|
|
@@ -49,6 +82,11 @@ const cssHSLToHex = v => {
|
|
|
49
82
|
const rgb = hslToRgbUint8([m[1], m[2], m[3]].map(v => parseFloat(v)));
|
|
50
83
|
return uint8RGBToHex(rgb);
|
|
51
84
|
};
|
|
85
|
+
const cssHSLAToHex = v => {
|
|
86
|
+
const m = cssHSLARegex.exec(v);
|
|
87
|
+
const rgba = hslaToRgbaUint8([m[1], m[2], m[3], m[4]].map(v => parseFloat(v)));
|
|
88
|
+
return uint8RGBAToHex(rgba);
|
|
89
|
+
};
|
|
52
90
|
|
|
53
91
|
const euclideanModulo = (v, n) => ((v % n) + n) % n;
|
|
54
92
|
|
|
@@ -67,6 +105,11 @@ export function hslToRgbUint8([h, s, l]) {
|
|
|
67
105
|
return [f(0), f(8), f(4)].map(v => Math.round(v * 255));
|
|
68
106
|
}
|
|
69
107
|
|
|
108
|
+
export function hslaToRgbaUint8([h, s, l, a]) {
|
|
109
|
+
const rgb = hslToRgbUint8([h, s, l]);
|
|
110
|
+
return [...rgb, a * 255 | 0];
|
|
111
|
+
}
|
|
112
|
+
|
|
70
113
|
export function rgbFloatToHsl01([r, g, b]) {
|
|
71
114
|
const max = Math.max(r, g, b);
|
|
72
115
|
const min = Math.min(r, g, b);
|
|
@@ -90,11 +133,21 @@ export function rgbFloatToHsl01([r, g, b]) {
|
|
|
90
133
|
return [h / 6, s, l];
|
|
91
134
|
}
|
|
92
135
|
|
|
136
|
+
export function rgbaFloatToHsla01([r, g, b, a]) {
|
|
137
|
+
const hsl = rgbFloatToHsl01([r, g, b]);
|
|
138
|
+
return [...hsl, a];
|
|
139
|
+
}
|
|
140
|
+
|
|
93
141
|
export const rgbUint8ToHsl = (rgb) => {
|
|
94
142
|
const [h, s, l] = rgbFloatToHsl01(rgb.map(v => v / 255));
|
|
95
143
|
return [h * 360, s * 100, l * 100];
|
|
96
144
|
};
|
|
97
145
|
|
|
146
|
+
export const rgbaUint8ToHsla = (rgba) => {
|
|
147
|
+
const [h, s, l, a] = rgbaFloatToHsla01(rgba.map(v => v / 255));
|
|
148
|
+
return [h * 360, s * 100, l * 100, a];
|
|
149
|
+
};
|
|
150
|
+
|
|
98
151
|
export function hsv01ToRGBFloat([hue, sat, val]) {
|
|
99
152
|
sat = clamp(sat, 0, 1);
|
|
100
153
|
val = clamp(val, 0, 1);
|
|
@@ -103,6 +156,11 @@ export function hsv01ToRGBFloat([hue, sat, val]) {
|
|
|
103
156
|
);
|
|
104
157
|
}
|
|
105
158
|
|
|
159
|
+
export function hsva01ToRGBAFloat([hue, sat, val, alpha]) {
|
|
160
|
+
const rgb = hsv01ToRGBFloat([hue, sat, val]);
|
|
161
|
+
return [...rgb, alpha];
|
|
162
|
+
}
|
|
163
|
+
|
|
106
164
|
const round3 = v => Math.round(v * 1000) / 1000;
|
|
107
165
|
|
|
108
166
|
export function rgbFloatToHSV01([r, g, b]) {
|
|
@@ -120,8 +178,13 @@ export function rgbFloatToHSV01([r, g, b]) {
|
|
|
120
178
|
].map(round3);
|
|
121
179
|
}
|
|
122
180
|
|
|
123
|
-
|
|
124
|
-
|
|
181
|
+
export function rgbaFloatToHSVA01([r, g, b, a]) {
|
|
182
|
+
const hsv = rgbFloatToHSV01([r, g, b]);
|
|
183
|
+
return [...hsv, a];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// window.hsv01ToRGBFloat = hsv01ToRGBFloat;
|
|
187
|
+
// window.rgbFloatToHSV01 = rgbFloatToHSV01;
|
|
125
188
|
|
|
126
189
|
// Yea, meh!
|
|
127
190
|
export const hasAlpha = format => format.endsWith('a') || format.startsWith('hex8');
|
|
@@ -199,6 +262,13 @@ function fixHex6(v) {
|
|
|
199
262
|
//return fix(v.trim());
|
|
200
263
|
}
|
|
201
264
|
|
|
265
|
+
function fixHex8(v) {
|
|
266
|
+
return v.trim(v);
|
|
267
|
+
//const formatInfo = guessStringColorFormat(v.trim());
|
|
268
|
+
//const fix = formatInfo ? formatInfo.fix : v => v;
|
|
269
|
+
//return fix(v.trim());
|
|
270
|
+
}
|
|
271
|
+
|
|
202
272
|
function hex6ToHex3(hex6) {
|
|
203
273
|
return (hex6[1] === hex6[2] &&
|
|
204
274
|
hex6[3] === hex6[4] &&
|
|
@@ -234,6 +304,19 @@ const strToRGBObject = (s) => {
|
|
|
234
304
|
}
|
|
235
305
|
};
|
|
236
306
|
|
|
307
|
+
const strToRGBAObject = (s) => {
|
|
308
|
+
try {
|
|
309
|
+
const json = s.replace(/([a-z])/g, '"$1"');
|
|
310
|
+
const rgba = JSON.parse(json);
|
|
311
|
+
if (Number.isNaN(rgba.r) || Number.isNaN(rgba.g) || Number.isNaN(rgba.b) || Number.isNaN(rgba.a)) {
|
|
312
|
+
throw new Error('not {r, g, b, a}');
|
|
313
|
+
}
|
|
314
|
+
return [true, rgba];
|
|
315
|
+
} catch (e) {
|
|
316
|
+
return [false];
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
|
|
237
320
|
const strToCssRGB = s => {
|
|
238
321
|
const m = cssRGBRegex.exec(s);
|
|
239
322
|
if (!m) {
|
|
@@ -244,6 +327,16 @@ const strToCssRGB = s => {
|
|
|
244
327
|
return [!outOfRange, `rgb(${v.join(', ')})`];
|
|
245
328
|
};
|
|
246
329
|
|
|
330
|
+
const strToCssRGBA = s => {
|
|
331
|
+
const m = cssRGBARegex.exec(s);
|
|
332
|
+
if (!m) {
|
|
333
|
+
return [false];
|
|
334
|
+
}
|
|
335
|
+
const v = [m[1], m[2], m[3], m[4]].map((v, i) => i === 3 ? parseFloat(v) : parseInt(v));
|
|
336
|
+
const outOfRange = v.find(v => v > 255);
|
|
337
|
+
return [!outOfRange, `rgba(${v.join(', ')})`];
|
|
338
|
+
};
|
|
339
|
+
|
|
247
340
|
const strToCssHSL = s => {
|
|
248
341
|
const m = cssHSLRegex.exec(s);
|
|
249
342
|
if (!m) {
|
|
@@ -254,9 +347,22 @@ const strToCssHSL = s => {
|
|
|
254
347
|
return [!outOfRange, `hsl(${v[0]}, ${v[1]}%, ${v[2]}%)`];
|
|
255
348
|
};
|
|
256
349
|
|
|
350
|
+
const strToCssHSLA = s => {
|
|
351
|
+
const m = cssHSLARegex.exec(s);
|
|
352
|
+
if (!m) {
|
|
353
|
+
return [false];
|
|
354
|
+
}
|
|
355
|
+
const v = [m[1], m[2], m[3], m[4]].map(v => parseFloat(v));
|
|
356
|
+
const outOfRange = v.find(v => Number.isNaN(v));
|
|
357
|
+
return [!outOfRange, `hsl(${v[0]} ${v[1]}% ${v[2]}% / ${v[3]})`];
|
|
358
|
+
};
|
|
359
|
+
|
|
257
360
|
const rgbObjectToStr = rgb => {
|
|
258
361
|
return `{r:${f3(rgb.r)}, g:${f3(rgb.g)}, b:${f3(rgb.b)}}`;
|
|
259
362
|
};
|
|
363
|
+
const rgbaObjectToStr = rgba => {
|
|
364
|
+
return `{r:${f3(rgba.r)}, g:${f3(rgba.g)}, b:${f3(rgba.b)}}, a:${f3(rgba.a)}}`;
|
|
365
|
+
};
|
|
260
366
|
|
|
261
367
|
const strTo3IntsRE = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*$/;
|
|
262
368
|
const strTo3Ints = s => {
|
|
@@ -269,6 +375,17 @@ const strTo3Ints = s => {
|
|
|
269
375
|
return [!outOfRange, v];
|
|
270
376
|
};
|
|
271
377
|
|
|
378
|
+
const strTo4IntsRE = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*$/;
|
|
379
|
+
const strTo4Ints = s => {
|
|
380
|
+
const m = strTo4IntsRE.exec(s);
|
|
381
|
+
if (!m) {
|
|
382
|
+
return [false];
|
|
383
|
+
}
|
|
384
|
+
const v = [m[1], m[2], m[3], m[4]].map(v => parseInt(v));
|
|
385
|
+
const outOfRange = v.find(v => v > 255);
|
|
386
|
+
return [!outOfRange, v];
|
|
387
|
+
};
|
|
388
|
+
|
|
272
389
|
const strTo3Floats = s => {
|
|
273
390
|
const numbers = s.split(',').map(s => s.trim());
|
|
274
391
|
const v = numbers.map(v => parseFloat(v));
|
|
@@ -280,6 +397,17 @@ const strTo3Floats = s => {
|
|
|
280
397
|
return [badNdx < 0, v.map(v => f3(v))];
|
|
281
398
|
};
|
|
282
399
|
|
|
400
|
+
const strTo4Floats = s => {
|
|
401
|
+
const numbers = s.split(',').map(s => s.trim());
|
|
402
|
+
const v = numbers.map(v => parseFloat(v));
|
|
403
|
+
if (v.length !== 4) {
|
|
404
|
+
return [false];
|
|
405
|
+
}
|
|
406
|
+
// Note: using isNaN not Number.isNaN
|
|
407
|
+
const badNdx = numbers.findIndex(v => isNaN(v));
|
|
408
|
+
return [badNdx < 0, v.map(v => f3(v))];
|
|
409
|
+
};
|
|
410
|
+
|
|
283
411
|
const strToUint32RGBRegex = /^\s*(?:0x){0,1}([0-9a-z]{1,6})\s*$/i;
|
|
284
412
|
const strToUint32RGB = s => {
|
|
285
413
|
const m = strToUint32RGBRegex.exec(s);
|
|
@@ -289,8 +417,19 @@ const strToUint32RGB = s => {
|
|
|
289
417
|
return [true, parseInt(m[1], 16)];
|
|
290
418
|
};
|
|
291
419
|
|
|
292
|
-
const
|
|
293
|
-
const
|
|
420
|
+
const strToUint32RGBARegex = /^\s*(?:0x){0,1}([0-9a-z]{1,8})\s*$/i;
|
|
421
|
+
const strToUint32RGBA = s => {
|
|
422
|
+
const m = strToUint32RGBARegex.exec(s);
|
|
423
|
+
if (!m) {
|
|
424
|
+
return [false];
|
|
425
|
+
}
|
|
426
|
+
return [true, parseInt(m[1], 16)];
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
const hex6RE = /^\s*#[a-f0-9]{6}\s*$|^\s*#[a-f0-9]{3}\s*$/i;
|
|
430
|
+
const hexNoHash6RE = /^\s*[a-f0-9]{6}\s*$/i;
|
|
431
|
+
const hex8RE = /^\s*#[a-f0-9]{8}\s*$/i;
|
|
432
|
+
const hexNoHash8RE = /^\s*[a-f0-9]{8}\s*$/i;
|
|
294
433
|
|
|
295
434
|
// For each format converter
|
|
296
435
|
//
|
|
@@ -328,7 +467,17 @@ export const colorFormatConverters = {
|
|
|
328
467
|
to: fixHex6,
|
|
329
468
|
},
|
|
330
469
|
text: {
|
|
331
|
-
from: v => [
|
|
470
|
+
from: v => [hex6RE.test(v), v.trim()],
|
|
471
|
+
to: v => v,
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
'hex8': {
|
|
475
|
+
color: {
|
|
476
|
+
from: v => [true, v],
|
|
477
|
+
to: fixHex8,
|
|
478
|
+
},
|
|
479
|
+
text: {
|
|
480
|
+
from: v => [hex8RE.test(v), v.trim()],
|
|
332
481
|
to: v => v,
|
|
333
482
|
},
|
|
334
483
|
},
|
|
@@ -338,7 +487,7 @@ export const colorFormatConverters = {
|
|
|
338
487
|
to: hex3ToHex6,
|
|
339
488
|
},
|
|
340
489
|
text: {
|
|
341
|
-
from: v => [
|
|
490
|
+
from: v => [hex6RE.test(v), hex6ToHex3(v.trim())],
|
|
342
491
|
to: v => v,
|
|
343
492
|
},
|
|
344
493
|
},
|
|
@@ -348,7 +497,17 @@ export const colorFormatConverters = {
|
|
|
348
497
|
to: v => `#${fixHex6(v)}`,
|
|
349
498
|
},
|
|
350
499
|
text: {
|
|
351
|
-
from: v => [
|
|
500
|
+
from: v => [hexNoHash6RE.test(v), v.trim()],
|
|
501
|
+
to: v => v,
|
|
502
|
+
},
|
|
503
|
+
},
|
|
504
|
+
'hex8-no-hash': {
|
|
505
|
+
color: {
|
|
506
|
+
from: v => [true, v.substring(1)],
|
|
507
|
+
to: v => `#${fixHex8(v)}`,
|
|
508
|
+
},
|
|
509
|
+
text: {
|
|
510
|
+
from: v => [hexNoHash8RE.test(v), v.trim()],
|
|
352
511
|
to: v => v,
|
|
353
512
|
},
|
|
354
513
|
},
|
|
@@ -358,7 +517,7 @@ export const colorFormatConverters = {
|
|
|
358
517
|
to: hex3ToHex6,
|
|
359
518
|
},
|
|
360
519
|
text: {
|
|
361
|
-
from: v => [
|
|
520
|
+
from: v => [hexNoHash6RE.test(v), hex6ToHex3(v.trim())],
|
|
362
521
|
to: v => v,
|
|
363
522
|
},
|
|
364
523
|
},
|
|
@@ -372,6 +531,16 @@ export const colorFormatConverters = {
|
|
|
372
531
|
to: v => `0x${v.toString(16).padStart(6, '0')}`,
|
|
373
532
|
},
|
|
374
533
|
},
|
|
534
|
+
'uint32-rgba': {
|
|
535
|
+
color: {
|
|
536
|
+
from: v => [true, hexToUint32RGBA(v)],
|
|
537
|
+
to: uint32RGBAToHex,
|
|
538
|
+
},
|
|
539
|
+
text: {
|
|
540
|
+
from: v => strToUint32RGBA(v),
|
|
541
|
+
to: v => `0x${v.toString(16).padStart(8, '0')}`,
|
|
542
|
+
},
|
|
543
|
+
},
|
|
375
544
|
'uint8-rgb': {
|
|
376
545
|
color: {
|
|
377
546
|
from: v => [true, hexToUint8RGB(v)],
|
|
@@ -382,6 +551,16 @@ export const colorFormatConverters = {
|
|
|
382
551
|
to: v => v.join(', '),
|
|
383
552
|
},
|
|
384
553
|
},
|
|
554
|
+
'uint8-rgba': {
|
|
555
|
+
color: {
|
|
556
|
+
from: v => [true, hexToUint8RGBA(v)],
|
|
557
|
+
to: uint8RGBAToHex,
|
|
558
|
+
},
|
|
559
|
+
text: {
|
|
560
|
+
from: strTo4Ints,
|
|
561
|
+
to: v => v.join(', '),
|
|
562
|
+
},
|
|
563
|
+
},
|
|
385
564
|
'float-rgb': {
|
|
386
565
|
color: {
|
|
387
566
|
from: v => [true, hexToFloatRGB(v)],
|
|
@@ -393,6 +572,61 @@ export const colorFormatConverters = {
|
|
|
393
572
|
to: v => Array.from(v).map(v => f3(v)).join(', '),
|
|
394
573
|
},
|
|
395
574
|
},
|
|
575
|
+
'float-rgba': {
|
|
576
|
+
color: {
|
|
577
|
+
from: v => [true, hexToFloatRGBA(v)],
|
|
578
|
+
to: floatRGBAToHex,
|
|
579
|
+
},
|
|
580
|
+
text: {
|
|
581
|
+
from: strTo4Floats,
|
|
582
|
+
// need Array.from because map of Float32Array makes a Float32Array
|
|
583
|
+
to: v => Array.from(v).map(v => f3(v)).join(', '),
|
|
584
|
+
},
|
|
585
|
+
},
|
|
586
|
+
'float-hsv': {
|
|
587
|
+
color: {
|
|
588
|
+
from: v => [true, rgbFloatToHSV01(hexToFloatRGB(v))],
|
|
589
|
+
to: v => hsv01ToRGBFloat(floatRGBToHex(v)),
|
|
590
|
+
},
|
|
591
|
+
text: {
|
|
592
|
+
from: strTo3Floats,
|
|
593
|
+
// need Array.from because map of Float32Array makes a Float32Array
|
|
594
|
+
to: v => Array.from(v).map(v => f3(v)).join(', '),
|
|
595
|
+
},
|
|
596
|
+
},
|
|
597
|
+
'float-hsva': {
|
|
598
|
+
color: {
|
|
599
|
+
from: v => [true, rgbaFloatToHSVA01(hexToFloatRGB(v))],
|
|
600
|
+
to: v => hsva01ToRGBAFloat(floatRGBToHex(v)),
|
|
601
|
+
},
|
|
602
|
+
text: {
|
|
603
|
+
from: strTo4Floats,
|
|
604
|
+
// need Array.from because map of Float32Array makes a Float32Array
|
|
605
|
+
to: v => Array.from(v).map(v => f3(v)).join(', '),
|
|
606
|
+
},
|
|
607
|
+
},
|
|
608
|
+
//'float-hsl': {
|
|
609
|
+
// color: {
|
|
610
|
+
// from: v => [true, rgbFloatToHsl01(hexToFloatRGB(v))],
|
|
611
|
+
// to: v => hsl01ToRGBFloat(floatRGBToHex(v)),
|
|
612
|
+
// },
|
|
613
|
+
// text: {
|
|
614
|
+
// from: strTo3Floats,
|
|
615
|
+
// // need Array.from because map of Float32Array makes a Float32Array
|
|
616
|
+
// to: v => Array.from(v).map(v => f3(v)).join(', '),
|
|
617
|
+
// },
|
|
618
|
+
//},
|
|
619
|
+
//'float-hsla': {
|
|
620
|
+
// color: {
|
|
621
|
+
// from: v => [true, hexToFloatRGBA(v)],
|
|
622
|
+
// to: floatRGBAToHex,
|
|
623
|
+
// },
|
|
624
|
+
// text: {
|
|
625
|
+
// from: strTo4Floats,
|
|
626
|
+
// // need Array.from because map of Float32Array makes a Float32Array
|
|
627
|
+
// to: v => Array.from(v).map(v => f3(v)).join(', '),
|
|
628
|
+
// },
|
|
629
|
+
//},
|
|
396
630
|
'object-rgb': {
|
|
397
631
|
color: {
|
|
398
632
|
from: v => [true, hexToObjectRGB(v)],
|
|
@@ -403,6 +637,16 @@ export const colorFormatConverters = {
|
|
|
403
637
|
to: rgbObjectToStr,
|
|
404
638
|
},
|
|
405
639
|
},
|
|
640
|
+
'object-rgba': {
|
|
641
|
+
color: {
|
|
642
|
+
from: v => [true, hexToObjectRGBA(v)],
|
|
643
|
+
to: objectRGBAToHex,
|
|
644
|
+
},
|
|
645
|
+
text: {
|
|
646
|
+
from: strToRGBAObject,
|
|
647
|
+
to: rgbaObjectToStr,
|
|
648
|
+
},
|
|
649
|
+
},
|
|
406
650
|
'css-rgb': {
|
|
407
651
|
color: {
|
|
408
652
|
from: v => [true, hexToCssRGB(v)],
|
|
@@ -413,6 +657,16 @@ export const colorFormatConverters = {
|
|
|
413
657
|
to: v => strToCssRGB(v)[1],
|
|
414
658
|
},
|
|
415
659
|
},
|
|
660
|
+
'css-rgba': {
|
|
661
|
+
color: {
|
|
662
|
+
from: v => [true, hexToCssRGBA(v)],
|
|
663
|
+
to: cssRGBAToHex,
|
|
664
|
+
},
|
|
665
|
+
text: {
|
|
666
|
+
from: strToCssRGBA,
|
|
667
|
+
to: v => strToCssRGBA(v)[1],
|
|
668
|
+
},
|
|
669
|
+
},
|
|
416
670
|
'css-hsl': {
|
|
417
671
|
color: {
|
|
418
672
|
from: v => [true, hexToCssHSL(v)],
|
|
@@ -423,4 +677,14 @@ export const colorFormatConverters = {
|
|
|
423
677
|
to: v => strToCssHSL(v)[1],
|
|
424
678
|
},
|
|
425
679
|
},
|
|
680
|
+
'css-hsla': {
|
|
681
|
+
color: {
|
|
682
|
+
from: v => [true, hexToCssHSLA(v)],
|
|
683
|
+
to: cssHSLAToHex,
|
|
684
|
+
},
|
|
685
|
+
text: {
|
|
686
|
+
from: strToCssHSLA,
|
|
687
|
+
to: v => strToCssHSLA(v)[1],
|
|
688
|
+
},
|
|
689
|
+
},
|
|
426
690
|
};
|
package/src/libs/elem.js
CHANGED
|
@@ -29,4 +29,9 @@ export function addElem(tag, parent, attrs = {}, children = []) {
|
|
|
29
29
|
const elem = createElem(tag, attrs, children);
|
|
30
30
|
parent.appendChild(elem);
|
|
31
31
|
return elem;
|
|
32
|
-
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let nextId = 0;
|
|
35
|
+
export function getNewId() {
|
|
36
|
+
return `muigui-id-${nextId++}`;
|
|
37
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const darkColors = {
|
|
2
|
+
main: '#ddd',
|
|
3
|
+
};
|
|
4
|
+
const lightColors = {
|
|
5
|
+
main: '#333',
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const darkMatcher = window.matchMedia('(prefers-color-scheme: dark)');
|
|
9
|
+
|
|
10
|
+
let colors;
|
|
11
|
+
let isDarkMode;
|
|
12
|
+
|
|
13
|
+
function update() {
|
|
14
|
+
isDarkMode = darkMatcher.matches;
|
|
15
|
+
colors = isDarkMode ? darkColors : lightColors;
|
|
16
|
+
}
|
|
17
|
+
darkMatcher.addEventListener('change', update);
|
|
18
|
+
update();
|
|
19
|
+
|
|
20
|
+
export function graph(canvas, data, {
|
|
21
|
+
min = -1,
|
|
22
|
+
max = 1,
|
|
23
|
+
interval = 16,
|
|
24
|
+
color,
|
|
25
|
+
}) {
|
|
26
|
+
const ctx = canvas.getContext('2d');
|
|
27
|
+
|
|
28
|
+
function render() {
|
|
29
|
+
const {width, height} = canvas;
|
|
30
|
+
ctx.clearRect(0, 0, width, height);
|
|
31
|
+
ctx.beginPath();
|
|
32
|
+
const range = max - min;
|
|
33
|
+
for (let i = 0; i < data.length; ++i) {
|
|
34
|
+
const x = i * width / data.length;
|
|
35
|
+
const y = (data[i] - min) * height / range;
|
|
36
|
+
ctx.lineTo(x, y);
|
|
37
|
+
}
|
|
38
|
+
ctx.strokeStyle = color || colors.main;
|
|
39
|
+
ctx.stroke();
|
|
40
|
+
}
|
|
41
|
+
setInterval(render, interval);
|
|
42
|
+
}
|
package/src/libs/keyboard.js
CHANGED
|
@@ -10,7 +10,7 @@ const keyDirections = {
|
|
|
10
10
|
|
|
11
11
|
// This probably needs to be global
|
|
12
12
|
export function addKeyboardEvents(elem, {onDown = noop, onUp = noop}) {
|
|
13
|
-
const keyDown = function(event) {
|
|
13
|
+
const keyDown = function (event) {
|
|
14
14
|
const mult = event.shiftKey ? 10 : 1;
|
|
15
15
|
const [dx, dy] = (keyDirections[event.key] || [0, 0]).map(v => v * mult);
|
|
16
16
|
const fn = event.type === 'keydown' ? onDown : onUp;
|
|
@@ -25,7 +25,7 @@ export function addKeyboardEvents(elem, {onDown = noop, onUp = noop}) {
|
|
|
25
25
|
elem.addEventListener('keydown', keyDown);
|
|
26
26
|
elem.addEventListener('keyup', keyDown);
|
|
27
27
|
|
|
28
|
-
return function() {
|
|
28
|
+
return function () {
|
|
29
29
|
elem.removeEventListener('keydown', keyDown);
|
|
30
30
|
elem.removeEventListener('keyup', keyDown);
|
|
31
31
|
};
|
package/src/libs/touch.js
CHANGED
|
@@ -17,7 +17,7 @@ export function computeRelativePosition(elem, event, start) {
|
|
|
17
17
|
|
|
18
18
|
export function addTouchEvents(elem, {onDown = noop, onMove = noop, onUp = noop}) {
|
|
19
19
|
let start;
|
|
20
|
-
const pointerMove = function(event) {
|
|
20
|
+
const pointerMove = function (event) {
|
|
21
21
|
const e = {
|
|
22
22
|
type: 'move',
|
|
23
23
|
...computeRelativePosition(elem, event, start),
|
|
@@ -25,7 +25,7 @@ export function addTouchEvents(elem, {onDown = noop, onMove = noop, onUp = noop}
|
|
|
25
25
|
onMove(e);
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
const pointerUp = function(event) {
|
|
28
|
+
const pointerUp = function (event) {
|
|
29
29
|
elem.releasePointerCapture(event.pointerId);
|
|
30
30
|
elem.removeEventListener('pointermove', pointerMove);
|
|
31
31
|
elem.removeEventListener('pointerup', pointerUp);
|
|
@@ -35,7 +35,7 @@ export function addTouchEvents(elem, {onDown = noop, onMove = noop, onUp = noop}
|
|
|
35
35
|
onUp('up');
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
const pointerDown = function(event) {
|
|
38
|
+
const pointerDown = function (event) {
|
|
39
39
|
elem.addEventListener('pointermove', pointerMove);
|
|
40
40
|
elem.addEventListener('pointerup', pointerUp);
|
|
41
41
|
elem.setPointerCapture(event.pointerId);
|
|
@@ -50,7 +50,7 @@ export function addTouchEvents(elem, {onDown = noop, onMove = noop, onUp = noop}
|
|
|
50
50
|
|
|
51
51
|
elem.addEventListener('pointerdown', pointerDown);
|
|
52
52
|
|
|
53
|
-
return function() {
|
|
53
|
+
return function () {
|
|
54
54
|
elem.removeEventListener('pointerdown', pointerDown);
|
|
55
55
|
};
|
|
56
56
|
}
|
package/src/libs/wheel.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export function createWheelHelper() {
|
|
2
2
|
let wheelAccum = 0;
|
|
3
|
-
return function(e, step, wheelScale = 5) {
|
|
3
|
+
return function (e, step, wheelScale = 5) {
|
|
4
4
|
wheelAccum -= e.deltaY * step / wheelScale;
|
|
5
5
|
const wheelSteps = Math.floor(Math.abs(wheelAccum) / step) * Math.sign(wheelAccum);
|
|
6
6
|
const delta = wheelSteps * step;
|
package/src/muigui.js
CHANGED
|
@@ -61,6 +61,10 @@ export class GUIFolder extends Folder {
|
|
|
61
61
|
addLabel(text) {
|
|
62
62
|
return this.addController(new Label(text));
|
|
63
63
|
}
|
|
64
|
+
addButton(name, fn) {
|
|
65
|
+
const o = {fn};
|
|
66
|
+
return this.add(o, 'fn').name(name);
|
|
67
|
+
}
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
class MuiguiElement extends HTMLElement {
|
|
@@ -73,7 +77,7 @@ class MuiguiElement extends HTMLElement {
|
|
|
73
77
|
customElements.define('muigui-element', MuiguiElement);
|
|
74
78
|
|
|
75
79
|
const baseStyleSheet = new CSSStyleSheet();
|
|
76
|
-
baseStyleSheet.replaceSync(css.default);
|
|
80
|
+
//baseStyleSheet.replaceSync(css.default);
|
|
77
81
|
const userStyleSheet = new CSSStyleSheet();
|
|
78
82
|
|
|
79
83
|
function makeStyleSheetUpdater(styleSheet) {
|
|
@@ -100,6 +104,11 @@ function makeStyleSheetUpdater(styleSheet) {
|
|
|
100
104
|
const updateBaseStyle = makeStyleSheetUpdater(baseStyleSheet);
|
|
101
105
|
const updateUserStyle = makeStyleSheetUpdater(userStyleSheet);
|
|
102
106
|
|
|
107
|
+
function getTheme(name) {
|
|
108
|
+
const { include, css: cssStr } = css.themes[name];
|
|
109
|
+
return `${include.map(m => css[m]).join('\n')} : css.default}\n${cssStr || ''}`;
|
|
110
|
+
}
|
|
111
|
+
|
|
103
112
|
export class GUI extends GUIFolder {
|
|
104
113
|
static converters = converters;
|
|
105
114
|
static mapRange = mapRange;
|
|
@@ -131,13 +140,14 @@ export class GUI extends GUIFolder {
|
|
|
131
140
|
}
|
|
132
141
|
if (parent) {
|
|
133
142
|
const muiguiElement = createElem('muigui-element');
|
|
134
|
-
muiguiElement.shadowRoot.adoptedStyleSheets = [baseStyleSheet, userStyleSheet
|
|
143
|
+
muiguiElement.shadowRoot.adoptedStyleSheets = [this.#localStyleSheet, baseStyleSheet, userStyleSheet];
|
|
135
144
|
muiguiElement.shadow.appendChild(this.domElement);
|
|
136
145
|
parent.appendChild(muiguiElement);
|
|
137
146
|
}
|
|
138
147
|
if (title) {
|
|
139
148
|
this.title(title);
|
|
140
149
|
}
|
|
150
|
+
this.#localStyleSheet.replaceSync(css.default);
|
|
141
151
|
this.domElement.classList.add('muigui', 'muigui-colors');
|
|
142
152
|
}
|
|
143
153
|
setStyle(css) {
|
|
@@ -155,8 +165,11 @@ export class GUI extends GUIFolder {
|
|
|
155
165
|
static getUserStyleSheet() {
|
|
156
166
|
return userStyleSheet;
|
|
157
167
|
}
|
|
168
|
+
setTheme(name) {
|
|
169
|
+
this.setStyle(getTheme(name));
|
|
170
|
+
}
|
|
158
171
|
static setTheme(name) {
|
|
159
|
-
GUI.setBaseStyles(
|
|
172
|
+
GUI.setBaseStyles(getTheme(name));
|
|
160
173
|
}
|
|
161
174
|
}
|
|
162
175
|
|