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/styles/muigui.css.js
CHANGED
|
@@ -10,16 +10,24 @@ export default {
|
|
|
10
10
|
--menu-bg-color: #f8f8f8;
|
|
11
11
|
--menu-sep-color: #bbb;
|
|
12
12
|
--hover-bg-color: #999;
|
|
13
|
-
--focus-color: #
|
|
14
|
-
--range-color: #
|
|
13
|
+
--focus-color: #8BF;
|
|
14
|
+
--range-color: #AAA;
|
|
15
15
|
--invalid-color: #FF0000;
|
|
16
16
|
--selected-color: rgb(255, 255, 255, 0.9);
|
|
17
17
|
|
|
18
18
|
--button-bg-color: var(--value-bg-color);
|
|
19
19
|
|
|
20
|
+
--image-open: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxyZWN0IHN0eWxlPSJmaWxsOiAjNDQ0OyIgeD0iMjAlIiB5PSI0NSUiIHdpZHRoPSI2MCUiIGhlaWdodD0iMTAlIj48L3JlY3Q+Cjwvc3ZnPg==);
|
|
21
|
+
--image-closed: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxyZWN0IHN0eWxlPSJmaWxsOiAjNDQ0OyIgeD0iNDUlIiB5PSIyMCUiIHdpZHRoPSIxMCUiIGhlaWdodD0iNjAlIj48L3JlY3Q+CiAgPHJlY3Qgc3R5bGU9ImZpbGw6ICM0NDQ7IiB4PSIyMCUiIHk9IjQ1JSIgd2lkdGg9IjYwJSIgaGVpZ2h0PSIxMCUiPjwvcmVjdD4KPC9zdmc+);
|
|
22
|
+
--image-checkerboard: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxyZWN0IHN0eWxlPSJmaWxsOiAjNDA0MDQwOyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSI+PC9yZWN0PgogIDxyZWN0IHN0eWxlPSJmaWxsOiAjODA4MDgwOyIgeD0iMCIgeT0iMCIgd2lkdGg9IjUwJSIgaGVpZ2h0PSI1MCUiPjwvcmVjdD4KICA8cmVjdCBzdHlsZT0iZmlsbDogIzgwODA4MDsiIHg9IjUwJSIgeT0iNTAlIiB3aWR0aD0iNTAlIiBoZWlnaHQ9IjUwJSI+PC9yZWN0Pgo8L3N2Zz4=);
|
|
23
|
+
|
|
20
24
|
--range-left-color: var(--value-color);
|
|
21
25
|
--range-right-color: var(--value-bg-color);
|
|
22
26
|
--range-right-hover-color: var(--hover-bg-color);
|
|
27
|
+
--button-image:
|
|
28
|
+
linear-gradient(
|
|
29
|
+
rgba(255, 255, 255, 1), rgba(0, 0, 0, 0.2)
|
|
30
|
+
);
|
|
23
31
|
|
|
24
32
|
color: var(--color);
|
|
25
33
|
background-color: var(--bg-color);
|
|
@@ -36,7 +44,7 @@ export default {
|
|
|
36
44
|
--menu-bg-color: #080808;
|
|
37
45
|
--menu-sep-color: #444444;
|
|
38
46
|
--hover-bg-color: #666666;
|
|
39
|
-
--focus-color: #88AAFF
|
|
47
|
+
--focus-color: #458; /*#88AAFF*/;
|
|
40
48
|
--range-color: #888888;
|
|
41
49
|
--invalid-color: #FF6666;
|
|
42
50
|
--selected-color: rgba(255, 255, 255, 0.3);
|
|
@@ -46,9 +54,15 @@ export default {
|
|
|
46
54
|
--range-left-color: var(--value-color);
|
|
47
55
|
--range-right-color: var(--value-bg-color);
|
|
48
56
|
--range-right-hover-color: var(--hover-bg-color);
|
|
57
|
+
--button-image: linear-gradient(
|
|
58
|
+
rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.4)
|
|
59
|
+
);
|
|
49
60
|
|
|
50
61
|
color: var(--color);
|
|
51
62
|
background-color: var(--bg-color);
|
|
63
|
+
|
|
64
|
+
--image-closed: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxyZWN0IHN0eWxlPSJmaWxsOiAjREREOyIgeD0iMjAlIiB5PSI0NSUiIHdpZHRoPSI2MCUiIGhlaWdodD0iMTAlIj48L3JlY3Q+Cjwvc3ZnPg==);
|
|
65
|
+
--image-open: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxyZWN0IHN0eWxlPSJmaWxsOiAjREREOyIgeD0iNDUlIiB5PSIyMCUiIHdpZHRoPSIxMCUiIGhlaWdodD0iNjAlIj48L3JlY3Q+CiAgPHJlY3Qgc3R5bGU9ImZpbGw6ICNEREQ7IiB4PSIyMCUiIHk9IjQ1JSIgd2lkdGg9IjYwJSIgaGVpZ2h0PSIxMCUiPjwvcmVjdD4KPC9zdmc+);
|
|
52
66
|
}
|
|
53
67
|
}
|
|
54
68
|
|
|
@@ -57,7 +71,6 @@ export default {
|
|
|
57
71
|
--label-width: 45%;
|
|
58
72
|
--number-width: 40%;
|
|
59
73
|
|
|
60
|
-
|
|
61
74
|
--font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
|
|
62
75
|
--font-size: 11px;
|
|
63
76
|
--font-family-mono: Menlo, Monaco, Consolas, "Droid Sans Mono", monospace;
|
|
@@ -150,6 +163,9 @@ export default {
|
|
|
150
163
|
min-width: 0;
|
|
151
164
|
min-height: var(--line-height);
|
|
152
165
|
}
|
|
166
|
+
.muigui-root {
|
|
167
|
+
z-index: 1;
|
|
168
|
+
}
|
|
153
169
|
.muigui-root,
|
|
154
170
|
.muigui-menu {
|
|
155
171
|
display: flex;
|
|
@@ -174,8 +190,7 @@ export default {
|
|
|
174
190
|
color: var(--color);
|
|
175
191
|
background-color: var(--menu-bg-color);
|
|
176
192
|
min-height: var(--line-height);
|
|
177
|
-
padding
|
|
178
|
-
padding-bottom: 0.2em;
|
|
193
|
+
padding: 0.2em;
|
|
179
194
|
cursor: pointer;
|
|
180
195
|
border-radius: var(--border-radius);
|
|
181
196
|
}
|
|
@@ -196,7 +211,7 @@ export default {
|
|
|
196
211
|
.muigui-controller>*:nth-child(1) {
|
|
197
212
|
flex: 1 0 var(--label-width);
|
|
198
213
|
min-width: 0;
|
|
199
|
-
white-space: pre;
|
|
214
|
+
/* white-space: pre; why?? */
|
|
200
215
|
}
|
|
201
216
|
.muigui-controller>label:nth-child(1) {
|
|
202
217
|
place-content: center start;
|
|
@@ -238,32 +253,41 @@ export default {
|
|
|
238
253
|
/* fix! */
|
|
239
254
|
.muigui-open>button>label::before,
|
|
240
255
|
.muigui-closed>button>label::before {
|
|
256
|
+
content: "X";
|
|
257
|
+
color: rgba(0, 0, 0, 0);
|
|
258
|
+
background-color: var(--range-color);
|
|
259
|
+
border-radius: 0.2em;
|
|
241
260
|
width: 1.25em;
|
|
242
|
-
|
|
261
|
+
margin-right: 0.25em;
|
|
262
|
+
height: 1.25em; /*var(--line-height);*/
|
|
243
263
|
display: inline-grid;
|
|
244
264
|
place-content: center start;
|
|
245
265
|
pointer-events: none;
|
|
246
266
|
}
|
|
247
267
|
.muigui-open>button>label::before {
|
|
248
|
-
|
|
268
|
+
background-image: var(--image-open);
|
|
249
269
|
}
|
|
250
270
|
.muigui-closed>button>label::before {
|
|
251
|
-
|
|
271
|
+
background-image: var(--image-closed);
|
|
252
272
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
max-height: 100vh;
|
|
273
|
+
|
|
274
|
+
.muigui-open>.muigui-open-container {
|
|
275
|
+
transition: all 0.1s ease-out;
|
|
257
276
|
overflow: auto;
|
|
258
|
-
|
|
277
|
+
height: 100%;
|
|
259
278
|
}
|
|
260
|
-
|
|
261
|
-
.
|
|
262
|
-
transition: max-height 0.2s ease-out,
|
|
263
|
-
opacity 1s;
|
|
264
|
-
max-height: 0;
|
|
265
|
-
opacity: 0;
|
|
279
|
+
.muigui-closed>.muigui-open-container {
|
|
280
|
+
transition: all 0.1s ease-out;
|
|
266
281
|
overflow: hidden;
|
|
282
|
+
min-height: 0;
|
|
283
|
+
}
|
|
284
|
+
.muigui-open>.muigui-open-container>* {
|
|
285
|
+
transition: all 0.1s ease-out;
|
|
286
|
+
margin-top: 0px;
|
|
287
|
+
}
|
|
288
|
+
.muigui-closed>.muigui-open-container>* {
|
|
289
|
+
transition: all 0.1s ease-out;
|
|
290
|
+
margin-top: -100%;
|
|
267
291
|
}
|
|
268
292
|
|
|
269
293
|
/* ---- popdown ---- */
|
|
@@ -275,8 +299,12 @@ export default {
|
|
|
275
299
|
.muigui-value>*:nth-child(1).muigui-pop-down-top {
|
|
276
300
|
flex: 0;
|
|
277
301
|
}
|
|
278
|
-
.muigui-pop-down-bottom {
|
|
302
|
+
.muigui-closed .muigui-pop-down-bottom {
|
|
303
|
+
max-height: 0;
|
|
304
|
+
}
|
|
279
305
|
|
|
306
|
+
.muigui-value .muigui-pop-down-bottom {
|
|
307
|
+
margin: 0;
|
|
280
308
|
}
|
|
281
309
|
|
|
282
310
|
.muigui-pop-down-values {
|
|
@@ -298,6 +326,10 @@ export default {
|
|
|
298
326
|
width: auto;
|
|
299
327
|
color: var(--value-color);
|
|
300
328
|
background-color: var(--value-bg-color);
|
|
329
|
+
background-image: var(--image-checkerboard);
|
|
330
|
+
background-size: 10px 10px;
|
|
331
|
+
background-position: 0 0, 0 5px, 5px -5px, -5px 0px;
|
|
332
|
+
|
|
301
333
|
cursor: pointer;
|
|
302
334
|
|
|
303
335
|
display: grid;
|
|
@@ -389,14 +421,16 @@ export default {
|
|
|
389
421
|
|
|
390
422
|
.muigui-button {
|
|
391
423
|
display: grid;
|
|
392
|
-
|
|
424
|
+
padding: 2px 0 2px 0;
|
|
393
425
|
}
|
|
394
426
|
.muigui-button button {
|
|
395
427
|
border: none;
|
|
396
428
|
color: var(--value-color);
|
|
397
429
|
background-color: var(--button-bg-color);
|
|
430
|
+
background-image: var(--button-image);
|
|
398
431
|
cursor: pointer;
|
|
399
432
|
place-content: center center;
|
|
433
|
+
height: var(--line-height);
|
|
400
434
|
}
|
|
401
435
|
|
|
402
436
|
/* ------ [ color ] ------ */
|
|
@@ -608,9 +642,9 @@ export default {
|
|
|
608
642
|
border-bottom: 1px solid rgba(0,0,0,0.2);
|
|
609
643
|
border-right: 1px solid rgba(0,0,0,0.2);
|
|
610
644
|
background-color: var(--range-color);
|
|
611
|
-
margin-top: calc((var(--line-height) -
|
|
612
|
-
width: calc(var(--line-height) -
|
|
613
|
-
height: calc(var(--line-height) -
|
|
645
|
+
margin-top: calc((var(--line-height) - 6px) / -2);
|
|
646
|
+
width: calc(var(--line-height) - 6px);
|
|
647
|
+
height: calc(var(--line-height) - 6px);
|
|
614
648
|
}
|
|
615
649
|
|
|
616
650
|
.muigui-range input[type=range]::-webkit-slider-runnable-track {
|
|
@@ -670,6 +704,17 @@ export default {
|
|
|
670
704
|
}
|
|
671
705
|
*/
|
|
672
706
|
|
|
707
|
+
.muigui-checkered-background {
|
|
708
|
+
background-color: #404040;
|
|
709
|
+
background-image:
|
|
710
|
+
linear-gradient(45deg, #808080 25%, transparent 25%),
|
|
711
|
+
linear-gradient(-45deg, #808080 25%, transparent 25%),
|
|
712
|
+
linear-gradient(45deg, transparent 75%, #808080 75%),
|
|
713
|
+
linear-gradient(-45deg, transparent 75%, #808080 75%);
|
|
714
|
+
background-size: 16px 16px;
|
|
715
|
+
background-position: 0 0, 0 8px, 8px -8px, -8px 0px;
|
|
716
|
+
}
|
|
717
|
+
|
|
673
718
|
/* ---------------------------------------------------------- */
|
|
674
719
|
|
|
675
720
|
/* needs to be at bottom to take precedence */
|
|
@@ -683,8 +728,14 @@ export default {
|
|
|
683
728
|
|
|
684
729
|
`,
|
|
685
730
|
themes: {
|
|
686
|
-
default:
|
|
687
|
-
|
|
731
|
+
default: {
|
|
732
|
+
include: ['default'],
|
|
733
|
+
css: `
|
|
734
|
+
`,
|
|
735
|
+
},
|
|
736
|
+
float: {
|
|
737
|
+
include: ['default'],
|
|
738
|
+
css: `
|
|
688
739
|
:root {
|
|
689
740
|
color-scheme: light dark,
|
|
690
741
|
}
|
|
@@ -741,5 +792,57 @@ themes: {
|
|
|
741
792
|
--range-color: rgba(0, 0, 0, 0.125);
|
|
742
793
|
}
|
|
743
794
|
`,
|
|
795
|
+
},
|
|
796
|
+
form: {
|
|
797
|
+
include: [],
|
|
798
|
+
css: `
|
|
799
|
+
.muigui {
|
|
800
|
+
--width: 100%;
|
|
801
|
+
--label-width: 45%;
|
|
802
|
+
--number-width: 40%;
|
|
803
|
+
}
|
|
804
|
+
.muigui-root>button {
|
|
805
|
+
display: none;
|
|
806
|
+
}
|
|
807
|
+
.muigui-controller {
|
|
808
|
+
margin-top: 1em;
|
|
809
|
+
}
|
|
810
|
+
.muigui-label-controller {
|
|
811
|
+
display: flex;
|
|
812
|
+
flex-direction: column;
|
|
813
|
+
align-items: stretch;
|
|
814
|
+
margin-top: 1em;
|
|
815
|
+
}
|
|
816
|
+
.muigui-label-controller:has(.muigui-checkbox) {
|
|
817
|
+
flex-direction: row;
|
|
818
|
+
}
|
|
819
|
+
.muigui-value {
|
|
820
|
+
display: flex;
|
|
821
|
+
align-items: stretch;
|
|
822
|
+
}
|
|
823
|
+
.muigui-value>* {
|
|
824
|
+
flex: 1 1 auto;
|
|
825
|
+
min-width: 0;
|
|
826
|
+
}
|
|
827
|
+
.muigui-controller>*:nth-child(1) {
|
|
828
|
+
flex: 1 0 var(--label-width);
|
|
829
|
+
min-width: 0;
|
|
830
|
+
white-space: pre;
|
|
831
|
+
}
|
|
832
|
+
.muigui-controller>label:nth-child(1) {
|
|
833
|
+
place-content: center start;
|
|
834
|
+
display: inline-grid;
|
|
835
|
+
overflow: hidden;
|
|
836
|
+
}
|
|
837
|
+
.muigui-controller>*:nth-child(2) {
|
|
838
|
+
flex: 1 1 75%;
|
|
839
|
+
min-width: 0;
|
|
840
|
+
}
|
|
841
|
+
`,
|
|
842
|
+
},
|
|
843
|
+
none: {
|
|
844
|
+
include: [],
|
|
845
|
+
css: '',
|
|
846
|
+
},
|
|
744
847
|
},
|
|
745
848
|
};
|
|
@@ -1,32 +1,38 @@
|
|
|
1
|
-
import { createElem } from '../libs/elem.js';
|
|
1
|
+
import { createElem, getNewId } from '../libs/elem.js';
|
|
2
2
|
import { addTouchEvents } from '../libs/touch.js';
|
|
3
|
+
import { identity } from '../libs/conversions.js';
|
|
3
4
|
import { clamp } from '../libs/utils.js';
|
|
4
5
|
import EditView from './EditView.js';
|
|
5
6
|
import {
|
|
6
7
|
hexToFloatRGB,
|
|
8
|
+
hexToFloatRGBA,
|
|
7
9
|
hsv01ToRGBFloat,
|
|
10
|
+
hsva01ToRGBAFloat,
|
|
8
11
|
rgbFloatToHSV01,
|
|
12
|
+
rgbaFloatToHSVA01,
|
|
9
13
|
floatRGBToHex,
|
|
14
|
+
floatRGBAToHex,
|
|
15
|
+
rgbaFloatToHsla01,
|
|
10
16
|
} from '../libs/color-utils.js';
|
|
17
|
+
import { copyExistingProperties } from '../libs/utils.js';
|
|
11
18
|
|
|
12
19
|
const svg = `
|
|
13
|
-
|
|
14
|
-
<
|
|
15
|
-
<linearGradient id="muigui-color-chooser-light-dark" x1="0" x2="0" y1="0" y2="1">
|
|
20
|
+
<svg class="muigui-checkered-background" tabindex="0" viewBox="0 0 64 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
|
21
|
+
<linearGradient data-src="muigui-color-chooser-light-dark" x1="0" x2="0" y1="0" y2="1">
|
|
16
22
|
<stop stop-color="rgba(0,0,0,0)" offset="0%"/>
|
|
17
23
|
<stop stop-color="#000" offset="100%"/>
|
|
18
24
|
</linearGradient>
|
|
19
|
-
<linearGradient
|
|
20
|
-
<stop stop-color="hsl(60
|
|
21
|
-
<stop stop-color="hsl(60
|
|
25
|
+
<linearGradient data-src="muigui-color-chooser-hue">
|
|
26
|
+
<stop stop-color="hsl(60 0% 100% / 1)" offset="0%"/>
|
|
27
|
+
<stop stop-color="hsl(60 100% 50% / 1)" offset="100%"/>
|
|
22
28
|
</linearGradient>
|
|
23
29
|
|
|
24
|
-
<rect width="64" height="48"
|
|
25
|
-
<rect width="64" height="48"
|
|
30
|
+
<rect width="64" height="48" data-target="muigui-color-chooser-hue"/>
|
|
31
|
+
<rect width="64" height="48" data-target="muigui-color-chooser-light-dark"/>
|
|
26
32
|
<circle r="4" class="muigui-color-chooser-circle"/>
|
|
27
33
|
</svg>
|
|
28
34
|
<svg tabindex="0" viewBox="0 0 64 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
|
29
|
-
<linearGradient
|
|
35
|
+
<linearGradient data-src="muigui-color-chooser-hues" x1="0" x2="1" y1="0" y2="0">
|
|
30
36
|
<stop stop-color="hsl(0,100%,50%)" offset="0%"/>
|
|
31
37
|
<stop stop-color="hsl(60,100%,50%)" offset="16.666%"/>
|
|
32
38
|
<stop stop-color="hsl(120,100%,50%)" offset="33.333%"/>
|
|
@@ -35,48 +41,108 @@ const svg = `
|
|
|
35
41
|
<stop stop-color="hsl(300,100%,50%)" offset="83.333%"/>
|
|
36
42
|
<stop stop-color="hsl(360,100%,50%)" offset="100%"/>
|
|
37
43
|
</linearGradient>
|
|
38
|
-
<rect y="1" width="64" height="4"
|
|
39
|
-
<g class="muigui-color-chooser-cursor">
|
|
44
|
+
<rect y="1" width="64" height="4" data-target="muigui-color-chooser-hues"/>
|
|
45
|
+
<g class="muigui-color-chooser-hue-cursor">
|
|
46
|
+
<rect x="-3" width="6" height="6" />
|
|
47
|
+
</g>
|
|
48
|
+
</svg>
|
|
49
|
+
<svg class="muigui-checkered-background" tabindex="0" viewBox="0 0 64 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
|
50
|
+
<linearGradient data-src="muigui-color-chooser-alpha" x1="0" x2="1" y1="0" y2="0">
|
|
51
|
+
<stop stop-color="hsla(0,100%,100%,0)" offset="0%"/>
|
|
52
|
+
<stop stop-color="hsla(0,100%,100%,1)" offset="100%"/>
|
|
53
|
+
</linearGradient>
|
|
54
|
+
<rect y="1" width="64" height="4" data-target="muigui-color-chooser-alpha"/>
|
|
55
|
+
<g class="muigui-color-chooser-alpha-cursor">
|
|
40
56
|
<rect x="-3" width="6" height="6" />
|
|
41
57
|
</g>
|
|
42
58
|
</svg>
|
|
43
59
|
`;
|
|
44
60
|
|
|
61
|
+
function connectFillTargets(elem) {
|
|
62
|
+
elem.querySelectorAll('[data-src]').forEach(srcElem => {
|
|
63
|
+
const id = getNewId();
|
|
64
|
+
srcElem.id = id;
|
|
65
|
+
elem.querySelectorAll(`[data-target=${srcElem.dataset.src}]`).forEach(targetElem => {
|
|
66
|
+
targetElem.setAttribute('fill', `url(#${id})`);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
return elem;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Was originally going to make alpha an option. Issue is
|
|
73
|
+
// hard coded conversions?
|
|
45
74
|
export default class ColorChooserView extends EditView {
|
|
75
|
+
#to;
|
|
76
|
+
#from;
|
|
46
77
|
#satLevelElem;
|
|
47
|
-
#hueUIElem;
|
|
48
78
|
#circleElem;
|
|
79
|
+
#hueUIElem;
|
|
49
80
|
#hueElem;
|
|
50
81
|
#hueCursorElem;
|
|
51
|
-
#
|
|
82
|
+
#alphaUIElem;
|
|
83
|
+
#alphaElem;
|
|
84
|
+
#alphaCursorElem;
|
|
85
|
+
#hsva;
|
|
52
86
|
#skipHueUpdate;
|
|
53
87
|
#skipSatLevelUpdate;
|
|
88
|
+
#skipAlphaUpdate;
|
|
89
|
+
#options = {
|
|
90
|
+
converters: identity,
|
|
91
|
+
alpha: false,
|
|
92
|
+
};
|
|
93
|
+
#convertInternalToHex;
|
|
94
|
+
#convertHexToInternal;
|
|
54
95
|
|
|
55
|
-
constructor(setter) {
|
|
96
|
+
constructor(setter, options) {
|
|
56
97
|
super(createElem('div', {
|
|
57
98
|
innerHTML: svg,
|
|
58
99
|
className: 'muigui-no-scroll',
|
|
59
100
|
}));
|
|
60
101
|
this.#satLevelElem = this.domElement.children[0];
|
|
61
102
|
this.#hueUIElem = this.domElement.children[1];
|
|
103
|
+
this.#alphaUIElem = this.domElement.children[2];
|
|
104
|
+
connectFillTargets(this.#satLevelElem);
|
|
105
|
+
connectFillTargets(this.#hueUIElem);
|
|
106
|
+
connectFillTargets(this.#alphaUIElem);
|
|
62
107
|
this.#circleElem = this.$('.muigui-color-chooser-circle');
|
|
63
|
-
this.#hueElem = this.$('
|
|
64
|
-
this.#hueCursorElem = this.$('.muigui-color-chooser-cursor');
|
|
108
|
+
this.#hueElem = this.$('[data-src=muigui-color-chooser-hue]');
|
|
109
|
+
this.#hueCursorElem = this.$('.muigui-color-chooser-hue-cursor');
|
|
110
|
+
this.#alphaElem = this.$('[data-src=muigui-color-chooser-alpha]');
|
|
111
|
+
this.#alphaCursorElem = this.$('.muigui-color-chooser-alpha-cursor');
|
|
65
112
|
|
|
66
113
|
const handleSatLevelChange = (e) => {
|
|
67
114
|
const s = clamp(e.nx, 0, 1);
|
|
68
115
|
const v = clamp(e.ny, 0, 1);
|
|
69
|
-
this.#
|
|
70
|
-
this.#
|
|
116
|
+
this.#hsva[1] = s;
|
|
117
|
+
this.#hsva[2] = (1 - v);
|
|
71
118
|
this.#skipHueUpdate = true;
|
|
72
|
-
|
|
119
|
+
this.#skipAlphaUpdate = true;
|
|
120
|
+
const [valid, newV] = this.#from(this.#convertInternalToHex(this.#hsva));
|
|
121
|
+
if (valid) {
|
|
122
|
+
setter.setValue(newV);
|
|
123
|
+
}
|
|
73
124
|
};
|
|
74
125
|
|
|
75
126
|
const handleHueChange = (e) => {
|
|
76
127
|
const h = clamp(e.nx, 0, 1);
|
|
77
|
-
this.#
|
|
128
|
+
this.#hsva[0] = h;
|
|
78
129
|
this.#skipSatLevelUpdate = true;
|
|
79
|
-
|
|
130
|
+
this.#skipAlphaUpdate = true;
|
|
131
|
+
const [valid, newV] = this.#from(this.#convertInternalToHex(this.#hsva));
|
|
132
|
+
if (valid) {
|
|
133
|
+
setter.setValue(newV);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const handleAlphaChange = (e) => {
|
|
138
|
+
const a = clamp(e.nx, 0, 1);
|
|
139
|
+
this.#hsva[3] = a;
|
|
140
|
+
this.#skipHueUpdate = true;
|
|
141
|
+
this.#skipSatLevelUpdate = true;
|
|
142
|
+
const [valid, newV] = this.#from(this.#convertInternalToHex(this.#hsva));
|
|
143
|
+
if (valid) {
|
|
144
|
+
setter.setValue(newV);
|
|
145
|
+
}
|
|
80
146
|
};
|
|
81
147
|
|
|
82
148
|
addTouchEvents(this.#satLevelElem, {
|
|
@@ -87,29 +153,45 @@ export default class ColorChooserView extends EditView {
|
|
|
87
153
|
onDown: handleHueChange,
|
|
88
154
|
onMove: handleHueChange,
|
|
89
155
|
});
|
|
156
|
+
addTouchEvents(this.#alphaUIElem, {
|
|
157
|
+
onDown: handleAlphaChange,
|
|
158
|
+
onMove: handleAlphaChange,
|
|
159
|
+
});
|
|
160
|
+
this.setOptions(options);
|
|
90
161
|
}
|
|
91
162
|
updateDisplay(newV) {
|
|
92
|
-
if (!this.#
|
|
93
|
-
this.#
|
|
163
|
+
if (!this.#hsva) {
|
|
164
|
+
this.#hsva = this.#convertHexToInternal(this.#to(newV));
|
|
94
165
|
}
|
|
95
166
|
{
|
|
96
|
-
const [h, s, v] =
|
|
167
|
+
const [h, s, v, a = 1] = this.#convertHexToInternal(this.#to(newV));
|
|
97
168
|
// Don't copy the hue if it was un-computable.
|
|
98
169
|
if (!this.#skipHueUpdate) {
|
|
99
|
-
this.#
|
|
170
|
+
this.#hsva[0] = s > 0.001 && v > 0.001 ? h : this.#hsva[0];
|
|
100
171
|
}
|
|
101
172
|
if (!this.#skipSatLevelUpdate) {
|
|
102
|
-
this.#
|
|
103
|
-
this.#
|
|
173
|
+
this.#hsva[1] = s;
|
|
174
|
+
this.#hsva[2] = v;
|
|
175
|
+
}
|
|
176
|
+
if (!this.#skipAlphaUpdate) {
|
|
177
|
+
this.#hsva[3] = a;
|
|
104
178
|
}
|
|
105
179
|
}
|
|
106
180
|
{
|
|
107
|
-
const [h, s, v] = this.#
|
|
181
|
+
const [h, s, v, a] = this.#hsva;
|
|
182
|
+
const [hue, sat, lum] = rgbaFloatToHsla01(hsva01ToRGBAFloat(this.#hsva));
|
|
183
|
+
|
|
108
184
|
if (!this.#skipHueUpdate) {
|
|
109
185
|
this.#hueCursorElem.setAttribute('transform', `translate(${h * 64}, 0)`);
|
|
110
|
-
this.#hueElem.children[0].setAttribute('stop-color', `hsl(${h * 360}, 0%, 100%)`);
|
|
111
|
-
this.#hueElem.children[1].setAttribute('stop-color', `hsl(${h * 360}, 100%, 50%)`);
|
|
112
186
|
}
|
|
187
|
+
this.#hueElem.children[0].setAttribute('stop-color', `hsl(${hue * 360} 0% 100% / ${a})`);
|
|
188
|
+
this.#hueElem.children[1].setAttribute('stop-color', `hsl(${hue * 360} 100% 50% / ${a})`);
|
|
189
|
+
if (!this.#skipAlphaUpdate) {
|
|
190
|
+
this.#alphaCursorElem.setAttribute('transform', `translate(${a * 64}, 0)`);
|
|
191
|
+
}
|
|
192
|
+
this.#alphaElem.children[0].setAttribute('stop-color', `hsl(${hue * 360} ${sat * 100}% ${lum * 100}% / 0)`);
|
|
193
|
+
this.#alphaElem.children[1].setAttribute('stop-color', `hsl(${hue * 360} ${sat * 100}% ${lum * 100}% / 1)`);
|
|
194
|
+
|
|
113
195
|
if (!this.#skipSatLevelUpdate) {
|
|
114
196
|
this.#circleElem.setAttribute('cx', `${s * 64}`);
|
|
115
197
|
this.#circleElem.setAttribute('cy', `${(1 - v) * 48}`);
|
|
@@ -117,5 +199,20 @@ export default class ColorChooserView extends EditView {
|
|
|
117
199
|
}
|
|
118
200
|
this.#skipHueUpdate = false;
|
|
119
201
|
this.#skipSatLevelUpdate = false;
|
|
202
|
+
this.#skipAlphaUpdate = false;
|
|
203
|
+
}
|
|
204
|
+
setOptions(options) {
|
|
205
|
+
copyExistingProperties(this.#options, options);
|
|
206
|
+
const {converters: {to, from}, alpha} = this.#options;
|
|
207
|
+
this.#alphaUIElem.style.display = alpha ? '' : 'none';
|
|
208
|
+
this.#convertInternalToHex = alpha
|
|
209
|
+
? v => floatRGBAToHex(hsva01ToRGBAFloat(v))
|
|
210
|
+
: v => floatRGBToHex(hsv01ToRGBFloat(v));
|
|
211
|
+
this.#convertHexToInternal = alpha
|
|
212
|
+
? v => rgbaFloatToHSVA01(hexToFloatRGBA(v))
|
|
213
|
+
: v => rgbFloatToHSV01(hexToFloatRGB(v));
|
|
214
|
+
this.#to = to;
|
|
215
|
+
this.#from = from;
|
|
216
|
+
return this;
|
|
120
217
|
}
|
|
121
218
|
}
|
package/src/views/NumberView.js
CHANGED
|
@@ -22,15 +22,22 @@ export default class NumberView extends EditView {
|
|
|
22
22
|
const wheelHelper = createWheelHelper();
|
|
23
23
|
super(createElem('input', {
|
|
24
24
|
type: 'number',
|
|
25
|
-
onInput: () =>
|
|
26
|
-
|
|
25
|
+
onInput: () => {
|
|
26
|
+
this.#handleInput(setValue, true);
|
|
27
|
+
},
|
|
28
|
+
onChange: () => {
|
|
29
|
+
this.#handleInput(setFinalValue, false);
|
|
30
|
+
},
|
|
27
31
|
onWheel: e => {
|
|
28
32
|
e.preventDefault();
|
|
29
33
|
const {min, max, step} = this.#options;
|
|
30
34
|
const delta = wheelHelper(e, step);
|
|
31
35
|
const v = parseFloat(this.domElement.value);
|
|
32
36
|
const newV = clamp(stepify(v + delta, v => v, step), min, max);
|
|
33
|
-
|
|
37
|
+
const [valid, outV] = this.#from(newV);
|
|
38
|
+
if (valid) {
|
|
39
|
+
setter.setValue(outV);
|
|
40
|
+
}
|
|
34
41
|
},
|
|
35
42
|
}));
|
|
36
43
|
this.setOptions(options);
|
|
@@ -15,7 +15,7 @@ export default class RadioGridView extends EditView {
|
|
|
15
15
|
type: 'radio',
|
|
16
16
|
name,
|
|
17
17
|
value: ndx,
|
|
18
|
-
onChange: function() {
|
|
18
|
+
onChange: function () {
|
|
19
19
|
if (this.checked) {
|
|
20
20
|
setter.setFinalValue(that.#values[this.value]);
|
|
21
21
|
}
|
|
@@ -24,12 +24,13 @@ export default class RadioGridView extends EditView {
|
|
|
24
24
|
createElem('button', {
|
|
25
25
|
type: 'button',
|
|
26
26
|
textContent: key,
|
|
27
|
-
onClick: function() {
|
|
27
|
+
onClick: function () {
|
|
28
28
|
this.previousElementSibling.click();
|
|
29
29
|
},
|
|
30
30
|
}),
|
|
31
31
|
]);
|
|
32
32
|
})));
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
33
34
|
const that = this;
|
|
34
35
|
this.#values = values;
|
|
35
36
|
this.cols(cols);
|
package/src/views/TextView.js
CHANGED
|
@@ -16,8 +16,12 @@ export default class TextView extends EditView {
|
|
|
16
16
|
const setFinalValue = setter.setFinalValue.bind(setter);
|
|
17
17
|
super(createElem('input', {
|
|
18
18
|
type: 'text',
|
|
19
|
-
onInput: () =>
|
|
20
|
-
|
|
19
|
+
onInput: () => {
|
|
20
|
+
this.#handleInput(setValue, true);
|
|
21
|
+
},
|
|
22
|
+
onChange: () => {
|
|
23
|
+
this.#handleInput(setFinalValue, false);
|
|
24
|
+
},
|
|
21
25
|
}));
|
|
22
26
|
this.setOptions(options);
|
|
23
27
|
}
|
|
@@ -1,56 +1,58 @@
|
|
|
1
1
|
import { removeArrayElem } from '../libs/utils.js';
|
|
2
2
|
|
|
3
3
|
export default class View {
|
|
4
|
-
|
|
5
|
-
#views = [];
|
|
4
|
+
domElement: HTMLElement;
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
#childDestElem: HTMLElement;
|
|
7
|
+
#views: View[] = [];
|
|
8
|
+
|
|
9
|
+
constructor(elem: HTMLElement) {
|
|
8
10
|
this.domElement = elem;
|
|
9
11
|
this.#childDestElem = elem;
|
|
10
12
|
}
|
|
11
|
-
addElem(elem) {
|
|
13
|
+
addElem(elem: HTMLElement) {
|
|
12
14
|
this.#childDestElem.appendChild(elem);
|
|
13
15
|
return elem;
|
|
14
16
|
}
|
|
15
|
-
removeElem(elem) {
|
|
17
|
+
removeElem(elem: HTMLElement) {
|
|
16
18
|
this.#childDestElem.removeChild(elem);
|
|
17
19
|
return elem;
|
|
18
20
|
}
|
|
19
|
-
pushSubElem(elem) {
|
|
21
|
+
pushSubElem(elem: HTMLElement) {
|
|
20
22
|
this.#childDestElem.appendChild(elem);
|
|
21
23
|
this.#childDestElem = elem;
|
|
22
24
|
}
|
|
23
25
|
popSubElem() {
|
|
24
|
-
this.#childDestElem = this.#childDestElem.parentElement
|
|
26
|
+
this.#childDestElem = this.#childDestElem.parentElement!;
|
|
25
27
|
}
|
|
26
|
-
add(view) {
|
|
28
|
+
add(view: View) {
|
|
27
29
|
this.#views.push(view);
|
|
28
30
|
this.addElem(view.domElement);
|
|
29
31
|
return view;
|
|
30
32
|
}
|
|
31
|
-
remove(view) {
|
|
33
|
+
remove(view: View) {
|
|
32
34
|
this.removeElem(view.domElement);
|
|
33
35
|
removeArrayElem(this.#views, view);
|
|
34
36
|
return view;
|
|
35
37
|
}
|
|
36
|
-
pushSubView(view) {
|
|
38
|
+
pushSubView(view: View) {
|
|
37
39
|
this.pushSubElem(view.domElement);
|
|
38
40
|
}
|
|
39
41
|
popSubView() {
|
|
40
42
|
this.popSubElem();
|
|
41
43
|
}
|
|
42
|
-
setOptions(options) {
|
|
44
|
+
setOptions(options: any) {
|
|
43
45
|
for (const view of this.#views) {
|
|
44
46
|
view.setOptions(options);
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
|
-
updateDisplayIfNeeded(newV, ignoreCache) {
|
|
49
|
+
updateDisplayIfNeeded(newV: any, ignoreCache?: boolean) {
|
|
48
50
|
for (const view of this.#views) {
|
|
49
51
|
view.updateDisplayIfNeeded(newV, ignoreCache);
|
|
50
52
|
}
|
|
51
53
|
return this;
|
|
52
54
|
}
|
|
53
|
-
$(selector) {
|
|
55
|
+
$(selector: string) {
|
|
54
56
|
return this.domElement.querySelector(selector);
|
|
55
57
|
}
|
|
56
58
|
}
|