perfect-gui 4.2.3 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -110,6 +110,19 @@ function w(y) {
110
110
  position: relative;
111
111
  margin-top: 1px;
112
112
  margin-bottom: 19px;
113
+ border-radius: var(--main-border-radius);
114
+ }
115
+
116
+ .p-gui__image--selected::after {
117
+ position: absolute;
118
+ top: 0;
119
+ left: 0;
120
+ width: 100%;
121
+ height: 100%;
122
+ content: '';
123
+ border: 1px solid #06FF89;
124
+ box-sizing: border-box;
125
+ border-radius: var(--main-border-radius);
113
126
  }
114
127
 
115
128
  .p-gui__image-text {
@@ -495,59 +508,66 @@ class h {
495
508
  else
496
509
  throw typeof e.path == null ? Error("[GUI] image() path must be provided.") : Error("[GUI] image() path must be a string.");
497
510
  let r = i.replace(/^.*[\\\/]/, ""), o;
498
- e.name == null ? o = r : o = typeof e.name == "string" && e.name || " ", this.imageContainer || (this.imageContainer = this._createElement({
511
+ e.name == null ? o = r : o = typeof e.name == "string" && e.name || " ";
512
+ const s = e.selected === !0, n = e.selectionBorder !== !1;
513
+ this.imageContainer || (this.imageContainer = this._createElement({
499
514
  class: "p-gui__image-container"
500
515
  }));
501
- var n = this._createElement({
516
+ var a = this._createElement({
502
517
  class: "p-gui__image",
503
518
  inline: `background-image: url(${i})`,
504
519
  parent: this.imageContainer
505
520
  });
506
- this._createElement({
507
- parent: n,
521
+ s && n && a.classList.add("p-gui__image--selected"), this._createElement({
522
+ parent: a,
508
523
  class: "p-gui__image-text",
509
524
  textContent: o
510
- }), typeof t == "function" && (n.onclick = () => t({ path: i, text: o }));
525
+ }), typeof t == "function" && (a.onclick = () => {
526
+ let l = this.imageContainer.querySelectorAll(".p-gui__image--selected");
527
+ for (let g = 0; g < l.length; g++)
528
+ l[g].classList.remove("p-gui__image--selected");
529
+ n && a.classList.add("p-gui__image--selected"), t({ path: i, text: o });
530
+ });
511
531
  }
512
532
  slider(e = {}, t) {
513
533
  if (typeof e != "object")
514
534
  throw Error(`[GUI] slider() first parameter must be an object. Received: ${typeof e}.`);
515
- let i = typeof e.name == "string" && e.name || " ", r = !1, o = null, n = e.obj || e.object, s = e.prop || e.property, a = typeof e.value == "number" ? e.value : null, l = e.min ?? 0, f = e.max ?? 1, g = e.step || (f - l) / 100;
535
+ let i = typeof e.name == "string" && e.name || " ", r = !1, o = null, s = e.obj || e.object, n = e.prop || e.property, a = typeof e.value == "number" ? e.value : null, l = e.min ?? 0, g = e.max ?? 1, u = e.step || (g - l) / 100;
516
536
  if (a !== null)
517
- (s != null || n != null) && console.warn('[GUI] slider() "obj" and "property" parameters are ignored when a "value" parameter is used.');
518
- else if (s != null && n != null) {
519
- if (typeof s != "string")
520
- throw Error(`[GUI] slider() "prop" (or "property") parameter must be an string. Received: ${typeof s}.`);
521
- if (typeof n != "object")
522
- throw Error(`[GUI] slider() "obj" (or "object") parameter must be an object. Received: ${typeof n}.`);
523
- i == " " && (i = s), o = this.propReferences.push(n[s]) - 1, r = !0;
537
+ (n != null || s != null) && console.warn('[GUI] slider() "obj" and "property" parameters are ignored when a "value" parameter is used.');
538
+ else if (n != null && s != null) {
539
+ if (typeof n != "string")
540
+ throw Error(`[GUI] slider() "prop" (or "property") parameter must be an string. Received: ${typeof n}.`);
541
+ if (typeof s != "object")
542
+ throw Error(`[GUI] slider() "obj" (or "object") parameter must be an object. Received: ${typeof s}.`);
543
+ i == " " && (i = n), o = this.propReferences.push(s[n]) - 1, r = !0;
524
544
  } else
525
- (s != null && n == null || s == null && n == null) && console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'), a = (f - l) / 2;
545
+ (n != null && s == null || n == null && s == null) && console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'), a = (g - l) / 2;
526
546
  this.imageContainer = null;
527
547
  var d = this._createElement({
528
548
  class: "p-gui__slider",
529
549
  textContent: i
530
- }), u = this._createElement({
550
+ }), f = this._createElement({
531
551
  parent: d,
532
552
  el: "input",
533
553
  class: "p-gui__slider-ctrl",
534
554
  customAttributes: {
535
555
  type: "range",
536
556
  min: l,
537
- max: f,
538
- step: g,
539
- value: r ? n[s] : a
557
+ max: g,
558
+ step: u,
559
+ value: r ? s[n] : a
540
560
  }
541
561
  }), _ = this._createElement({
542
562
  parent: d,
543
563
  class: "p-gui__slider-value",
544
- textContent: String(r ? n[s] : a)
564
+ textContent: String(r ? s[n] : a)
545
565
  });
546
- u.addEventListener("input", () => {
547
- _.textContent = u.value, r && (n[s] = u.value), typeof t == "function" && t(parseFloat(u.value));
548
- }), r && Object.defineProperty(n, s, {
566
+ f.addEventListener("input", () => {
567
+ _.textContent = f.value, r && (s[n] = f.value), typeof t == "function" && t(parseFloat(f.value));
568
+ }), r && Object.defineProperty(s, n, {
549
569
  set: (b) => {
550
- this.propReferences[o] = b, u.value = b, _.textContent = String(b);
570
+ this.propReferences[o] = b, f.value = b, _.textContent = String(b);
551
571
  },
552
572
  get: () => this.propReferences[o]
553
573
  });
@@ -559,15 +579,15 @@ class h {
559
579
  this.imageContainer = null;
560
580
  let o = this._createElement({
561
581
  class: "p-gui__switch",
562
- onclick: (s) => {
563
- let a = s.target.childNodes[1], l = !0;
582
+ onclick: (n) => {
583
+ let a = n.target.childNodes[1], l = !0;
564
584
  a.classList.contains("p-gui__switch-checkbox--active") && (l = !1), a.classList.toggle("p-gui__switch-checkbox--active"), typeof t == "function" && t(l);
565
585
  },
566
586
  textContent: i
567
- }), n = r ? " p-gui__switch-checkbox--active" : "";
587
+ }), s = r ? " p-gui__switch-checkbox--active" : "";
568
588
  this._createElement({
569
589
  parent: o,
570
- class: "p-gui__switch-checkbox" + n
590
+ class: "p-gui__switch-checkbox" + s
571
591
  });
572
592
  }
573
593
  list(e = {}, t) {
@@ -578,22 +598,22 @@ class h {
578
598
  let o = this._createElement({
579
599
  class: "p-gui__list",
580
600
  textContent: i
581
- }), n = this._createElement({
601
+ }), s = this._createElement({
582
602
  parent: o,
583
603
  el: "select",
584
604
  class: "p-gui__list-dropdown",
585
- onchange: (s) => {
586
- t && t(s.target.value);
605
+ onchange: (n) => {
606
+ t && t(n.target.value);
587
607
  }
588
608
  });
589
- r.forEach((s) => {
609
+ r.forEach((n) => {
590
610
  this._createElement({
591
- parent: n,
611
+ parent: s,
592
612
  el: "option",
593
613
  customAttributes: {
594
- value: s
614
+ value: n
595
615
  },
596
- textContent: s
616
+ textContent: n
597
617
  });
598
618
  });
599
619
  }
@@ -606,7 +626,7 @@ class h {
606
626
  if (typeof e != "object")
607
627
  throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof e}.`);
608
628
  let i = typeof e.name == "string" && e.name || " ";
609
- const r = e.x.min ?? 0, o = e.x.max ?? 1, n = e.y.min ?? 0, s = e.y.max ?? 1, a = e.x.obj || e.x.object, l = e.x.prop || e.x.property, f = this.propReferences.push(a[l]) - 1, g = e.y.obj || e.y.object, d = e.y.prop || e.y.property, u = this.propReferences.push(g[d]) - 1;
629
+ const r = e.x.min ?? 0, o = e.x.max ?? 1, s = e.y.min ?? 0, n = e.y.max ?? 1, a = e.x.obj || e.x.object, l = e.x.prop || e.x.property, g = this.propReferences.push(a[l]) - 1, u = e.y.obj || e.y.object, d = e.y.prop || e.y.property, f = this.propReferences.push(u[d]) - 1;
610
630
  t = typeof t == "function" ? t : null, this.imageContainer = null;
611
631
  const _ = this._createElement({
612
632
  class: "p-gui__vector2",
@@ -614,43 +634,43 @@ class h {
614
634
  }), b = this._createElement({
615
635
  parent: _,
616
636
  class: "p-gui__vector-value",
617
- textContent: a[l] + ", " + g[d]
618
- }), p = this._createElement({
637
+ textContent: a[l] + ", " + u[d]
638
+ }), c = this._createElement({
619
639
  parent: _,
620
640
  el: "div",
621
641
  class: "p-gui__vector2-area",
622
- onclick: (c) => {
623
- a[l] = parseFloat(this._mapLinear(c.offsetX, 0, p.clientWidth, r, o).toFixed(2)), g[d] = parseFloat(this._mapLinear(c.offsetY, 0, p.clientHeight, s, n).toFixed(2)), t && t(a[l], a[d]);
642
+ onclick: (p) => {
643
+ a[l] = parseFloat(this._mapLinear(p.offsetX, 0, c.clientWidth, r, o).toFixed(2)), u[d] = parseFloat(this._mapLinear(p.offsetY, 0, c.clientHeight, n, s).toFixed(2)), t && t(a[l], a[d]);
624
644
  }
625
645
  });
626
646
  let m = !1;
627
- p.addEventListener("pointerdown", (c) => {
647
+ c.addEventListener("pointerdown", (p) => {
628
648
  m = !0;
629
- }), p.addEventListener("pointerup", () => {
649
+ }), c.addEventListener("pointerup", () => {
630
650
  m = !1;
631
- }), p.addEventListener("pointermove", (c) => {
632
- m && (a[l] = parseFloat(this._mapLinear(c.offsetX, 0, p.clientWidth, r, o).toFixed(2)), g[d] = parseFloat(this._mapLinear(c.offsetY, 0, p.clientHeight, s, n).toFixed(2)), t && t(a[l], a[d]));
651
+ }), c.addEventListener("pointermove", (p) => {
652
+ m && (a[l] = parseFloat(this._mapLinear(p.offsetX, 0, c.clientWidth, r, o).toFixed(2)), u[d] = parseFloat(this._mapLinear(p.offsetY, 0, c.clientHeight, n, s).toFixed(2)), t && t(a[l], a[d]));
633
653
  }), this._createElement({
634
- parent: p,
654
+ parent: c,
635
655
  class: "p-gui__vector2-line p-gui__vector2-line-x"
636
656
  }), this._createElement({
637
- parent: p,
657
+ parent: c,
638
658
  class: "p-gui__vector2-line p-gui__vector2-line-y"
639
659
  });
640
660
  const x = this._createElement({
641
- parent: p,
661
+ parent: c,
642
662
  class: "p-gui__vector2-dot"
643
663
  });
644
- x.style.left = this._mapLinear(a[l], r, o, 0, p.clientWidth) + "px", x.style.top = this._mapLinear(g[d], n, s, p.clientHeight, 0) + "px", Object.defineProperty(a, l, {
645
- set: (c) => {
646
- this.propReferences[f] = c, x.style.left = this._mapLinear(c, r, o, 0, p.clientWidth) + "px", b.textContent = String(c) + ", " + g[d];
664
+ x.style.left = this._mapLinear(a[l], r, o, 0, c.clientWidth) + "px", x.style.top = this._mapLinear(u[d], s, n, c.clientHeight, 0) + "px", Object.defineProperty(a, l, {
665
+ set: (p) => {
666
+ this.propReferences[g] = p, x.style.left = this._mapLinear(p, r, o, 0, c.clientWidth) + "px", b.textContent = String(p) + ", " + u[d];
647
667
  },
648
- get: () => this.propReferences[f]
649
- }), Object.defineProperty(g, d, {
650
- set: (c) => {
651
- this.propReferences[u] = c, x.style.top = this._mapLinear(c, n, s, p.clientHeight, 0) + "px", b.textContent = a[l] + ", " + String(c);
668
+ get: () => this.propReferences[g]
669
+ }), Object.defineProperty(u, d, {
670
+ set: (p) => {
671
+ this.propReferences[f] = p, x.style.top = this._mapLinear(p, s, n, c.clientHeight, 0) + "px", b.textContent = a[l] + ", " + String(p);
652
672
  },
653
- get: () => this.propReferences[u]
673
+ get: () => this.propReferences[f]
654
674
  });
655
675
  }
656
676
  color(e = {}, t) {
@@ -662,27 +682,27 @@ class h {
662
682
  el: "div",
663
683
  class: "p-gui__color",
664
684
  textContent: i
665
- }), n = this._createElement({
685
+ }), s = this._createElement({
666
686
  parent: o,
667
687
  el: "input",
668
688
  class: "p-gui__color-picker",
669
689
  type: "color",
670
690
  value: r
671
691
  });
672
- typeof t == "function" && n.addEventListener("input", () => {
673
- t(n.value);
692
+ typeof t == "function" && s.addEventListener("input", () => {
693
+ t(s.value);
674
694
  });
675
695
  }
676
696
  folder(e = {}) {
677
697
  let t = typeof e.closed == "boolean" ? e.closed : !1, i = e.name || "", r = e.color || null, o = e.maxHeight || null;
678
698
  this.imageContainer = null;
679
- let n = "p-gui__folder";
680
- this.folders.length == 0 && (n += " p-gui__folder--first"), t && (n += " p-gui__folder--closed");
681
- let s = r ? `background-color: ${r};` : "";
682
- s += o ? `max-height: ${o}px;` : "";
699
+ let s = "p-gui__folder";
700
+ this.folders.length == 0 && (s += " p-gui__folder--first"), t && (s += " p-gui__folder--closed");
701
+ let n = r ? `background-color: ${r};` : "";
702
+ n += o ? `max-height: ${o}px;` : "";
683
703
  let a = this._createElement({
684
- class: n,
685
- inline: s
704
+ class: s,
705
+ inline: n
686
706
  });
687
707
  this._createElement({
688
708
  innerHTML: `<span class="p-gui__folder-arrow"></span>${i}`,
@@ -0,0 +1,415 @@
1
+ (function(_,c){typeof exports=="object"&&typeof module<"u"?module.exports=c():typeof define=="function"&&define.amd?define(c):(_=typeof globalThis<"u"?globalThis:_||self,_["Perfect GUI"]=c())})(this,function(){"use strict";function _(w){return`
2
+ .p-gui {
3
+ --main-border-radius: 5px;
4
+ --color-bg: #121212;
5
+ --color-border: #484848;
6
+ --color-border-2: rgba(255,255,255,.1);
7
+ --color-accent: #1681ca;
8
+ --color-accent-hover: #218fda;
9
+
10
+ position: ${w};
11
+ top: 0;
12
+ left: 0;
13
+ transform: translate3d(0,0,0);
14
+ padding-top: 21px;
15
+ background: var(--color-bg);
16
+ display: flex;
17
+ justify-content: center;
18
+ flex-wrap: wrap;
19
+ font-family: Verdana, Arial, sans-serif;
20
+ width: 290px;
21
+ overflow: auto;
22
+ box-shadow: 0 0 2px black;
23
+ box-sizing: border-box;
24
+ z-index: 99999;
25
+ user-select: none;
26
+ border-bottom-right-radius: 3px;
27
+ border-bottom-left-radius: 3px;
28
+ cursor: auto;
29
+ border-radius: var(--main-border-radius);
30
+ border: 1px solid var(--color-border);
31
+ }
32
+
33
+ .p-gui * {
34
+ font-size: 11px;
35
+ }
36
+
37
+ .p-gui::-webkit-scrollbar,
38
+ .p-gui *::-webkit-scrollbar {
39
+ width: 10px;
40
+ }
41
+
42
+ .p-gui::-webkit-scrollbar-track,
43
+ .p-gui *::-webkit-scrollbar-track {
44
+ background: #2f2f2f;
45
+ border-radius: 3px;
46
+ }
47
+
48
+ .p-gui::-webkit-scrollbar-thumb,
49
+ .p-gui *::-webkit-scrollbar-thumb {
50
+ background: #757576;
51
+ border-radius: 10px;
52
+ box-sizing: border-box;
53
+ border: 1px solid #2f2f2f;
54
+ }
55
+
56
+ .p-gui--collapsed {
57
+ height: 0;
58
+ padding: 21px 10px 0 10px;
59
+ overflow: hidden;
60
+ }
61
+
62
+ .p-gui__header {
63
+ position: absolute;
64
+ top: 0;
65
+ left: 0;
66
+ width: 100%;
67
+ height: 20px;
68
+ background-color: rgba(0, 0, 0, .8);
69
+ cursor: grab;
70
+ color: grey;
71
+ font-size: 10px;
72
+ line-height: 20px;
73
+ padding-left: 12px;
74
+ box-sizing: border-box;
75
+ touch-action: none;
76
+ }
77
+
78
+ .p-gui__header-close {
79
+ width: 20px;
80
+ height: 20px;
81
+ position: absolute;
82
+ top: 0;
83
+ right: 5px;
84
+ cursor: pointer;
85
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUAQMAAAC3R49OAAAABlBMVEUAAAD///+l2Z/dAAAAAXRSTlMAQObYZgAAABFJREFUCNdjIAb8//8BjIkAAOrOBd3TR0jRAAAAAElFTkSuQmCC);
86
+ background-size: 50% 50%;
87
+ background-position: center;
88
+ background-repeat: no-repeat;
89
+ }
90
+
91
+ .p-gui--collapsed .p-gui__header-close {
92
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUAQMAAAC3R49OAAAABlBMVEUAAAD///+l2Z/dAAAAAXRSTlMAQObYZgAAABVJREFUCNdjYEhgIIj///8AwsSoBQD43QydY5mb0QAAAABJRU5ErkJggg==);
93
+ }
94
+
95
+ .p-gui__image-container {
96
+ width: 100%;
97
+ display: grid;
98
+ grid-template-columns: repeat(auto-fill, 32%);
99
+ justify-content: space-between;
100
+ padding: 0 2%;
101
+ }
102
+
103
+ .p-gui__image {
104
+ aspect-ratio: 1 / 1;
105
+ background-size: cover;
106
+ cursor: pointer;
107
+ position: relative;
108
+ margin-top: 1px;
109
+ margin-bottom: 19px;
110
+ border-radius: var(--main-border-radius);
111
+ }
112
+
113
+ .p-gui__image--selected::after {
114
+ position: absolute;
115
+ top: 0;
116
+ left: 0;
117
+ width: 100%;
118
+ height: 100%;
119
+ content: '';
120
+ border: 1px solid #06FF89;
121
+ box-sizing: border-box;
122
+ border-radius: var(--main-border-radius);
123
+ }
124
+
125
+ .p-gui__image-text {
126
+ position: absolute;
127
+ bottom: -15px;
128
+ color: #eee;
129
+ text-shadow: 0 -1px 0 #111;
130
+ white-space: nowrap;
131
+ width: 100%;
132
+ overflow: hidden;
133
+ text-overflow: ellipsis;
134
+ }
135
+
136
+ .p-gui__button,
137
+ .p-gui__switch,
138
+ .p-gui__list,
139
+ .p-gui__vector2,
140
+ .p-gui__color {
141
+ width: 100%;
142
+ padding: 7px 13px;
143
+ color: white;
144
+ cursor: pointer;
145
+ position: relative;
146
+ box-sizing: border-box;
147
+ margin-bottom: 3px;
148
+ margin: 3px;
149
+
150
+ border: 1px solid var(--color-border-2);
151
+ border-radius: var(--main-border-radius);
152
+ }
153
+
154
+ .p-gui__vector2 {
155
+ padding: 7px;
156
+ }
157
+
158
+ .p-gui__button,
159
+ .p-gui__switch {
160
+ margin-right: 4px;
161
+ margin-left: 4px;
162
+ }
163
+
164
+ .p-gui__button {
165
+ background: var(--color-accent);
166
+ text-align: center;
167
+ color: white;
168
+ border: none;
169
+ }
170
+
171
+ .p-gui__button:hover {
172
+ background: var(--color-accent-hover);
173
+ }
174
+
175
+ .p-gui__switch {
176
+ background: rgba(255, 255, 255, .05);
177
+ }
178
+
179
+ .p-gui__switch:hover {
180
+ background: rgba(255, 255, 255, .1);
181
+ }
182
+
183
+ .p-gui__folder .p-gui__button,
184
+ .p-gui__folder .p-gui__switch {
185
+ margin-right: 0;
186
+ margin-left: 0;
187
+ }
188
+
189
+ .p-gui__vector2 {
190
+ background: transparent;
191
+ aspect-ratio: 1;
192
+ padding-bottom: 0;
193
+ }
194
+
195
+ .p-gui__vector2-area {
196
+ position: relative;
197
+ background: rgba(0, 0, 0, .3);
198
+ margin-top: 8px;
199
+ width: 100%;
200
+ height: calc(100% - 28px);
201
+ touch-action: none;
202
+ }
203
+
204
+ .p-gui__vector2-line {
205
+ position: absolute;
206
+ background: white;
207
+ opacity: .3;
208
+ pointer-events: none;
209
+ }
210
+
211
+ .p-gui__vector2-line-x {
212
+ width: 100%;
213
+ height: 1px;
214
+ left: 0;
215
+ top: 50%;
216
+ transform: translateY(-50%);
217
+ }
218
+
219
+ .p-gui__vector2-line-y {
220
+ width: 1px;
221
+ height: 100%;
222
+ top: 0;
223
+ left: 50%;
224
+ transform: translateX(-50%);
225
+ }
226
+
227
+ .p-gui__vector2-dot {
228
+ position: absolute;
229
+ top: 0;
230
+ left: 0;
231
+ width: 8px;
232
+ height: 8px;
233
+ border-radius: 50%;
234
+ background: #d5d5d5;
235
+ border: 2px solid #ff9999;
236
+ transform: translate(-50%, -50%);
237
+ pointer-events: none;
238
+ }
239
+
240
+ .p-gui__switch-checkbox {
241
+ width: 5px;
242
+ height: 5px;
243
+ background-color: rgba(0, 0, 0, .5);
244
+ border: 1px solid grey;
245
+ position: absolute;
246
+ top: 0;
247
+ right: 10px;
248
+ bottom: 0;
249
+ margin: auto;
250
+ border-radius: 50%;
251
+ pointer-events: none;
252
+ }
253
+
254
+ .p-gui__switch-checkbox--active {
255
+ background-color: #00ff89;
256
+ box-shadow: 0 0 7px #00ff89;
257
+ }
258
+
259
+ .p-gui__list,
260
+ .p-gui__color {
261
+ cursor: default;
262
+ }
263
+
264
+ .p-gui__list-dropdown,
265
+ .p-gui__color-picker {
266
+ position: absolute;
267
+ right: 5px;
268
+ top: 0;
269
+ bottom: 0;
270
+ margin: auto;
271
+ height: 21px;
272
+ cursor: pointer;
273
+ border-radius: 3px;
274
+ border: 1px solid var(--color-border-2);
275
+ }
276
+
277
+ .p-gui__list-dropdown {
278
+ background: rgba(255, 255, 255,.05);
279
+ color: white;
280
+ padding: 0 12px;
281
+ top: 0px;
282
+ }
283
+
284
+ .p-gui__list-dropdown:hover {
285
+ background: rgba(255, 255, 255, .1);
286
+ }
287
+
288
+ .p-gui__color-picker {
289
+ -webkit-appearance: none;
290
+ padding: 0;
291
+ background-color: transparent;
292
+ border: 1px solid #222222;
293
+ overflow: hidden;
294
+ }
295
+
296
+ .p-gui__color-picker::-webkit-color-swatch-wrapper {
297
+ padding: 0;
298
+ }
299
+ .p-gui__color-picker::-webkit-color-swatch {
300
+ border: none;
301
+ }
302
+
303
+ .p-gui__slider {
304
+ width: 100%;
305
+ margin-bottom: 8px;
306
+ padding: 7px;
307
+ color: white;
308
+ position: relative;
309
+ min-height: 14px;
310
+ }
311
+
312
+ .p-gui__slider-ctrl {
313
+ -webkit-appearance: none;
314
+ padding: 0;
315
+ font: inherit;
316
+ outline: none;
317
+ opacity: .8;
318
+ background: var(--color-accent);
319
+ box-sizing: border-box;
320
+ cursor: pointer;
321
+ position: absolute;
322
+ bottom: -4px; /* 5px height -1px de dépassement du curseur */
323
+ right: 0;
324
+ height: 5px;
325
+ width: 100%;
326
+ margin: 0;
327
+ }
328
+
329
+ /* la zone de déplacement */
330
+ .p-gui__slider-ctrl::-webkit-slider-runnable-track {
331
+ height: 13px;
332
+ border: none;
333
+ border-radius: 0;
334
+ background-color: transparent; /* supprimé définie sur l'input */
335
+ }
336
+
337
+ /* Curseur */
338
+ .p-gui__slider-ctrl::-webkit-slider-thumb {
339
+ -webkit-appearance: none; /* également nécessaire sur le curseur */
340
+ width: 15px;
341
+ height: 7px;
342
+ border: none; /* pris en compte sur Webkit et Edge */
343
+ background: white; /* pris en compte sur Webkit only */
344
+ position: relative;
345
+ top: 3px;
346
+ border-radius: 1px;
347
+ }
348
+
349
+ .p-gui__slider-value,
350
+ .p-gui__vector-value {
351
+ display: inline-block;
352
+ position: absolute;
353
+ right: 7px;
354
+ }
355
+
356
+ .p-gui__folder {
357
+ width: 100%;
358
+ position: relative;
359
+ background: #434343;
360
+ overflow: auto;
361
+ margin-bottom: 3px;
362
+ display: flex;
363
+ flex-wrap: wrap;
364
+ border-left: 3px solid grey;
365
+ border-bottom: 1px solid grey;
366
+ padding: 0 3px;
367
+ }
368
+
369
+ .p-gui__folder:last-of-type {
370
+ margin-bottom: 0;
371
+ border-bottom: none;
372
+ }
373
+
374
+ .p-gui__folder--first {
375
+ margin-top: 0;
376
+ }
377
+
378
+ .p-gui__folder--closed {
379
+ height: 32px;
380
+ overflow: hidden;
381
+ }
382
+
383
+ .p-gui__folder-header {
384
+ padding: 10px 5px;
385
+ background-color: rgba(0, 0, 0, .5);
386
+ color: white;
387
+ cursor: pointer;
388
+ width: 100%;
389
+ margin: 0 -2px 2px -3px;
390
+ }
391
+
392
+ .p-gui__folder-header:hover {
393
+ background-color: rgba(0, 0, 0, .75);
394
+ }
395
+
396
+ .p-gui__folder-arrow {
397
+ width: 8px;
398
+ height: 8px;
399
+ display: inline-block;
400
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAHlBMVEUAAAD///////////////////////////////////8kfJuVAAAACXRSTlMA9Z1fCdMo1yxEJnA0AAAAK0lEQVQI12PABlRgjKkJUMZMYRhjpgqMAZSEMICSaIzpDWiKhdENhEhgAgATSg5jyWnYewAAAABJRU5ErkJggg==);
401
+ background-size: contain;
402
+ margin-right: 5px;
403
+ transform: rotate(90deg)
404
+ }
405
+
406
+ .p-gui__folder--closed .p-gui__folder-arrow {
407
+ transform: rotate(0deg);
408
+ }
409
+ `}class c{constructor(e={}){if(e.container?(this.container=typeof e.container=="string"?document.querySelector(e.container):e.container,this.position_type="absolute"):(this.container=document.body,this.position_type="fixed"),this.propReferences=[],this.folders=[],e.isFolder){this._folderConstructor(e.folderOptions);return}this.name=e!=null&&typeof e.name=="string"?e.name:"",this.backgroundColor=e.color||null,this.container==document.body?this.maxHeight=window.innerHeight:this.maxHeight=Math.min(this.container.clientHeight,window.innerHeight),e.maxHeight&&(this.initMaxHeight=e.maxHeight,this.maxHeight=Math.min(this.initMaxHeight,this.maxHeight)),this.screenCorner=this._parseScreenCorner(e.position),this instanceof c&&(typeof c[c.instanceCounter]!="number"?c[c.instanceCounter]=0:c[c.instanceCounter]++),this.instanceId=c[c.instanceCounter],this.wrapperWidth=e.width||290,this.stylesheet=document.createElement("style"),this.stylesheet.setAttribute("type","text/css"),this.stylesheet.setAttribute("id","lm-gui-stylesheet"),document.head.append(this.stylesheet),this.instanceId==0&&this._addStyles(`${_(this.position_type)}`),this._styleInstance(),this._addWrapper(),this.wrapper.setAttribute("data-corner-x",this.screenCorner.x),this.wrapper.setAttribute("data-corner-y",this.screenCorner.y),e.autoRepositioning!=!1&&window.addEventListener("resize",this._handleResize.bind(this)),this._handleResize(),this.hasBeenDragged=!1,e.draggable==!0&&this._makeDraggable(),this.closed=!1,e.closed&&this.toggleClose()}_styleInstance(){let e=this._getScrollbarWidth(this.container);if(this.screenCorner.x=="left"?this.xOffset=0:this.xOffset=this.container.clientWidth-this.wrapperWidth-e,this.instanceId>0){let t=this.container.querySelectorAll(".p-gui");for(let i=0;i<t.length;i++)this.screenCorner.y==t[i].dataset.cornerY&&(this.screenCorner.x=="left"&&t[i].dataset.cornerX=="left"?this.xOffset+=t[i].offsetWidth:this.screenCorner.x=="right"&&t[i].dataset.cornerX=="right"&&(this.xOffset-=t[i].offsetWidth))}this.yOffset=0,this.position={prevX:this.xOffset,prevY:this.yOffset,x:this.xOffset,y:this.yOffset},this._addStyles(`#p-gui-${this.instanceId} {
410
+ width: ${this.wrapperWidth}px;
411
+ max-height: ${this.maxHeight}px;
412
+ transform: translate3d(${this.xOffset}px,${this.yOffset}px,0);
413
+ ${this.screenCorner.y=="top"?"":"top: auto; bottom: 0;"}
414
+ ${this.backgroundColor?"background: "+this.backgroundColor+";":""}
415
+ }`)}_folderConstructor(e){this.wrapper=e.wrapper}_parseScreenCorner(e){let t={x:"right",y:"top"};return e==null||(typeof e!="string"&&console.error("[perfect-gui] Position must be a string."),e.includes("left")&&(t.x="left"),e.includes("bottom")&&(t.y="bottom")),t}_getScrollbarWidth(e){return e===document.body?window.innerWidth-document.documentElement.clientWidth:e.offsetWidth-e.clientWidth}_handleResize(){if(this.container==document.body?this.maxHeight=window.innerHeight:this.maxHeight=Math.min(this.container.clientHeight,window.innerHeight),this.initMaxHeight&&(this.maxHeight=Math.min(this.initMaxHeight,this.maxHeight)),this.wrapper.style.maxHeight=this.maxHeight+"px",this.hasBeenDragged)return;let e=this._getScrollbarWidth(this.container);if(this.xOffset=this.screenCorner.x=="left"?0:this.container.clientWidth-this.wrapperWidth-e,this.instanceId>0){let t=this.container.querySelectorAll(`.p-gui:not(#${this.wrapper.id}):not([data-dragged])`);for(let i=0;i<t.length&&!(parseInt(t[i].id.replace("p-gui-",""))>this.instanceId);i++)this.screenCorner.y==t[i].dataset.cornerY&&(this.screenCorner.x=="left"&&t[i].dataset.cornerX=="left"?this.xOffset+=t[i].offsetWidth:this.screenCorner.x=="right"&&t[i].dataset.cornerX=="right"&&(this.xOffset-=t[i].offsetWidth))}this.position={prevX:this.xOffset,prevY:this.yOffset,x:this.xOffset,y:this.yOffset},this.wrapper.style.transform=`translate3d(${this.position.x}px, ${this.position.y}px, 0)`}_createElement(e){e.el=e.el||"div";var t=document.createElement(e.el);if(e.id&&(t.id=e.id),e.class&&(t.className=e.class),e.inline&&(t.style=e.inline),e.href&&(t.href=e.href),e.onclick&&(t.onclick=e.onclick),e.onchange&&(t.onchange=e.onchange),e.textContent&&(t.textContent=e.textContent),e.innerHTML&&(t.innerHTML=e.innerHTML),e.type&&(t.type=e.type),e.value&&(t.value=e.value),e.customAttributes)for(var i in e.customAttributes)t.setAttribute(i,e.customAttributes[i]);return e.parent=e.parent?e.parent:this.wrapper,e.parent.append(t),t}_addStyles(e){this.stylesheet.innerHTML+=e}_addWrapper(){this.wrapper=this._createElement({parent:this.container,id:"p-gui-"+this.instanceId,class:"p-gui"}),this.header=this._createElement({parent:this.wrapper,class:"p-gui__header",textContent:this.name,inline:`${this.backgroundColor?"border-color: "+this.backgroundColor+";":""}`}),this._createElement({parent:this.header,class:"p-gui__header-close",onclick:this.toggleClose.bind(this)})}button(e,t){let i="";typeof e!="string"?typeof e=="object"&&(e!=null&&e.hasOwnProperty("name"))?i=e.name==""?" ":e.name:i=" ":i=e==""?" ":e,this.imageContainer=null,typeof t!="function"&&(t=()=>{});const r=this._createElement({class:"p-gui__button",textContent:i,onclick:t});typeof e.color=="string"&&(r.style.setProperty("--color-accent",e.color),r.style.setProperty("--color-accent-hover",e.hoverColor||e.color))}image(e={},t){if(typeof e!="object")throw Error(`[GUI] image() first parameter must be an object. Received: ${typeof e}.`);let i;if(typeof e.path=="string")i=e.path;else throw typeof e.path==null?Error("[GUI] image() path must be provided."):Error("[GUI] image() path must be a string.");let r=i.replace(/^.*[\\\/]/,""),o;e.name==null?o=r:o=typeof e.name=="string"&&e.name||" ";const s=e.selected===!0,n=e.selectionBorder!==!1;this.imageContainer||(this.imageContainer=this._createElement({class:"p-gui__image-container"}));var a=this._createElement({class:"p-gui__image",inline:`background-image: url(${i})`,parent:this.imageContainer});s&&n&&a.classList.add("p-gui__image--selected"),this._createElement({parent:a,class:"p-gui__image-text",textContent:o}),typeof t=="function"&&(a.onclick=()=>{let l=this.imageContainer.querySelectorAll(".p-gui__image--selected");for(let g=0;g<l.length;g++)l[g].classList.remove("p-gui__image--selected");n&&a.classList.add("p-gui__image--selected"),t({path:i,text:o})})}slider(e={},t){if(typeof e!="object")throw Error(`[GUI] slider() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"&&e.name||" ",r=!1,o=null,s=e.obj||e.object,n=e.prop||e.property,a=typeof e.value=="number"?e.value:null,l=e.min??0,g=e.max??1,u=e.step||(g-l)/100;if(a!==null)(n!=null||s!=null)&&console.warn('[GUI] slider() "obj" and "property" parameters are ignored when a "value" parameter is used.');else if(n!=null&&s!=null){if(typeof n!="string")throw Error(`[GUI] slider() "prop" (or "property") parameter must be an string. Received: ${typeof n}.`);if(typeof s!="object")throw Error(`[GUI] slider() "obj" (or "object") parameter must be an object. Received: ${typeof s}.`);i==" "&&(i=n),o=this.propReferences.push(s[n])-1,r=!0}else(n!=null&&s==null||n==null&&s==null)&&console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'),a=(g-l)/2;this.imageContainer=null;var h=this._createElement({class:"p-gui__slider",textContent:i}),f=this._createElement({parent:h,el:"input",class:"p-gui__slider-ctrl",customAttributes:{type:"range",min:l,max:g,step:u,value:r?s[n]:a}}),x=this._createElement({parent:h,class:"p-gui__slider-value",textContent:String(r?s[n]:a)});f.addEventListener("input",()=>{x.textContent=f.value,r&&(s[n]=f.value),typeof t=="function"&&t(parseFloat(f.value))}),r&&Object.defineProperty(s,n,{set:b=>{this.propReferences[o]=b,f.value=b,x.textContent=String(b)},get:()=>this.propReferences[o]})}toggle(e={},t){if(typeof e!="object")throw Error(`[GUI] toggle() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"&&e.name||" ",r=e.value===!0;this.imageContainer=null;let o=this._createElement({class:"p-gui__switch",onclick:n=>{let a=n.target.childNodes[1],l=!0;a.classList.contains("p-gui__switch-checkbox--active")&&(l=!1),a.classList.toggle("p-gui__switch-checkbox--active"),typeof t=="function"&&t(l)},textContent:i}),s=r?" p-gui__switch-checkbox--active":"";this._createElement({parent:o,class:"p-gui__switch-checkbox"+s})}list(e={},t){if(typeof e!="object")throw Error(`[GUI] list() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"?e.name:" ",r=Array.isArray(e.values)?e.values:null;t=typeof t=="function"?t:null,this.imageContainer=null;let o=this._createElement({class:"p-gui__list",textContent:i}),s=this._createElement({parent:o,el:"select",class:"p-gui__list-dropdown",onchange:n=>{t&&t(n.target.value)}});r.forEach(n=>{this._createElement({parent:s,el:"option",customAttributes:{value:n},textContent:n})})}options(e,t){if(typeof e!="object")throw Error(`[GUI] options() first parameter must be an object. Received: ${typeof e}.`);this.list(e,t)}vector2(e={},t){if(typeof e!="object")throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"&&e.name||" ";const r=e.x.min??0,o=e.x.max??1,s=e.y.min??0,n=e.y.max??1,a=e.x.obj||e.x.object,l=e.x.prop||e.x.property,g=this.propReferences.push(a[l])-1,u=e.y.obj||e.y.object,h=e.y.prop||e.y.property,f=this.propReferences.push(u[h])-1;t=typeof t=="function"?t:null,this.imageContainer=null;const x=this._createElement({class:"p-gui__vector2",textContent:i}),b=this._createElement({parent:x,class:"p-gui__vector-value",textContent:a[l]+", "+u[h]}),p=this._createElement({parent:x,el:"div",class:"p-gui__vector2-area",onclick:d=>{a[l]=parseFloat(this._mapLinear(d.offsetX,0,p.clientWidth,r,o).toFixed(2)),u[h]=parseFloat(this._mapLinear(d.offsetY,0,p.clientHeight,n,s).toFixed(2)),t&&t(a[l],a[h])}});let y=!1;p.addEventListener("pointerdown",d=>{y=!0}),p.addEventListener("pointerup",()=>{y=!1}),p.addEventListener("pointermove",d=>{y&&(a[l]=parseFloat(this._mapLinear(d.offsetX,0,p.clientWidth,r,o).toFixed(2)),u[h]=parseFloat(this._mapLinear(d.offsetY,0,p.clientHeight,n,s).toFixed(2)),t&&t(a[l],a[h]))}),this._createElement({parent:p,class:"p-gui__vector2-line p-gui__vector2-line-x"}),this._createElement({parent:p,class:"p-gui__vector2-line p-gui__vector2-line-y"});const m=this._createElement({parent:p,class:"p-gui__vector2-dot"});m.style.left=this._mapLinear(a[l],r,o,0,p.clientWidth)+"px",m.style.top=this._mapLinear(u[h],s,n,p.clientHeight,0)+"px",Object.defineProperty(a,l,{set:d=>{this.propReferences[g]=d,m.style.left=this._mapLinear(d,r,o,0,p.clientWidth)+"px",b.textContent=String(d)+", "+u[h]},get:()=>this.propReferences[g]}),Object.defineProperty(u,h,{set:d=>{this.propReferences[f]=d,m.style.top=this._mapLinear(d,s,n,p.clientHeight,0)+"px",b.textContent=a[l]+", "+String(d)},get:()=>this.propReferences[f]})}color(e={},t){if(typeof e!="object")throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"&&e.name||" ",r;typeof e.value=="string"&&(e.value.length!=7||e.value[0]!="#"?console.error(`[GUI] color() 'value' parameter must be an hexadecimal string in the format "#ffffff". Received: "${e.value}".`):r=e.value),r||(r="#000000");const o=this._createElement({el:"div",class:"p-gui__color",textContent:i}),s=this._createElement({parent:o,el:"input",class:"p-gui__color-picker",type:"color",value:r});typeof t=="function"&&s.addEventListener("input",()=>{t(s.value)})}folder(e={}){let t=typeof e.closed=="boolean"?e.closed:!1,i=e.name||"",r=e.color||null,o=e.maxHeight||null;this.imageContainer=null;let s="p-gui__folder";this.folders.length==0&&(s+=" p-gui__folder--first"),t&&(s+=" p-gui__folder--closed");let n=r?`background-color: ${r};`:"";n+=o?`max-height: ${o}px;`:"";let a=this._createElement({class:s,inline:n});this._createElement({innerHTML:`<span class="p-gui__folder-arrow"></span>${i}`,class:"p-gui__folder-header",onclick:function(){this.parentNode.classList.toggle("p-gui__folder--closed")},parent:a});let l=new c({isFolder:!0,folderOptions:{wrapper:a}});return this.folders.push(l),l}_makeDraggable(){var e=this;this.header.addEventListener("pointerdown",t),this.header.addEventListener("pointerup",r);function t(o){o.preventDefault(),e.position.initX=e.position.x,e.position.initY=e.position.y,e.position.prevX=o.clientX,e.position.prevY=o.clientY,document.addEventListener("pointermove",i)}function i(o){o.preventDefault(),e.hasBeenDragged||(e.hasBeenDragged=!0,e.wrapper.setAttribute("data-dragged","true")),e.position.x=e.position.initX+o.clientX-e.position.prevX,e.position.y=e.position.initY+o.clientY-e.position.prevY,e.wrapper.style.transform="translate3d("+e.position.x+"px,"+e.position.y+"px,0)"}function r(o){document.removeEventListener("pointermove",i)}}toggleClose(){this.closed=!this.closed,this.wrapper.classList.toggle("p-gui--collapsed")}kill(){this.wrapper.remove()}_mapLinear(e,t,i,r,o){return r+(e-t)*(o-r)/(i-t)}}return c});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perfect-gui",
3
- "version": "4.2.3",
3
+ "version": "4.3.1",
4
4
  "description": "Nice and simple GUI for JavaScript",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
package/src/index.js CHANGED
@@ -286,6 +286,9 @@ export default class GUI {
286
286
  } else {
287
287
  name = typeof params.name == 'string' ? params.name || ' ' : ' ';
288
288
  }
289
+
290
+ const selected = params.selected === true;
291
+ const selectionBorder = params.selectionBorder !== false;
289
292
 
290
293
  if (!this.imageContainer) {
291
294
  this.imageContainer = this._createElement({
@@ -299,6 +302,10 @@ export default class GUI {
299
302
  inline: `background-image: url(${path})`,
300
303
  parent: this.imageContainer
301
304
  })
305
+
306
+ if (selected && selectionBorder) {
307
+ image.classList.add('p-gui__image--selected');
308
+ }
302
309
 
303
310
  // Text inside image
304
311
  this._createElement({
@@ -308,7 +315,16 @@ export default class GUI {
308
315
  })
309
316
 
310
317
  if (typeof callback == 'function') {
311
- image.onclick = () => callback({ path, text: name });
318
+ image.onclick = () => {
319
+ let selected = this.imageContainer.querySelectorAll('.p-gui__image--selected');
320
+ for (let i = 0; i < selected.length; i++) {
321
+ selected[i].classList.remove('p-gui__image--selected');
322
+ }
323
+ if (selectionBorder) {
324
+ image.classList.add('p-gui__image--selected');
325
+ }
326
+ callback({ path, text: name });
327
+ };
312
328
  }
313
329
  }
314
330
 
package/src/styles.js CHANGED
@@ -113,6 +113,19 @@ export default function( position_type ) {
113
113
  position: relative;
114
114
  margin-top: 1px;
115
115
  margin-bottom: 19px;
116
+ border-radius: var(--main-border-radius);
117
+ }
118
+
119
+ .p-gui__image--selected::after {
120
+ position: absolute;
121
+ top: 0;
122
+ left: 0;
123
+ width: 100%;
124
+ height: 100%;
125
+ content: '';
126
+ border: 1px solid #06FF89;
127
+ box-sizing: border-box;
128
+ border-radius: var(--main-border-radius);
116
129
  }
117
130
 
118
131
  .p-gui__image-text {