muigui 0.0.6 → 0.0.12
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 +19 -4
- package/src/controllers/ColorChooser.js +43 -3
- package/src/controllers/Container.js +8 -2
- package/src/controllers/Controller.js +3 -0
- package/src/controllers/PopDownController.js +14 -13
- package/src/controllers/ValueController.js +15 -7
- package/src/controllers/Vec2.js +0 -1
- package/src/layout/Layout.js +0 -1
- package/src/libs/color-utils.js +252 -12
- package/src/libs/elem.js +6 -1
- package/src/libs/keyboard.js +2 -2
- package/src/libs/touch.js +6 -6
- package/src/libs/utils.js +31 -0
- package/src/libs/wheel.js +1 -1
- package/src/muigui.js +75 -12
- package/src/styles/muigui.css.js +78 -4
- package/src/views/CheckboxView.js +3 -1
- package/src/views/ColorChooserView.js +128 -35
- package/src/views/RadioGridView.js +3 -2
- package/src/views/RangeView.js +10 -4
- package/src/views/{View.js → View.ts} +15 -13
- /package/src/{esm.js → esm.ts} +0 -0
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,12 +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
|
};
|
|
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
|
+
};
|
|
37
67
|
|
|
38
68
|
const hexToCssHSL = v => {
|
|
39
69
|
const hsl = rgbUint8ToHsl(hexToUint8RGB(v)).map(v => f0(v));
|
|
40
70
|
return `hsl(${hsl[0]}, ${hsl[1]}%, ${hsl[2]}%)`;
|
|
41
71
|
};
|
|
42
|
-
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*$/;
|
|
43
78
|
|
|
44
79
|
const hex3DigitTo6Digit = v => `${v[0]}${v[0]}${v[1]}${v[1]}${v[2]}${v[2]}`;
|
|
45
80
|
const cssHSLToHex = v => {
|
|
@@ -47,6 +82,11 @@ const cssHSLToHex = v => {
|
|
|
47
82
|
const rgb = hslToRgbUint8([m[1], m[2], m[3]].map(v => parseFloat(v)));
|
|
48
83
|
return uint8RGBToHex(rgb);
|
|
49
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
|
+
};
|
|
50
90
|
|
|
51
91
|
const euclideanModulo = (v, n) => ((v % n) + n) % n;
|
|
52
92
|
|
|
@@ -65,6 +105,11 @@ export function hslToRgbUint8([h, s, l]) {
|
|
|
65
105
|
return [f(0), f(8), f(4)].map(v => Math.round(v * 255));
|
|
66
106
|
}
|
|
67
107
|
|
|
108
|
+
export function hslaToRgbaUint8([h, s, l, a]) {
|
|
109
|
+
const rgb = hslToRgbUint8([h, s, l]);
|
|
110
|
+
return [...rgb, a * 255 | 0];
|
|
111
|
+
}
|
|
112
|
+
|
|
68
113
|
export function rgbFloatToHsl01([r, g, b]) {
|
|
69
114
|
const max = Math.max(r, g, b);
|
|
70
115
|
const min = Math.min(r, g, b);
|
|
@@ -88,11 +133,21 @@ export function rgbFloatToHsl01([r, g, b]) {
|
|
|
88
133
|
return [h / 6, s, l];
|
|
89
134
|
}
|
|
90
135
|
|
|
136
|
+
export function rgbaFloatToHsla01([r, g, b, a]) {
|
|
137
|
+
const hsl = rgbFloatToHsl01([r, g, b]);
|
|
138
|
+
return [...hsl, a];
|
|
139
|
+
}
|
|
140
|
+
|
|
91
141
|
export const rgbUint8ToHsl = (rgb) => {
|
|
92
142
|
const [h, s, l] = rgbFloatToHsl01(rgb.map(v => v / 255));
|
|
93
143
|
return [h * 360, s * 100, l * 100];
|
|
94
144
|
};
|
|
95
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
|
+
|
|
96
151
|
export function hsv01ToRGBFloat([hue, sat, val]) {
|
|
97
152
|
sat = clamp(sat, 0, 1);
|
|
98
153
|
val = clamp(val, 0, 1);
|
|
@@ -101,6 +156,11 @@ export function hsv01ToRGBFloat([hue, sat, val]) {
|
|
|
101
156
|
);
|
|
102
157
|
}
|
|
103
158
|
|
|
159
|
+
export function hsva01ToRGBAFloat([hue, sat, val, alpha]) {
|
|
160
|
+
const rgb = hsv01ToRGBFloat([hue, sat, val]);
|
|
161
|
+
return [...rgb, alpha];
|
|
162
|
+
}
|
|
163
|
+
|
|
104
164
|
const round3 = v => Math.round(v * 1000) / 1000;
|
|
105
165
|
|
|
106
166
|
export function rgbFloatToHSV01([r, g, b]) {
|
|
@@ -118,16 +178,28 @@ export function rgbFloatToHSV01([r, g, b]) {
|
|
|
118
178
|
].map(round3);
|
|
119
179
|
}
|
|
120
180
|
|
|
121
|
-
|
|
122
|
-
|
|
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;
|
|
188
|
+
|
|
189
|
+
// Yea, meh!
|
|
190
|
+
export const hasAlpha = format => format.endsWith('a') || format.startsWith('hex8');
|
|
123
191
|
|
|
124
192
|
const cssStringFormats = [
|
|
125
193
|
{ re: /^#(?:[0-9a-f]){6}$/i, format: 'hex6' },
|
|
126
194
|
{ re: /^(?:[0-9a-f]){6}$/i, format: 'hex6-no-hash' },
|
|
195
|
+
{ re: /^#(?:[0-9a-f]){8}$/i, format: 'hex8' },
|
|
196
|
+
{ re: /^(?:[0-9a-f]){8}$/i, format: 'hex8-no-hash' },
|
|
127
197
|
{ re: /^#(?:[0-9a-f]){3}$/i, format: 'hex3' },
|
|
128
198
|
{ re: /^(?:[0-9a-f]){3}$/i, format: 'hex3-no-hash' },
|
|
129
199
|
{ re: cssRGBRegex, format: 'css-rgb' },
|
|
130
200
|
{ re: cssHSLRegex, format: 'css-hsl' },
|
|
201
|
+
{ re: cssRGBARegex, format: 'css-rgba' },
|
|
202
|
+
{ re: cssHSLARegex, format: 'css-hsla' },
|
|
131
203
|
];
|
|
132
204
|
|
|
133
205
|
function guessStringColorFormat(v) {
|
|
@@ -142,7 +214,8 @@ function guessStringColorFormat(v) {
|
|
|
142
214
|
export function guessFormat(v) {
|
|
143
215
|
switch (typeof v) {
|
|
144
216
|
case 'number':
|
|
145
|
-
|
|
217
|
+
console.warn('can not reliably guess format based on a number. You should pass in a format like {format: "uint32-rgb"} or {format: "uint32-rgb"}');
|
|
218
|
+
return v <= 0xFFFFFF ? 'uint32-rgb' : 'uint32-rgba';
|
|
146
219
|
case 'string': {
|
|
147
220
|
const formatInfo = guessStringColorFormat(v.trim());
|
|
148
221
|
if (formatInfo) {
|
|
@@ -154,18 +227,28 @@ export function guessFormat(v) {
|
|
|
154
227
|
if (v instanceof Uint8Array || v instanceof Uint8ClampedArray) {
|
|
155
228
|
if (v.length === 3) {
|
|
156
229
|
return 'uint8-rgb';
|
|
230
|
+
} else if (v.length === 4) {
|
|
231
|
+
return 'uint8-rgba';
|
|
157
232
|
}
|
|
158
233
|
} else if (v instanceof Float32Array) {
|
|
159
234
|
if (v.length === 3) {
|
|
160
235
|
return 'float-rgb';
|
|
236
|
+
} else if (v.length === 4) {
|
|
237
|
+
return 'float-rgba';
|
|
161
238
|
}
|
|
162
239
|
} else if (Array.isArray(v)) {
|
|
163
240
|
if (v.length === 3) {
|
|
164
241
|
return 'float-rgb';
|
|
242
|
+
} else if (v.length === 4) {
|
|
243
|
+
return 'float-rgba';
|
|
165
244
|
}
|
|
166
245
|
} else {
|
|
167
246
|
if ('r' in v && 'g' in v && 'b' in v) {
|
|
168
|
-
|
|
247
|
+
if ('a' in v) {
|
|
248
|
+
return 'object-rgba';
|
|
249
|
+
} else {
|
|
250
|
+
return 'object-rgb';
|
|
251
|
+
}
|
|
169
252
|
}
|
|
170
253
|
}
|
|
171
254
|
}
|
|
@@ -179,6 +262,13 @@ function fixHex6(v) {
|
|
|
179
262
|
//return fix(v.trim());
|
|
180
263
|
}
|
|
181
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
|
+
|
|
182
272
|
function hex6ToHex3(hex6) {
|
|
183
273
|
return (hex6[1] === hex6[2] &&
|
|
184
274
|
hex6[3] === hex6[4] &&
|
|
@@ -214,6 +304,19 @@ const strToRGBObject = (s) => {
|
|
|
214
304
|
}
|
|
215
305
|
};
|
|
216
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
|
+
|
|
217
320
|
const strToCssRGB = s => {
|
|
218
321
|
const m = cssRGBRegex.exec(s);
|
|
219
322
|
if (!m) {
|
|
@@ -224,6 +327,16 @@ const strToCssRGB = s => {
|
|
|
224
327
|
return [!outOfRange, `rgb(${v.join(', ')})`];
|
|
225
328
|
};
|
|
226
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
|
+
|
|
227
340
|
const strToCssHSL = s => {
|
|
228
341
|
const m = cssHSLRegex.exec(s);
|
|
229
342
|
if (!m) {
|
|
@@ -234,9 +347,22 @@ const strToCssHSL = s => {
|
|
|
234
347
|
return [!outOfRange, `hsl(${v[0]}, ${v[1]}%, ${v[2]}%)`];
|
|
235
348
|
};
|
|
236
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
|
+
|
|
237
360
|
const rgbObjectToStr = rgb => {
|
|
238
361
|
return `{r:${f3(rgb.r)}, g:${f3(rgb.g)}, b:${f3(rgb.b)}}`;
|
|
239
362
|
};
|
|
363
|
+
const rgbaObjectToStr = rgba => {
|
|
364
|
+
return `{r:${f3(rgba.r)}, g:${f3(rgba.g)}, b:${f3(rgba.b)}}, a:${f3(rgba.a)}}`;
|
|
365
|
+
};
|
|
240
366
|
|
|
241
367
|
const strTo3IntsRE = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*$/;
|
|
242
368
|
const strTo3Ints = s => {
|
|
@@ -249,6 +375,17 @@ const strTo3Ints = s => {
|
|
|
249
375
|
return [!outOfRange, v];
|
|
250
376
|
};
|
|
251
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
|
+
|
|
252
389
|
const strTo3Floats = s => {
|
|
253
390
|
const numbers = s.split(',').map(s => s.trim());
|
|
254
391
|
const v = numbers.map(v => parseFloat(v));
|
|
@@ -260,6 +397,17 @@ const strTo3Floats = s => {
|
|
|
260
397
|
return [badNdx < 0, v.map(v => f3(v))];
|
|
261
398
|
};
|
|
262
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
|
+
|
|
263
411
|
const strToUint32RGBRegex = /^\s*(?:0x){0,1}([0-9a-z]{1,6})\s*$/i;
|
|
264
412
|
const strToUint32RGB = s => {
|
|
265
413
|
const m = strToUint32RGBRegex.exec(s);
|
|
@@ -269,8 +417,19 @@ const strToUint32RGB = s => {
|
|
|
269
417
|
return [true, parseInt(m[1], 16)];
|
|
270
418
|
};
|
|
271
419
|
|
|
272
|
-
const
|
|
273
|
-
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;
|
|
274
433
|
|
|
275
434
|
// For each format converter
|
|
276
435
|
//
|
|
@@ -308,7 +467,17 @@ export const colorFormatConverters = {
|
|
|
308
467
|
to: fixHex6,
|
|
309
468
|
},
|
|
310
469
|
text: {
|
|
311
|
-
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()],
|
|
312
481
|
to: v => v,
|
|
313
482
|
},
|
|
314
483
|
},
|
|
@@ -318,7 +487,7 @@ export const colorFormatConverters = {
|
|
|
318
487
|
to: hex3ToHex6,
|
|
319
488
|
},
|
|
320
489
|
text: {
|
|
321
|
-
from: v => [
|
|
490
|
+
from: v => [hex6RE.test(v), hex6ToHex3(v.trim())],
|
|
322
491
|
to: v => v,
|
|
323
492
|
},
|
|
324
493
|
},
|
|
@@ -328,7 +497,17 @@ export const colorFormatConverters = {
|
|
|
328
497
|
to: v => `#${fixHex6(v)}`,
|
|
329
498
|
},
|
|
330
499
|
text: {
|
|
331
|
-
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()],
|
|
332
511
|
to: v => v,
|
|
333
512
|
},
|
|
334
513
|
},
|
|
@@ -338,7 +517,7 @@ export const colorFormatConverters = {
|
|
|
338
517
|
to: hex3ToHex6,
|
|
339
518
|
},
|
|
340
519
|
text: {
|
|
341
|
-
from: v => [
|
|
520
|
+
from: v => [hexNoHash6RE.test(v), hex6ToHex3(v.trim())],
|
|
342
521
|
to: v => v,
|
|
343
522
|
},
|
|
344
523
|
},
|
|
@@ -352,6 +531,16 @@ export const colorFormatConverters = {
|
|
|
352
531
|
to: v => `0x${v.toString(16).padStart(6, '0')}`,
|
|
353
532
|
},
|
|
354
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
|
+
},
|
|
355
544
|
'uint8-rgb': {
|
|
356
545
|
color: {
|
|
357
546
|
from: v => [true, hexToUint8RGB(v)],
|
|
@@ -362,6 +551,16 @@ export const colorFormatConverters = {
|
|
|
362
551
|
to: v => v.join(', '),
|
|
363
552
|
},
|
|
364
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
|
+
},
|
|
365
564
|
'float-rgb': {
|
|
366
565
|
color: {
|
|
367
566
|
from: v => [true, hexToFloatRGB(v)],
|
|
@@ -373,6 +572,17 @@ export const colorFormatConverters = {
|
|
|
373
572
|
to: v => Array.from(v).map(v => f3(v)).join(', '),
|
|
374
573
|
},
|
|
375
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
|
+
},
|
|
376
586
|
'object-rgb': {
|
|
377
587
|
color: {
|
|
378
588
|
from: v => [true, hexToObjectRGB(v)],
|
|
@@ -383,6 +593,16 @@ export const colorFormatConverters = {
|
|
|
383
593
|
to: rgbObjectToStr,
|
|
384
594
|
},
|
|
385
595
|
},
|
|
596
|
+
'object-rgba': {
|
|
597
|
+
color: {
|
|
598
|
+
from: v => [true, hexToObjectRGBA(v)],
|
|
599
|
+
to: objectRGBAToHex,
|
|
600
|
+
},
|
|
601
|
+
text: {
|
|
602
|
+
from: strToRGBAObject,
|
|
603
|
+
to: rgbaObjectToStr,
|
|
604
|
+
},
|
|
605
|
+
},
|
|
386
606
|
'css-rgb': {
|
|
387
607
|
color: {
|
|
388
608
|
from: v => [true, hexToCssRGB(v)],
|
|
@@ -393,6 +613,16 @@ export const colorFormatConverters = {
|
|
|
393
613
|
to: v => strToCssRGB(v)[1],
|
|
394
614
|
},
|
|
395
615
|
},
|
|
616
|
+
'css-rgba': {
|
|
617
|
+
color: {
|
|
618
|
+
from: v => [true, hexToCssRGBA(v)],
|
|
619
|
+
to: cssRGBAToHex,
|
|
620
|
+
},
|
|
621
|
+
text: {
|
|
622
|
+
from: strToCssRGBA,
|
|
623
|
+
to: v => strToCssRGBA(v)[1],
|
|
624
|
+
},
|
|
625
|
+
},
|
|
396
626
|
'css-hsl': {
|
|
397
627
|
color: {
|
|
398
628
|
from: v => [true, hexToCssHSL(v)],
|
|
@@ -403,4 +633,14 @@ export const colorFormatConverters = {
|
|
|
403
633
|
to: v => strToCssHSL(v)[1],
|
|
404
634
|
},
|
|
405
635
|
},
|
|
636
|
+
'css-hsla': {
|
|
637
|
+
color: {
|
|
638
|
+
from: v => [true, hexToCssHSLA(v)],
|
|
639
|
+
to: cssHSLAToHex,
|
|
640
|
+
},
|
|
641
|
+
text: {
|
|
642
|
+
from: strToCssHSLA,
|
|
643
|
+
to: v => strToCssHSLA(v)[1],
|
|
644
|
+
},
|
|
645
|
+
},
|
|
406
646
|
};
|
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
|
+
}
|
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,17 +25,17 @@ 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);
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
document.body.style.backgroundColor = '';
|
|
34
|
-
|
|
34
|
+
|
|
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/utils.js
CHANGED
|
@@ -72,3 +72,34 @@ export const makeRangeOptions = ({from, to, step}) => {
|
|
|
72
72
|
};
|
|
73
73
|
};
|
|
74
74
|
|
|
75
|
+
// TODO: remove an use one in conversions. Move makeRangeConverters there?
|
|
76
|
+
export const identity = {
|
|
77
|
+
to: v => v,
|
|
78
|
+
from: v => [true, v],
|
|
79
|
+
};
|
|
80
|
+
export function makeMinMaxPair(gui, properties, minPropName, maxPropName, options) {
|
|
81
|
+
const { converters: { from } = identity } = options;
|
|
82
|
+
const { min, max } = options;
|
|
83
|
+
const guiMinRange = options.minRange || 0;
|
|
84
|
+
const valueMinRange = from(guiMinRange)[1];
|
|
85
|
+
const minGui = gui
|
|
86
|
+
.add(properties, minPropName, {
|
|
87
|
+
...options,
|
|
88
|
+
min,
|
|
89
|
+
max: max - guiMinRange,
|
|
90
|
+
})
|
|
91
|
+
.onChange(v => {
|
|
92
|
+
maxGui.setValue(Math.min(max, Math.max(v + valueMinRange, properties[maxPropName])));
|
|
93
|
+
});
|
|
94
|
+
const maxGui = gui
|
|
95
|
+
.add(properties, maxPropName, {
|
|
96
|
+
...options,
|
|
97
|
+
min: min + guiMinRange,
|
|
98
|
+
max,
|
|
99
|
+
})
|
|
100
|
+
.onChange(v => {
|
|
101
|
+
minGui.setValue(Math.max(min, Math.min(v - valueMinRange, properties[minPropName])));
|
|
102
|
+
});
|
|
103
|
+
return [ minGui, maxGui ];
|
|
104
|
+
}
|
|
105
|
+
|
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;
|