perfect-gui 4.11.5 → 4.11.7

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.
@@ -1,4 +1,4 @@
1
- class k {
1
+ class C {
2
2
  constructor(e, t = {}, i) {
3
3
  if (this.parent = e, this.propReferences = [], typeof t != "object")
4
4
  throw Error(`[GUI] slider() first parameter must be an object. Received: ${typeof t}.`);
@@ -6,8 +6,8 @@ class k {
6
6
  this.isObject = !1;
7
7
  let s = null;
8
8
  this.obj = t.obj, this.prop = t.prop;
9
- let n = typeof t.value == "number" ? t.value : null;
10
- if (this.min = t.min ?? 0, this.max = t.max ?? 1, this.step = t.step || (this.max - this.min) / 100, this.callback = typeof i == "function" ? i : null, n !== null)
9
+ let r = typeof t.value == "number" ? t.value : null;
10
+ if (this.min = t.min ?? 0, this.max = t.max ?? 1, this.step = t.step || (this.max - this.min) / 100, this.decimals = this.parent._countDecimals(this.step), this.callback = typeof i == "function" ? i : null, r !== null)
11
11
  (this.prop != null || this.obj != null) && console.warn('[GUI] slider() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
12
12
  else if (this.prop != null && this.obj != null) {
13
13
  if (typeof this.prop != "string")
@@ -16,17 +16,17 @@ class k {
16
16
  throw Error(`[GUI] slider() "obj" parameter must be an object. Received: ${typeof this.obj}.`);
17
17
  a == " " && (a = this.prop), s = this.propReferences.push(this.obj[this.prop]) - 1, this.isObject = !0;
18
18
  } else
19
- (this.prop != null && this.obj == null || this.prop == null && this.obj != null) && console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'), n = (this.max - this.min) / 2;
19
+ (this.prop != null && this.obj == null || this.prop == null && this.obj != null) && console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'), r = (this.max - this.min) / 2;
20
20
  const o = typeof t.tooltip == "string" ? t.tooltip : t.tooltip === !0 ? a : null;
21
21
  this.imageContainer = null;
22
- const r = document.createElement("div");
23
- r.className = "p-gui__slider", o && r.setAttribute("title", o);
24
- const p = document.createElement("div");
25
- p.className = "p-gui__slider-name", p.textContent = a, r.append(p), this.ctrlDiv = document.createElement("div"), this.ctrlDiv.className = "p-gui__slider-ctrl", this.ctrlDiv.setAttribute("type", "range"), this.ctrlDiv.setAttribute("min", this.min), this.ctrlDiv.setAttribute("max", this.max), r.append(this.ctrlDiv);
22
+ const n = document.createElement("div");
23
+ n.className = "p-gui__slider", o && n.setAttribute("title", o);
24
+ const c = document.createElement("div");
25
+ c.className = "p-gui__slider-name", c.textContent = a, n.append(c), this.ctrlDiv = document.createElement("div"), this.ctrlDiv.className = "p-gui__slider-ctrl", this.ctrlDiv.setAttribute("type", "range"), this.ctrlDiv.setAttribute("min", this.min), this.ctrlDiv.setAttribute("max", this.max), n.append(this.ctrlDiv);
26
26
  const l = document.createElement("div");
27
- return l.className = "p-gui__slider-bar", this.ctrlDiv.append(l), this.handle = document.createElement("div"), this.handle.className = "p-gui__slider-handle", this.ctrlDiv.append(this.handle), this.filling = document.createElement("div"), this.filling.className = "p-gui__slider-filling", l.append(this.filling), this.valueInput = document.createElement("input"), this.valueInput.className = "p-gui__slider-value", this.valueInput.value = this.isObject ? this.obj[this.prop] : n, r.append(this.valueInput), setTimeout(() => {
27
+ return l.className = "p-gui__slider-bar", this.ctrlDiv.append(l), this.handle = document.createElement("div"), this.handle.className = "p-gui__slider-handle", this.ctrlDiv.append(this.handle), this.filling = document.createElement("div"), this.filling.className = "p-gui__slider-filling", l.append(this.filling), this.valueInput = document.createElement("input"), this.valueInput.className = "p-gui__slider-value", this.valueInput.value = this.isObject ? this.obj[this.prop] : r, n.append(this.valueInput), setTimeout(() => {
28
28
  const d = this.handle.offsetWidth;
29
- this.handle.position = this._mapLinear(this.valueInput.value, this.min, this.max, d / 2, 88 - d / 2), this.handle.style.transform = `translate(-50%, -50%) translateX(${this.handle.position}px)`, this.filling.style.width = `${this.handle.position}px`;
29
+ this.handle.position = this._mapLinear(this.valueInput.value, this.min, this.max, d / 2, 88 - d / 2), this.handle.position = Math.min(this.handle.position, 88 - d / 2), this.handle.position = Math.max(this.handle.position, d / 2), this.handle.style.transform = `translate(-50%, -50%) translateX(${this.handle.position}px)`, this.filling.style.width = `${this.handle.position}px`;
30
30
  }, 0), this.valueInput.addEventListener("change", () => {
31
31
  this._updateHandlePositionFromValue(), this._triggerCallbacks();
32
32
  }), this.ctrlDiv.addEventListener("pointerdown", (d) => {
@@ -40,23 +40,16 @@ class k {
40
40
  this.propReferences[s] = d, this.valueInput.value = d, this._updateHandlePositionFromValue(), this.callback && this.callback(parseFloat(this.valueInput.value));
41
41
  },
42
42
  get: () => this.propReferences[s]
43
- }), r;
43
+ }), n;
44
44
  }
45
45
  _updateHandlePositionFromPointer(e, t = !1) {
46
- const i = this.ctrlDiv.offsetWidth, a = this.handle.offsetWidth, s = e.clientX - this.ctrlDiv.prevPosition, n = parseFloat(this.valueInput.value);
46
+ const i = this.ctrlDiv.offsetWidth, a = this.handle.offsetWidth, s = e.clientX - this.ctrlDiv.prevPosition, r = parseFloat(this.valueInput.value);
47
47
  let o;
48
48
  t ? o = e.offsetX : o = this.handle.position + s, o = Math.max(a / 2, Math.min(o, i - a / 2));
49
- let r = this.min + (this.max - this.min) * (o - a / 2) / (i - a);
50
- r > n ? r = this._quantizeFloor(r, this.step) : r = this._quantizeCeil(r, this.step), r = parseFloat(r.toFixed(9));
51
- const p = parseFloat((n + this.step).toFixed(9)), l = parseFloat((n - this.step).toFixed(9));
52
- if (r >= p || r <= l) {
53
- const d = this._countDecimals(this.step);
54
- r = r.toFixed(d), this.valueInput.value = r, this.ctrlDiv.prevPosition = e.clientX, this.handle.style.transform = `translate(-50%, -50%) translateX(${o}px)`, this.handle.position = o, this.filling.style.width = this.handle.position + "px", this._triggerCallbacks();
55
- }
56
- }
57
- _countDecimals(e) {
58
- const t = e.toString(), i = t.indexOf(".");
59
- return i === -1 ? 0 : t.length - i - 1;
49
+ let n = this.min + (this.max - this.min) * (o - a / 2) / (i - a);
50
+ n > r ? n = this._quantizeFloor(n, this.step) : n = this._quantizeCeil(n, this.step), n = parseFloat(n.toFixed(9));
51
+ const c = parseFloat((r + this.step).toFixed(9)), l = parseFloat((r - this.step).toFixed(9));
52
+ (n >= c || n <= l) && (n = n.toFixed(this.decimals), this.valueInput.value = n, this.ctrlDiv.prevPosition = e.clientX, this.handle.style.transform = `translate(-50%, -50%) translateX(${o}px)`, this.handle.position = o, this.filling.style.width = this.handle.position + "px", this._triggerCallbacks());
60
53
  }
61
54
  _updateHandlePositionFromValue() {
62
55
  const e = this.ctrlDiv.offsetWidth, t = this.handle.offsetWidth;
@@ -79,7 +72,50 @@ class k {
79
72
  return t * Math.floor(e / t);
80
73
  }
81
74
  }
82
- const E = (
75
+ function R(f = {}, e) {
76
+ if (typeof f != "object")
77
+ throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof f}.`);
78
+ let t = typeof f.name == "string" && f.name || " ";
79
+ const i = f.x.min ?? 0, a = f.x.max ?? 1, s = f.y.min ?? 0, r = f.y.max ?? 1, o = f.x.step || (a - i) / 100, n = f.y.step || (r - s) / 100, c = this._countDecimals(o), l = this._countDecimals(n), d = f.x.obj, h = f.x.prop, g = this.propReferences.push(d[h]) - 1, p = f.y.obj, u = f.y.prop, v = this.propReferences.push(p[u]) - 1, x = typeof f.tooltip == "string" ? f.tooltip : f.tooltip === !0 ? t : null;
80
+ e = typeof e == "function" ? e : null, this.imageContainer = null;
81
+ const _ = document.createElement("div");
82
+ _.className = "p-gui__vector2", _.textContent = t, x && _.setAttribute("title", x), this.wrapper.append(_);
83
+ const w = document.createElement("div");
84
+ w.className = "p-gui__vector-value", w.textContent = d[h] + ", " + p[u], _.append(w);
85
+ const b = document.createElement("div");
86
+ b.className = "p-gui__vector2-area", _.append(b), b.addEventListener("click", (m) => {
87
+ const k = parseFloat(this._mapLinear(m.offsetX, 0, b.clientWidth, i, a)), E = parseFloat(this._mapLinear(m.offsetY, 0, b.clientHeight, r, s));
88
+ d[h] = k.toFixed(c), p[u] = E.toFixed(l), e && e(d[h], d[u]), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
89
+ });
90
+ let A = !1;
91
+ b.addEventListener("pointerdown", (m) => {
92
+ A = !0;
93
+ }), b.addEventListener("pointerup", () => {
94
+ A = !1;
95
+ }), b.addEventListener("pointermove", (m) => {
96
+ if (A) {
97
+ const k = parseFloat(this._mapLinear(m.offsetX, 0, b.clientWidth, i, a)), E = parseFloat(this._mapLinear(m.offsetY, 0, b.clientHeight, r, s));
98
+ d[h] = k.toFixed(c), p[u] = E.toFixed(l), e && e(d[h], d[u]), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
99
+ }
100
+ });
101
+ const U = document.createElement("div");
102
+ U.className = "p-gui__vector2-line p-gui__vector2-line-x", b.append(U);
103
+ const j = document.createElement("div");
104
+ j.className = "p-gui__vector2-line p-gui__vector2-line-y", b.append(j);
105
+ const y = document.createElement("div");
106
+ y.className = "p-gui__vector2-dot", b.append(y), y.style.left = this._mapLinear(d[h], i, a, 0, b.clientWidth) + "px", y.style.top = this._mapLinear(p[u], s, r, b.clientHeight, 0) + "px", Object.defineProperty(d, h, {
107
+ set: (m) => {
108
+ this.propReferences[g] = m, y.style.left = this._mapLinear(m, i, a, 0, b.clientWidth) + "px", w.textContent = String(m) + ", " + p[u];
109
+ },
110
+ get: () => this.propReferences[g]
111
+ }), Object.defineProperty(p, u, {
112
+ set: (m) => {
113
+ this.propReferences[v] = m, y.style.top = this._mapLinear(m, s, r, b.clientHeight, 0) + "px", w.textContent = d[h] + ", " + String(m);
114
+ },
115
+ get: () => this.propReferences[v]
116
+ });
117
+ }
118
+ const P = (
83
119
  /* css */
84
120
  `
85
121
  .p-gui__button {
@@ -102,7 +138,7 @@ const E = (
102
138
  margin-inline: 0;
103
139
  }
104
140
  `
105
- ), U = (
141
+ ), O = (
106
142
  /* css */
107
143
  `
108
144
  .p-gui__slider {
@@ -196,7 +232,7 @@ const E = (
196
232
  outline: none;
197
233
  }
198
234
  `
199
- ), j = (
235
+ ), $ = (
200
236
  /* css */
201
237
  `
202
238
  .p-gui__list {
@@ -233,7 +269,7 @@ const E = (
233
269
  background: rgba(255, 255, 255, .1);
234
270
  }
235
271
  `
236
- ), I = (
272
+ ), D = (
237
273
  /* css */
238
274
  `
239
275
  .p-gui__switch {
@@ -270,7 +306,7 @@ const E = (
270
306
  box-shadow: 0 0 7px #00ff89;
271
307
  }
272
308
  `
273
- ), C = (
309
+ ), F = (
274
310
  /* css */
275
311
  `
276
312
  .p-gui__color {
@@ -308,7 +344,7 @@ const E = (
308
344
  border: none;
309
345
  }
310
346
  `
311
- ), R = (
347
+ ), L = (
312
348
  /* css */
313
349
  `
314
350
  .p-gui__vector2 {
@@ -373,7 +409,7 @@ const E = (
373
409
  position: absolute;
374
410
  }
375
411
  `
376
- ), P = (
412
+ ), H = (
377
413
  /* css */
378
414
  `
379
415
  .p-gui__image-container {
@@ -429,7 +465,7 @@ const E = (
429
465
 
430
466
  }
431
467
  `
432
- ), O = (
468
+ ), N = (
433
469
  /* css */
434
470
  `
435
471
  .p-gui__folder {
@@ -483,7 +519,7 @@ const E = (
483
519
  }
484
520
  `
485
521
  );
486
- function $(w) {
522
+ function M(f) {
487
523
  return (
488
524
  /* css */
489
525
  `
@@ -498,7 +534,7 @@ function $(w) {
498
534
  --color-accent-hover: #218fda;
499
535
  --transition: .1s linear;
500
536
 
501
- position: ${w};
537
+ position: ${f};
502
538
  top: 0;
503
539
  left: 0;
504
540
  transform: translate3d(0,0,0);
@@ -616,31 +652,31 @@ function $(w) {
616
652
  border-color: rgba(255,255,255,.2);
617
653
  }
618
654
 
619
- ${E}
620
-
621
655
  ${P}
622
656
 
623
- ${j}
657
+ ${H}
624
658
 
625
- ${I}
659
+ ${$}
660
+
661
+ ${D}
626
662
 
627
- ${U}
663
+ ${O}
628
664
 
629
- ${C}
665
+ ${F}
630
666
 
631
- ${R}
667
+ ${L}
632
668
 
633
- ${O}
669
+ ${N}
634
670
  `
635
671
  );
636
672
  }
637
- class A {
673
+ class I {
638
674
  constructor(e = {}) {
639
675
  if (this.firstParent = this, 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) {
640
676
  this._folderConstructor(e.folderOptions);
641
677
  return;
642
678
  }
643
- typeof e.onUpdate == "function" && (this.onUpdate = e.onUpdate), this.name = e != null && typeof e.name == "string" ? e.name : "", this.backgroundColor = e.color || null, this.opacity = e.opacity || 1, 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), window.perfectGUI || (window.perfectGUI = {}), window.perfectGUI.instanceCounter == null ? window.perfectGUI.instanceCounter = 0 : window.perfectGUI.instanceCounter++, this.instanceId = window.perfectGUI.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();
679
+ typeof e.onUpdate == "function" && (this.onUpdate = e.onUpdate), this.name = e != null && typeof e.name == "string" ? e.name : "", this.backgroundColor = e.color || null, this.opacity = e.opacity || 1, 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), window.perfectGUI || (window.perfectGUI = {}), window.perfectGUI.instanceCounter == null ? window.perfectGUI.instanceCounter = 0 : window.perfectGUI.instanceCounter++, this.instanceId = window.perfectGUI.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(`${M(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(), this.vector2 = R;
644
680
  }
645
681
  _styleInstance() {
646
682
  let e = this._getScrollbarWidth(this.container);
@@ -712,50 +748,50 @@ class A {
712
748
  throw typeof e.path == null ? Error("[GUI] image() path must be provided.") : Error("[GUI] image() path must be a string.");
713
749
  let a = i.replace(/^.*[\\\/]/, ""), s;
714
750
  e.name == null ? s = a : s = typeof e.name == "string" && e.name || " ";
715
- const n = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null, o = e.selected === !0, r = e.selectionBorder !== !1;
716
- let p = "";
717
- e.width && (typeof e.width == "number" && (e.width += "px"), p += `flex: 0 0 calc(${e.width} - 5px); `), e.height && (typeof e.height == "number" && (e.height += "px"), p += `height: ${e.height}; `), this.imageContainer || (this.imageContainer = document.createElement("div"), this.imageContainer.className = "p-gui__image-container", this.wrapper.append(this.imageContainer));
751
+ const r = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null, o = e.selected === !0, n = e.selectionBorder !== !1;
752
+ let c = "";
753
+ e.width && (typeof e.width == "number" && (e.width += "px"), c += `flex: 0 0 calc(${e.width} - 5px); `), e.height && (typeof e.height == "number" && (e.height += "px"), c += `height: ${e.height}; `), this.imageContainer || (this.imageContainer = document.createElement("div"), this.imageContainer.className = "p-gui__image-container", this.wrapper.append(this.imageContainer));
718
754
  const l = document.createElement("div");
719
- l.className = "p-gui__image", l.style = "background-image: url(" + i + "); " + p, n && l.setAttribute("title", n), this.imageContainer.append(l), o && r && l.classList.add("p-gui__image--selected");
755
+ l.className = "p-gui__image", l.style = "background-image: url(" + i + "); " + c, r && l.setAttribute("title", r), this.imageContainer.append(l), o && n && l.classList.add("p-gui__image--selected");
720
756
  const d = document.createElement("div");
721
757
  return d.className = "p-gui__image-text", d.textContent = s, l.append(d), l.addEventListener("click", () => {
722
- let c = l.parentElement.querySelectorAll(".p-gui__image--selected");
723
- for (let f = 0; f < c.length; f++)
724
- c[f].classList.remove("p-gui__image--selected");
725
- r && l.classList.add("p-gui__image--selected"), typeof t == "function" && t({ path: i, text: s }), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
758
+ let h = l.parentElement.querySelectorAll(".p-gui__image--selected");
759
+ for (let g = 0; g < h.length; g++)
760
+ h[g].classList.remove("p-gui__image--selected");
761
+ n && l.classList.add("p-gui__image--selected"), typeof t == "function" && t({ path: i, text: s }), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
726
762
  }), l;
727
763
  }
728
764
  slider(e = {}, t) {
729
- const i = new k(this, e, t);
765
+ const i = new C(this, e, t);
730
766
  this.wrapper.append(i);
731
767
  }
732
768
  toggle(e = {}, t) {
733
769
  if (typeof e != "object")
734
770
  throw Error(`[GUI] toggle() first parameter must be an object. Received: ${typeof e}.`);
735
- let i = typeof e.name == "string" && e.name || " ", a = !1, s = null, n = e.obj, o = e.prop, r = typeof e.value == "boolean" ? e.value : null;
736
- if (r !== null)
737
- (o != null || n != null) && console.warn('[GUI] toggle() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
738
- else if (o != null && n != null) {
771
+ let i = typeof e.name == "string" && e.name || " ", a = !1, s = null, r = e.obj, o = e.prop, n = typeof e.value == "boolean" ? e.value : null;
772
+ if (n !== null)
773
+ (o != null || r != null) && console.warn('[GUI] toggle() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
774
+ else if (o != null && r != null) {
739
775
  if (typeof o != "string")
740
776
  throw Error(`[GUI] toggle() "prop" parameter must be an string. Received: ${typeof o}.`);
741
- if (typeof n != "object")
742
- throw Error(`[GUI] toggle() "obj" parameter must be an object. Received: ${typeof n}.`);
743
- i == " " && (i = o), s = this.propReferences.push(n[o]) - 1, a = !0;
777
+ if (typeof r != "object")
778
+ throw Error(`[GUI] toggle() "obj" parameter must be an object. Received: ${typeof r}.`);
779
+ i == " " && (i = o), s = this.propReferences.push(r[o]) - 1, a = !0;
744
780
  } else
745
- (o != null && n == null || o == null && n == null) && console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');
746
- const p = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
781
+ (o != null && r == null || o == null && r == null) && console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');
782
+ const c = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
747
783
  this.imageContainer = null;
748
784
  const l = document.createElement("div");
749
- l.textContent = i, l.className = "p-gui__switch", p && l.setAttribute("title", p), this.wrapper.append(l), l.addEventListener("click", (f) => {
750
- const u = f.target.childNodes[1];
751
- let g = !0;
752
- u.classList.contains("p-gui__switch-checkbox--active") && (g = !1), u.classList.toggle("p-gui__switch-checkbox--active"), a ? n[o] = g : typeof t == "function" && t(g), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
785
+ l.textContent = i, l.className = "p-gui__switch", c && l.setAttribute("title", c), this.wrapper.append(l), l.addEventListener("click", (g) => {
786
+ const p = g.target.childNodes[1];
787
+ let u = !0;
788
+ p.classList.contains("p-gui__switch-checkbox--active") && (u = !1), p.classList.toggle("p-gui__switch-checkbox--active"), a ? r[o] = u : typeof t == "function" && t(u), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
753
789
  });
754
- let d = (() => a ? n[o] ? " p-gui__switch-checkbox--active" : "" : r ? " p-gui__switch-checkbox--active" : "")();
755
- const c = document.createElement("div");
756
- c.className = "p-gui__switch-checkbox" + d, l.append(c), a && Object.defineProperty(n, o, {
757
- set: (f) => {
758
- this.propReferences[s] = f, f ? c.classList.add("p-gui__switch-checkbox--active") : c.classList.remove("p-gui__switch-checkbox--active"), typeof t == "function" && t(f);
790
+ let d = (() => a ? r[o] ? " p-gui__switch-checkbox--active" : "" : n ? " p-gui__switch-checkbox--active" : "")();
791
+ const h = document.createElement("div");
792
+ h.className = "p-gui__switch-checkbox" + d, l.append(h), a && Object.defineProperty(r, o, {
793
+ set: (g) => {
794
+ this.propReferences[s] = g, g ? h.classList.add("p-gui__switch-checkbox--active") : h.classList.remove("p-gui__switch-checkbox--active"), typeof t == "function" && t(g);
759
795
  },
760
796
  get: () => this.propReferences[s]
761
797
  });
@@ -763,115 +799,76 @@ class A {
763
799
  list(e = {}, t) {
764
800
  if (typeof e != "object")
765
801
  throw Error(`[GUI] list() first parameter must be an object. Received: ${typeof e}.`);
766
- let i = typeof e.name == "string" ? e.name : " ", a = !1, s = null, n = e.obj, o = e.prop, r = Array.isArray(e.values) ? e.values : null, p, l = typeof r[0] != "string";
802
+ let i = typeof e.name == "string" ? e.name : " ", a = !1, s = null, r = e.obj, o = e.prop, n = Array.isArray(e.values) ? e.values : null, c, l = typeof n[0] != "string";
767
803
  const d = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
768
- if (t = typeof t == "function" ? t : null, e.value !== void 0 || e.value === void 0 && n === void 0 && o === void 0)
769
- (o != null || n != null) && console.warn('[GUI] list() "obj" and "prop" parameters are ignored when a "value" parameter is used.'), p = (() => {
770
- if (!r)
804
+ if (t = typeof t == "function" ? t : null, e.value !== void 0 || e.value === void 0 && r === void 0 && o === void 0)
805
+ (o != null || r != null) && console.warn('[GUI] list() "obj" and "prop" parameters are ignored when a "value" parameter is used.'), c = (() => {
806
+ if (!n)
771
807
  return null;
772
808
  if (typeof e.value == "string")
773
- return r.indexOf(e.value);
809
+ return n.indexOf(e.value);
774
810
  if (typeof e.value == "number")
775
811
  return e.value;
776
812
  })();
777
- else if (o != null && n != null) {
813
+ else if (o != null && r != null) {
778
814
  if (typeof o != "string")
779
815
  throw Error(`[GUI] list() "prop" parameter must be an string. Received: ${typeof o}.`);
780
- if (typeof n != "object")
781
- throw Error(`[GUI] list() "obj" parameter must be an object. Received: ${typeof n}.`);
782
- p = (() => {
783
- if (!r)
816
+ if (typeof r != "object")
817
+ throw Error(`[GUI] list() "obj" parameter must be an object. Received: ${typeof r}.`);
818
+ c = (() => {
819
+ if (!n)
784
820
  return null;
785
- if (typeof n[o] == "string")
786
- return l ? r.find((u) => u.value === n[o]).value : r.indexOf(n[o]);
787
- if (typeof n[o] == "number")
788
- return l ? r.find((u) => u.value === n[o]).value : n[o];
789
- })(), s = this.propReferences.push(n[o]) - 1, a = !0;
821
+ if (typeof r[o] == "string")
822
+ return l ? n.find((p) => p.value === r[o]).value : n.indexOf(r[o]);
823
+ if (typeof r[o] == "number")
824
+ return l ? n.find((p) => p.value === r[o]).value : r[o];
825
+ })(), s = this.propReferences.push(r[o]) - 1, a = !0;
790
826
  } else
791
- (o != null && n == null || o == null && n == null) && console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');
827
+ (o != null && r == null || o == null && r == null) && console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');
792
828
  this.imageContainer = null;
793
- let c = document.createElement("div");
794
- c.className = "p-gui__list", c.textContent = i, d && c.setAttribute("title", d), this.wrapper.append(c);
795
- let f = document.createElement("select");
796
- c.append(f), f.className = "p-gui__list-dropdown", f.addEventListener("change", (u) => {
797
- a ? n[o] = u.target.value : t && t(u.target.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
798
- }), r && r.forEach((u, g) => {
799
- const _ = l ? u.name : u, h = l ? u.value : u;
800
- let x = document.createElement("option");
801
- x.setAttribute("value", h), x.textContent = _, f.append(x), (!l && p == g || l && p == h) && x.setAttribute("selected", "");
802
- }), a && Object.defineProperty(n, o, {
803
- set: (u) => {
804
- let g, _, h;
805
- l ? (h = r.find((v) => v.value == u), _ = (h == null ? void 0 : h.value) || r[0].value, g = r.indexOf(h)) : (typeof u == "string" && (g = r.indexOf(u), _ = u), typeof u == "number" && (g = u, _ = r[u])), this.propReferences[s] = l ? _ : u;
806
- const x = f.querySelector("[selected]");
807
- x && x.removeAttribute("selected"), f.querySelectorAll("option")[g].setAttribute("selected", ""), typeof t == "function" && t(l ? h : _, g);
829
+ let h = document.createElement("div");
830
+ h.className = "p-gui__list", h.textContent = i, d && h.setAttribute("title", d), this.wrapper.append(h);
831
+ let g = document.createElement("select");
832
+ h.append(g), g.className = "p-gui__list-dropdown", g.addEventListener("change", (p) => {
833
+ a ? r[o] = p.target.value : t && t(p.target.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
834
+ }), n && n.forEach((p, u) => {
835
+ const v = l ? p.name : p, x = l ? p.value : p;
836
+ let _ = document.createElement("option");
837
+ _.setAttribute("value", x), _.textContent = v, g.append(_), (!l && c == u || l && c == x) && _.setAttribute("selected", "");
838
+ }), a && Object.defineProperty(r, o, {
839
+ set: (p) => {
840
+ let u, v, x;
841
+ l ? (x = n.find((w) => w.value == p), v = (x == null ? void 0 : x.value) || n[0].value, u = n.indexOf(x)) : (typeof p == "string" && (u = n.indexOf(p), v = p), typeof p == "number" && (u = p, v = n[p])), this.propReferences[s] = l ? v : p;
842
+ const _ = g.querySelector("[selected]");
843
+ _ && _.removeAttribute("selected"), g.querySelectorAll("option")[u].setAttribute("selected", ""), typeof t == "function" && t(l ? x : v, u);
808
844
  },
809
845
  get: () => this.propReferences[s]
810
846
  });
811
847
  }
812
- vector2(e = {}, t) {
813
- if (typeof e != "object")
814
- throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof e}.`);
815
- let i = typeof e.name == "string" && e.name || " ";
816
- const a = e.x.min ?? 0, s = e.x.max ?? 1, n = e.y.min ?? 0, o = e.y.max ?? 1, r = e.x.obj, p = e.x.prop, l = this.propReferences.push(r[p]) - 1, d = e.y.obj, c = e.y.prop, f = this.propReferences.push(d[c]) - 1, u = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
817
- t = typeof t == "function" ? t : null, this.imageContainer = null;
818
- const g = document.createElement("div");
819
- g.className = "p-gui__vector2", g.textContent = i, u && g.setAttribute("title", u), this.wrapper.append(g);
820
- const _ = document.createElement("div");
821
- _.className = "p-gui__vector-value", _.textContent = r[p] + ", " + d[c], g.append(_);
822
- const h = document.createElement("div");
823
- h.className = "p-gui__vector2-area", g.append(h), h.addEventListener("click", (b) => {
824
- r[p] = parseFloat(this._mapLinear(b.offsetX, 0, h.clientWidth, a, s).toFixed(2)), d[c] = parseFloat(this._mapLinear(b.offsetY, 0, h.clientHeight, o, n).toFixed(2)), t && t(r[p], r[c]), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
825
- });
826
- let x = !1;
827
- h.addEventListener("pointerdown", (b) => {
828
- x = !0;
829
- }), h.addEventListener("pointerup", () => {
830
- x = !1;
831
- }), h.addEventListener("pointermove", (b) => {
832
- x && (r[p] = parseFloat(this._mapLinear(b.offsetX, 0, h.clientWidth, a, s).toFixed(2)), d[c] = parseFloat(this._mapLinear(b.offsetY, 0, h.clientHeight, o, n).toFixed(2)), t && t(r[p], r[c]), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate());
833
- });
834
- const v = document.createElement("div");
835
- v.className = "p-gui__vector2-line p-gui__vector2-line-x", h.append(v);
836
- const y = document.createElement("div");
837
- y.className = "p-gui__vector2-line p-gui__vector2-line-y", h.append(y);
838
- const m = document.createElement("div");
839
- m.className = "p-gui__vector2-dot", h.append(m), m.style.left = this._mapLinear(r[p], a, s, 0, h.clientWidth) + "px", m.style.top = this._mapLinear(d[c], n, o, h.clientHeight, 0) + "px", Object.defineProperty(r, p, {
840
- set: (b) => {
841
- this.propReferences[l] = b, m.style.left = this._mapLinear(b, a, s, 0, h.clientWidth) + "px", _.textContent = String(b) + ", " + d[c];
842
- },
843
- get: () => this.propReferences[l]
844
- }), Object.defineProperty(d, c, {
845
- set: (b) => {
846
- this.propReferences[f] = b, m.style.top = this._mapLinear(b, n, o, h.clientHeight, 0) + "px", _.textContent = r[p] + ", " + String(b);
847
- },
848
- get: () => this.propReferences[f]
849
- });
850
- }
851
848
  color(e = {}, t) {
852
849
  if (typeof e != "object")
853
850
  throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof e}.`);
854
- let i = typeof e.name == "string" && e.name || " ", a = !1, s = null, n = e.obj, o = e.prop, r;
855
- const p = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
856
- if (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"), e.value !== void 0)
857
- (o != null || n != null) && console.warn('[GUI] color() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
858
- else if (o != null && n != null) {
851
+ let i = typeof e.name == "string" && e.name || " ", a = !1, s = null, r = e.obj, o = e.prop, n;
852
+ const c = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
853
+ if (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}".`) : n = e.value), n || (n = "#000000"), e.value !== void 0)
854
+ (o != null || r != null) && console.warn('[GUI] color() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
855
+ else if (o != null && r != null) {
859
856
  if (typeof o != "string")
860
857
  throw Error(`[GUI] color() "prop" parameter must be an string. Received: ${typeof o}.`);
861
- if (typeof n != "object")
862
- throw Error(`[GUI] color() "obj" parameter must be an object. Received: ${typeof n}.`);
863
- i == " " && (i = o), s = this.propReferences.push(n[o]) - 1, a = !0;
858
+ if (typeof r != "object")
859
+ throw Error(`[GUI] color() "obj" parameter must be an object. Received: ${typeof r}.`);
860
+ i == " " && (i = o), s = this.propReferences.push(r[o]) - 1, a = !0;
864
861
  } else
865
- (o != null && n == null || o == null && n == null) && console.warn('[GUI] color() "obj" and "prop" parameters must be used together.');
862
+ (o != null && r == null || o == null && r == null) && console.warn('[GUI] color() "obj" and "prop" parameters must be used together.');
866
863
  this.imageContainer = null;
867
864
  const l = document.createElement("div");
868
- l.className = "p-gui__color", l.textContent = i, p && l.setAttribute("title", p), this.wrapper.append(l);
865
+ l.className = "p-gui__color", l.textContent = i, c && l.setAttribute("title", c), this.wrapper.append(l);
869
866
  const d = document.createElement("input");
870
- d.className = "p-gui__color-picker", d.setAttribute("type", "color"), d.value = r, l.append(d), typeof t == "function" && d.addEventListener("input", () => {
871
- a ? n[o] = d.value : typeof t == "function" && t(d.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
872
- }), a && Object.defineProperty(n, o, {
873
- set: (c) => {
874
- this.propReferences[s] = c, d.value = c, typeof t == "function" && t(c);
867
+ d.className = "p-gui__color-picker", d.setAttribute("type", "color"), d.value = n, l.append(d), typeof t == "function" && d.addEventListener("input", () => {
868
+ a ? r[o] = d.value : typeof t == "function" && t(d.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
869
+ }), a && Object.defineProperty(r, o, {
870
+ set: (h) => {
871
+ this.propReferences[s] = h, d.value = h, typeof t == "function" && t(h);
875
872
  },
876
873
  get: () => this.propReferences[s]
877
874
  });
@@ -879,18 +876,18 @@ class A {
879
876
  folder(e = {}) {
880
877
  let t = typeof e.closed == "boolean" ? e.closed : !1, i = e.name || "", a = e.color || null, s = e.maxHeight || null;
881
878
  this.imageContainer = null;
882
- let n = "p-gui__folder";
883
- this.folders.length == 0 && (n += " p-gui__folder--first"), t && (n += " p-gui__folder--closed");
879
+ let r = "p-gui__folder";
880
+ this.folders.length == 0 && (r += " p-gui__folder--first"), t && (r += " p-gui__folder--closed");
884
881
  let o = a ? `background-color: ${a};` : "";
885
882
  o += s ? `max-height: ${s}px;` : "";
886
- const r = document.createElement("div");
887
- r.className = n, r.style = o, this.wrapper.append(r);
888
- const p = document.createElement("div");
889
- p.innerHTML = `<span class="p-gui__folder-arrow"></span>${i}`, p.className = "p-gui__folder-header", r.append(p), p.addEventListener("click", () => {
890
- r.classList.toggle("p-gui__folder--closed");
883
+ const n = document.createElement("div");
884
+ n.className = r, n.style = o, this.wrapper.append(n);
885
+ const c = document.createElement("div");
886
+ c.innerHTML = `<span class="p-gui__folder-arrow"></span>${i}`, c.className = "p-gui__folder-header", n.append(c), c.addEventListener("click", () => {
887
+ n.classList.toggle("p-gui__folder--closed");
891
888
  });
892
- let l = new A({ isFolder: !0, folderOptions: {
893
- wrapper: r,
889
+ let l = new I({ isFolder: !0, folderOptions: {
890
+ wrapper: n,
894
891
  parent: this,
895
892
  firstParent: this.firstParent
896
893
  } });
@@ -918,7 +915,11 @@ class A {
918
915
  _mapLinear(e, t, i, a, s) {
919
916
  return a + (e - t) * (s - a) / (i - t);
920
917
  }
918
+ _countDecimals(e) {
919
+ const t = e.toString(), i = t.indexOf(".");
920
+ return i === -1 ? 0 : t.length - i - 1;
921
+ }
921
922
  }
922
923
  export {
923
- A as default
924
+ I as default
924
925
  };
@@ -1,4 +1,4 @@
1
- (function(v,w){typeof exports=="object"&&typeof module<"u"?module.exports=w():typeof define=="function"&&define.amd?define(w):(v=typeof globalThis<"u"?globalThis:v||self,v["Perfect GUI"]=w())})(this,function(){"use strict";class v{constructor(e,t={},i){if(this.parent=e,this.propReferences=[],typeof t!="object")throw Error(`[GUI] slider() first parameter must be an object. Received: ${typeof t}.`);let a=typeof t.name=="string"&&t.name||" ";this.isObject=!1;let s=null;this.obj=t.obj,this.prop=t.prop;let n=typeof t.value=="number"?t.value:null;if(this.min=t.min??0,this.max=t.max??1,this.step=t.step||(this.max-this.min)/100,this.callback=typeof i=="function"?i:null,n!==null)(this.prop!=null||this.obj!=null)&&console.warn('[GUI] slider() "obj" and "prop" parameters are ignored when a "value" parameter is used.');else if(this.prop!=null&&this.obj!=null){if(typeof this.prop!="string")throw Error(`[GUI] slider() "prop" parameter must be an string. Received: ${typeof this.prop}.`);if(typeof this.obj!="object")throw Error(`[GUI] slider() "obj" parameter must be an object. Received: ${typeof this.obj}.`);a==" "&&(a=this.prop),s=this.propReferences.push(this.obj[this.prop])-1,this.isObject=!0}else(this.prop!=null&&this.obj==null||this.prop==null&&this.obj!=null)&&console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'),n=(this.max-this.min)/2;const o=typeof t.tooltip=="string"?t.tooltip:t.tooltip===!0?a:null;this.imageContainer=null;const r=document.createElement("div");r.className="p-gui__slider",o&&r.setAttribute("title",o);const p=document.createElement("div");p.className="p-gui__slider-name",p.textContent=a,r.append(p),this.ctrlDiv=document.createElement("div"),this.ctrlDiv.className="p-gui__slider-ctrl",this.ctrlDiv.setAttribute("type","range"),this.ctrlDiv.setAttribute("min",this.min),this.ctrlDiv.setAttribute("max",this.max),r.append(this.ctrlDiv);const l=document.createElement("div");return l.className="p-gui__slider-bar",this.ctrlDiv.append(l),this.handle=document.createElement("div"),this.handle.className="p-gui__slider-handle",this.ctrlDiv.append(this.handle),this.filling=document.createElement("div"),this.filling.className="p-gui__slider-filling",l.append(this.filling),this.valueInput=document.createElement("input"),this.valueInput.className="p-gui__slider-value",this.valueInput.value=this.isObject?this.obj[this.prop]:n,r.append(this.valueInput),setTimeout(()=>{const d=this.handle.offsetWidth;this.handle.position=this._mapLinear(this.valueInput.value,this.min,this.max,d/2,88-d/2),this.handle.style.transform=`translate(-50%, -50%) translateX(${this.handle.position}px)`,this.filling.style.width=`${this.handle.position}px`},0),this.valueInput.addEventListener("change",()=>{this._updateHandlePositionFromValue(),this._triggerCallbacks()}),this.ctrlDiv.addEventListener("pointerdown",d=>{this.ctrlDiv.pointerDown=!0,this.ctrlDiv.prevPosition=d.clientX,this._updateHandlePositionFromPointer(d,!0)}),window.addEventListener("pointerup",d=>{this.ctrlDiv.pointerDown=!1}),window.addEventListener("pointermove",d=>{this.ctrlDiv.pointerDown&&(this.ctrlDiv.pointerDelta=d.clientX-this.ctrlDiv.prevPosition,this._updateHandlePositionFromPointer(d))}),this.isObject&&Object.defineProperty(this.obj,this.prop,{set:d=>{this.propReferences[s]=d,this.valueInput.value=d,this._updateHandlePositionFromValue(),this.callback&&this.callback(parseFloat(this.valueInput.value))},get:()=>this.propReferences[s]}),r}_updateHandlePositionFromPointer(e,t=!1){const i=this.ctrlDiv.offsetWidth,a=this.handle.offsetWidth,s=e.clientX-this.ctrlDiv.prevPosition,n=parseFloat(this.valueInput.value);let o;t?o=e.offsetX:o=this.handle.position+s,o=Math.max(a/2,Math.min(o,i-a/2));let r=this.min+(this.max-this.min)*(o-a/2)/(i-a);r>n?r=this._quantizeFloor(r,this.step):r=this._quantizeCeil(r,this.step),r=parseFloat(r.toFixed(9));const p=parseFloat((n+this.step).toFixed(9)),l=parseFloat((n-this.step).toFixed(9));if(r>=p||r<=l){const d=this._countDecimals(this.step);r=r.toFixed(d),this.valueInput.value=r,this.ctrlDiv.prevPosition=e.clientX,this.handle.style.transform=`translate(-50%, -50%) translateX(${o}px)`,this.handle.position=o,this.filling.style.width=this.handle.position+"px",this._triggerCallbacks()}}_countDecimals(e){const t=e.toString(),i=t.indexOf(".");return i===-1?0:t.length-i-1}_updateHandlePositionFromValue(){const e=this.ctrlDiv.offsetWidth,t=this.handle.offsetWidth;let i=this._mapLinear(this.valueInput.value,this.min,this.max,t/2,e-t/2);i=Math.max(t/2,Math.min(i,e-t/2)),this.handle.style.transform=`translate(-50%, -50%) translateX(${i}px)`,this.handle.position=i,this.filling.style.width=this.handle.position+"px"}_triggerCallbacks(){this.isObject?this.obj[this.prop]=parseFloat(this.valueInput.value):this.callback&&this.callback(parseFloat(this.valueInput.value)),this.parent.onUpdate?this.parent.onUpdate():this.parent.isFolder&&this.parent.firstParent.onUpdate&&this.parent.firstParent.onUpdate()}_mapLinear(e,t,i,a,s){return a+(e-t)*(s-a)/(i-t)}_quantize(e,t){return t*Math.round(e/t)}_quantizeCeil(e,t){return t*Math.ceil(e/t)}_quantizeFloor(e,t){return t*Math.floor(e/t)}}const w=`
1
+ (function(A,k){typeof exports=="object"&&typeof module<"u"?module.exports=k():typeof define=="function"&&define.amd?define(k):(A=typeof globalThis<"u"?globalThis:A||self,A["Perfect GUI"]=k())})(this,function(){"use strict";class A{constructor(e,t={},i){if(this.parent=e,this.propReferences=[],typeof t!="object")throw Error(`[GUI] slider() first parameter must be an object. Received: ${typeof t}.`);let a=typeof t.name=="string"&&t.name||" ";this.isObject=!1;let s=null;this.obj=t.obj,this.prop=t.prop;let r=typeof t.value=="number"?t.value:null;if(this.min=t.min??0,this.max=t.max??1,this.step=t.step||(this.max-this.min)/100,this.decimals=this.parent._countDecimals(this.step),this.callback=typeof i=="function"?i:null,r!==null)(this.prop!=null||this.obj!=null)&&console.warn('[GUI] slider() "obj" and "prop" parameters are ignored when a "value" parameter is used.');else if(this.prop!=null&&this.obj!=null){if(typeof this.prop!="string")throw Error(`[GUI] slider() "prop" parameter must be an string. Received: ${typeof this.prop}.`);if(typeof this.obj!="object")throw Error(`[GUI] slider() "obj" parameter must be an object. Received: ${typeof this.obj}.`);a==" "&&(a=this.prop),s=this.propReferences.push(this.obj[this.prop])-1,this.isObject=!0}else(this.prop!=null&&this.obj==null||this.prop==null&&this.obj!=null)&&console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'),r=(this.max-this.min)/2;const o=typeof t.tooltip=="string"?t.tooltip:t.tooltip===!0?a:null;this.imageContainer=null;const n=document.createElement("div");n.className="p-gui__slider",o&&n.setAttribute("title",o);const c=document.createElement("div");c.className="p-gui__slider-name",c.textContent=a,n.append(c),this.ctrlDiv=document.createElement("div"),this.ctrlDiv.className="p-gui__slider-ctrl",this.ctrlDiv.setAttribute("type","range"),this.ctrlDiv.setAttribute("min",this.min),this.ctrlDiv.setAttribute("max",this.max),n.append(this.ctrlDiv);const l=document.createElement("div");return l.className="p-gui__slider-bar",this.ctrlDiv.append(l),this.handle=document.createElement("div"),this.handle.className="p-gui__slider-handle",this.ctrlDiv.append(this.handle),this.filling=document.createElement("div"),this.filling.className="p-gui__slider-filling",l.append(this.filling),this.valueInput=document.createElement("input"),this.valueInput.className="p-gui__slider-value",this.valueInput.value=this.isObject?this.obj[this.prop]:r,n.append(this.valueInput),setTimeout(()=>{const d=this.handle.offsetWidth;this.handle.position=this._mapLinear(this.valueInput.value,this.min,this.max,d/2,88-d/2),this.handle.position=Math.min(this.handle.position,88-d/2),this.handle.position=Math.max(this.handle.position,d/2),this.handle.style.transform=`translate(-50%, -50%) translateX(${this.handle.position}px)`,this.filling.style.width=`${this.handle.position}px`},0),this.valueInput.addEventListener("change",()=>{this._updateHandlePositionFromValue(),this._triggerCallbacks()}),this.ctrlDiv.addEventListener("pointerdown",d=>{this.ctrlDiv.pointerDown=!0,this.ctrlDiv.prevPosition=d.clientX,this._updateHandlePositionFromPointer(d,!0)}),window.addEventListener("pointerup",d=>{this.ctrlDiv.pointerDown=!1}),window.addEventListener("pointermove",d=>{this.ctrlDiv.pointerDown&&(this.ctrlDiv.pointerDelta=d.clientX-this.ctrlDiv.prevPosition,this._updateHandlePositionFromPointer(d))}),this.isObject&&Object.defineProperty(this.obj,this.prop,{set:d=>{this.propReferences[s]=d,this.valueInput.value=d,this._updateHandlePositionFromValue(),this.callback&&this.callback(parseFloat(this.valueInput.value))},get:()=>this.propReferences[s]}),n}_updateHandlePositionFromPointer(e,t=!1){const i=this.ctrlDiv.offsetWidth,a=this.handle.offsetWidth,s=e.clientX-this.ctrlDiv.prevPosition,r=parseFloat(this.valueInput.value);let o;t?o=e.offsetX:o=this.handle.position+s,o=Math.max(a/2,Math.min(o,i-a/2));let n=this.min+(this.max-this.min)*(o-a/2)/(i-a);n>r?n=this._quantizeFloor(n,this.step):n=this._quantizeCeil(n,this.step),n=parseFloat(n.toFixed(9));const c=parseFloat((r+this.step).toFixed(9)),l=parseFloat((r-this.step).toFixed(9));(n>=c||n<=l)&&(n=n.toFixed(this.decimals),this.valueInput.value=n,this.ctrlDiv.prevPosition=e.clientX,this.handle.style.transform=`translate(-50%, -50%) translateX(${o}px)`,this.handle.position=o,this.filling.style.width=this.handle.position+"px",this._triggerCallbacks())}_updateHandlePositionFromValue(){const e=this.ctrlDiv.offsetWidth,t=this.handle.offsetWidth;let i=this._mapLinear(this.valueInput.value,this.min,this.max,t/2,e-t/2);i=Math.max(t/2,Math.min(i,e-t/2)),this.handle.style.transform=`translate(-50%, -50%) translateX(${i}px)`,this.handle.position=i,this.filling.style.width=this.handle.position+"px"}_triggerCallbacks(){this.isObject?this.obj[this.prop]=parseFloat(this.valueInput.value):this.callback&&this.callback(parseFloat(this.valueInput.value)),this.parent.onUpdate?this.parent.onUpdate():this.parent.isFolder&&this.parent.firstParent.onUpdate&&this.parent.firstParent.onUpdate()}_mapLinear(e,t,i,a,s){return a+(e-t)*(s-a)/(i-t)}_quantize(e,t){return t*Math.round(e/t)}_quantizeCeil(e,t){return t*Math.ceil(e/t)}_quantizeFloor(e,t){return t*Math.floor(e/t)}}function k(f={},e){if(typeof f!="object")throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof f}.`);let t=typeof f.name=="string"&&f.name||" ";const i=f.x.min??0,a=f.x.max??1,s=f.y.min??0,r=f.y.max??1,o=f.x.step||(a-i)/100,n=f.y.step||(r-s)/100,c=this._countDecimals(o),l=this._countDecimals(n),d=f.x.obj,h=f.x.prop,g=this.propReferences.push(d[h])-1,p=f.y.obj,u=f.y.prop,v=this.propReferences.push(p[u])-1,x=typeof f.tooltip=="string"?f.tooltip:f.tooltip===!0?t:null;e=typeof e=="function"?e:null,this.imageContainer=null;const _=document.createElement("div");_.className="p-gui__vector2",_.textContent=t,x&&_.setAttribute("title",x),this.wrapper.append(_);const w=document.createElement("div");w.className="p-gui__vector-value",w.textContent=d[h]+", "+p[u],_.append(w);const b=document.createElement("div");b.className="p-gui__vector2-area",_.append(b),b.addEventListener("click",m=>{const j=parseFloat(this._mapLinear(m.offsetX,0,b.clientWidth,i,a)),I=parseFloat(this._mapLinear(m.offsetY,0,b.clientHeight,r,s));d[h]=j.toFixed(c),p[u]=I.toFixed(l),e&&e(d[h],d[u]),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()});let U=!1;b.addEventListener("pointerdown",m=>{U=!0}),b.addEventListener("pointerup",()=>{U=!1}),b.addEventListener("pointermove",m=>{if(U){const j=parseFloat(this._mapLinear(m.offsetX,0,b.clientWidth,i,a)),I=parseFloat(this._mapLinear(m.offsetY,0,b.clientHeight,r,s));d[h]=j.toFixed(c),p[u]=I.toFixed(l),e&&e(d[h],d[u]),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}});const C=document.createElement("div");C.className="p-gui__vector2-line p-gui__vector2-line-x",b.append(C);const R=document.createElement("div");R.className="p-gui__vector2-line p-gui__vector2-line-y",b.append(R);const y=document.createElement("div");y.className="p-gui__vector2-dot",b.append(y),y.style.left=this._mapLinear(d[h],i,a,0,b.clientWidth)+"px",y.style.top=this._mapLinear(p[u],s,r,b.clientHeight,0)+"px",Object.defineProperty(d,h,{set:m=>{this.propReferences[g]=m,y.style.left=this._mapLinear(m,i,a,0,b.clientWidth)+"px",w.textContent=String(m)+", "+p[u]},get:()=>this.propReferences[g]}),Object.defineProperty(p,u,{set:m=>{this.propReferences[v]=m,y.style.top=this._mapLinear(m,s,r,b.clientHeight,0)+"px",w.textContent=d[h]+", "+String(m)},get:()=>this.propReferences[v]})}const P=`
2
2
  .p-gui__button {
3
3
  background: var(--color-accent);
4
4
  text-align: center;
@@ -18,7 +18,7 @@
18
18
  .p-gui__folder .p-gui__button {
19
19
  margin-inline: 0;
20
20
  }
21
- `,U=`
21
+ `,O=`
22
22
  .p-gui__slider {
23
23
  position: relative;
24
24
  min-height: 14px;
@@ -109,7 +109,7 @@
109
109
  .p-gui__slider-value:focus {
110
110
  outline: none;
111
111
  }
112
- `,j=`
112
+ `,$=`
113
113
  .p-gui__list {
114
114
  cursor: default;
115
115
  color: var(--color-text-dark);
@@ -143,7 +143,7 @@
143
143
  .p-gui__list-dropdown:hover {
144
144
  background: rgba(255, 255, 255, .1);
145
145
  }
146
- `,I=`
146
+ `,D=`
147
147
  .p-gui__switch {
148
148
  background: rgba(255, 255, 255, .05);
149
149
  color: var(--color-text-dark);
@@ -177,7 +177,7 @@
177
177
  background-color: #00ff89;
178
178
  box-shadow: 0 0 7px #00ff89;
179
179
  }
180
- `,C=`
180
+ `,F=`
181
181
  .p-gui__color {
182
182
  cursor: default;
183
183
  color: var(--color-text-dark);
@@ -212,7 +212,7 @@
212
212
  .p-gui__color-picker::-webkit-color-swatch {
213
213
  border: none;
214
214
  }
215
- `,R=`
215
+ `,L=`
216
216
  .p-gui__vector2 {
217
217
  background: transparent;
218
218
  aspect-ratio: 1;
@@ -274,7 +274,7 @@
274
274
  right: 7px;
275
275
  position: absolute;
276
276
  }
277
- `,P=`
277
+ `,H=`
278
278
  .p-gui__image-container {
279
279
  width: 100%;
280
280
  padding: 3px;
@@ -327,7 +327,7 @@
327
327
  text-overflow: ellipsis;
328
328
 
329
329
  }
330
- `,O=`
330
+ `,N=`
331
331
  .p-gui__folder {
332
332
  width: 100%;
333
333
  position: relative;
@@ -377,7 +377,7 @@
377
377
  .p-gui__folder--closed .p-gui__folder-arrow {
378
378
  transform: rotate(0deg);
379
379
  }
380
- `;function $(k){return`
380
+ `;function M(f){return`
381
381
  .p-gui {
382
382
  --main-border-radius: 5px;
383
383
  --color-bg: #121212;
@@ -389,7 +389,7 @@
389
389
  --color-accent-hover: #218fda;
390
390
  --transition: .1s linear;
391
391
 
392
- position: ${k};
392
+ position: ${f};
393
393
  top: 0;
394
394
  left: 0;
395
395
  transform: translate3d(0,0,0);
@@ -507,26 +507,26 @@
507
507
  border-color: rgba(255,255,255,.2);
508
508
  }
509
509
 
510
- ${w}
511
-
512
510
  ${P}
513
511
 
514
- ${j}
512
+ ${H}
515
513
 
516
- ${I}
514
+ ${$}
515
+
516
+ ${D}
517
517
 
518
- ${U}
518
+ ${O}
519
519
 
520
- ${C}
520
+ ${F}
521
521
 
522
- ${R}
522
+ ${L}
523
523
 
524
- ${O}
525
- `}class A{constructor(e={}){if(this.firstParent=this,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}typeof e.onUpdate=="function"&&(this.onUpdate=e.onUpdate),this.name=e!=null&&typeof e.name=="string"?e.name:"",this.backgroundColor=e.color||null,this.opacity=e.opacity||1,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),window.perfectGUI||(window.perfectGUI={}),window.perfectGUI.instanceCounter==null?window.perfectGUI.instanceCounter=0:window.perfectGUI.instanceCounter++,this.instanceId=window.perfectGUI.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} {
524
+ ${N}
525
+ `}class E{constructor(e={}){if(this.firstParent=this,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}typeof e.onUpdate=="function"&&(this.onUpdate=e.onUpdate),this.name=e!=null&&typeof e.name=="string"?e.name:"",this.backgroundColor=e.color||null,this.opacity=e.opacity||1,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),window.perfectGUI||(window.perfectGUI={}),window.perfectGUI.instanceCounter==null?window.perfectGUI.instanceCounter=0:window.perfectGUI.instanceCounter++,this.instanceId=window.perfectGUI.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(`${M(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(),this.vector2=k}_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} {
526
526
  width: ${this.wrapperWidth}px;
527
527
  max-height: ${this.maxHeight}px;
528
528
  transform: translate3d(${this.xOffset}px,${this.yOffset}px,0);
529
529
  ${this.screenCorner.y=="top"?"":"top: auto; bottom: 0;"}
530
530
  ${this.backgroundColor?"background: "+this.backgroundColor+";":""}
531
531
  opacity: ${this.opacity};
532
- }`)}_folderConstructor(e){this.wrapper=e.wrapper,this.isFolder=!0,this.parent=e.parent,this.firstParent=e.firstParent}_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)`}_addStyles(e){this.stylesheet.innerHTML+=e}_addWrapper(){this.wrapper=document.createElement("div"),this.wrapper.id="p-gui-"+this.instanceId,this.wrapper.className="p-gui",this.container.append(this.wrapper),this.header=document.createElement("div"),this.header.className="p-gui__header",this.header.textContent=this.name,this.header.style=`${this.backgroundColor?"border-color: "+this.backgroundColor+";":""}`,this.wrapper.append(this.header);const e=document.createElement("div");e.className="p-gui__header-close",e.addEventListener("click",this.toggleClose.bind(this)),this.header.append(e)}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;const a=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;this.imageContainer=null;const s=document.createElement("div");s.className="p-gui__button",s.textContent=i,a&&s.setAttribute("title",a),s.addEventListener("click",()=>{t&&t(),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),this.wrapper.append(s),typeof e.color=="string"&&(s.style.setProperty("--color-accent",e.color),s.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 a=i.replace(/^.*[\\\/]/,""),s;e.name==null?s=a:s=typeof e.name=="string"&&e.name||" ";const n=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?s:null,o=e.selected===!0,r=e.selectionBorder!==!1;let p="";e.width&&(typeof e.width=="number"&&(e.width+="px"),p+=`flex: 0 0 calc(${e.width} - 5px); `),e.height&&(typeof e.height=="number"&&(e.height+="px"),p+=`height: ${e.height}; `),this.imageContainer||(this.imageContainer=document.createElement("div"),this.imageContainer.className="p-gui__image-container",this.wrapper.append(this.imageContainer));const l=document.createElement("div");l.className="p-gui__image",l.style="background-image: url("+i+"); "+p,n&&l.setAttribute("title",n),this.imageContainer.append(l),o&&r&&l.classList.add("p-gui__image--selected");const d=document.createElement("div");return d.className="p-gui__image-text",d.textContent=s,l.append(d),l.addEventListener("click",()=>{let c=l.parentElement.querySelectorAll(".p-gui__image--selected");for(let f=0;f<c.length;f++)c[f].classList.remove("p-gui__image--selected");r&&l.classList.add("p-gui__image--selected"),typeof t=="function"&&t({path:i,text:s}),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),l}slider(e={},t){const i=new v(this,e,t);this.wrapper.append(i)}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||" ",a=!1,s=null,n=e.obj,o=e.prop,r=typeof e.value=="boolean"?e.value:null;if(r!==null)(o!=null||n!=null)&&console.warn('[GUI] toggle() "obj" and "prop" parameters are ignored when a "value" parameter is used.');else if(o!=null&&n!=null){if(typeof o!="string")throw Error(`[GUI] toggle() "prop" parameter must be an string. Received: ${typeof o}.`);if(typeof n!="object")throw Error(`[GUI] toggle() "obj" parameter must be an object. Received: ${typeof n}.`);i==" "&&(i=o),s=this.propReferences.push(n[o])-1,a=!0}else(o!=null&&n==null||o==null&&n==null)&&console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');const p=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;this.imageContainer=null;const l=document.createElement("div");l.textContent=i,l.className="p-gui__switch",p&&l.setAttribute("title",p),this.wrapper.append(l),l.addEventListener("click",f=>{const u=f.target.childNodes[1];let g=!0;u.classList.contains("p-gui__switch-checkbox--active")&&(g=!1),u.classList.toggle("p-gui__switch-checkbox--active"),a?n[o]=g:typeof t=="function"&&t(g),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()});let d=(()=>a?n[o]?" p-gui__switch-checkbox--active":"":r?" p-gui__switch-checkbox--active":"")();const c=document.createElement("div");c.className="p-gui__switch-checkbox"+d,l.append(c),a&&Object.defineProperty(n,o,{set:f=>{this.propReferences[s]=f,f?c.classList.add("p-gui__switch-checkbox--active"):c.classList.remove("p-gui__switch-checkbox--active"),typeof t=="function"&&t(f)},get:()=>this.propReferences[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:" ",a=!1,s=null,n=e.obj,o=e.prop,r=Array.isArray(e.values)?e.values:null,p,l=typeof r[0]!="string";const d=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;if(t=typeof t=="function"?t:null,e.value!==void 0||e.value===void 0&&n===void 0&&o===void 0)(o!=null||n!=null)&&console.warn('[GUI] list() "obj" and "prop" parameters are ignored when a "value" parameter is used.'),p=(()=>{if(!r)return null;if(typeof e.value=="string")return r.indexOf(e.value);if(typeof e.value=="number")return e.value})();else if(o!=null&&n!=null){if(typeof o!="string")throw Error(`[GUI] list() "prop" parameter must be an string. Received: ${typeof o}.`);if(typeof n!="object")throw Error(`[GUI] list() "obj" parameter must be an object. Received: ${typeof n}.`);p=(()=>{if(!r)return null;if(typeof n[o]=="string")return l?r.find(u=>u.value===n[o]).value:r.indexOf(n[o]);if(typeof n[o]=="number")return l?r.find(u=>u.value===n[o]).value:n[o]})(),s=this.propReferences.push(n[o])-1,a=!0}else(o!=null&&n==null||o==null&&n==null)&&console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');this.imageContainer=null;let c=document.createElement("div");c.className="p-gui__list",c.textContent=i,d&&c.setAttribute("title",d),this.wrapper.append(c);let f=document.createElement("select");c.append(f),f.className="p-gui__list-dropdown",f.addEventListener("change",u=>{a?n[o]=u.target.value:t&&t(u.target.value),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),r&&r.forEach((u,g)=>{const _=l?u.name:u,h=l?u.value:u;let x=document.createElement("option");x.setAttribute("value",h),x.textContent=_,f.append(x),(!l&&p==g||l&&p==h)&&x.setAttribute("selected","")}),a&&Object.defineProperty(n,o,{set:u=>{let g,_,h;l?(h=r.find(y=>y.value==u),_=(h==null?void 0:h.value)||r[0].value,g=r.indexOf(h)):(typeof u=="string"&&(g=r.indexOf(u),_=u),typeof u=="number"&&(g=u,_=r[u])),this.propReferences[s]=l?_:u;const x=f.querySelector("[selected]");x&&x.removeAttribute("selected"),f.querySelectorAll("option")[g].setAttribute("selected",""),typeof t=="function"&&t(l?h:_,g)},get:()=>this.propReferences[s]})}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 a=e.x.min??0,s=e.x.max??1,n=e.y.min??0,o=e.y.max??1,r=e.x.obj,p=e.x.prop,l=this.propReferences.push(r[p])-1,d=e.y.obj,c=e.y.prop,f=this.propReferences.push(d[c])-1,u=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;t=typeof t=="function"?t:null,this.imageContainer=null;const g=document.createElement("div");g.className="p-gui__vector2",g.textContent=i,u&&g.setAttribute("title",u),this.wrapper.append(g);const _=document.createElement("div");_.className="p-gui__vector-value",_.textContent=r[p]+", "+d[c],g.append(_);const h=document.createElement("div");h.className="p-gui__vector2-area",g.append(h),h.addEventListener("click",b=>{r[p]=parseFloat(this._mapLinear(b.offsetX,0,h.clientWidth,a,s).toFixed(2)),d[c]=parseFloat(this._mapLinear(b.offsetY,0,h.clientHeight,o,n).toFixed(2)),t&&t(r[p],r[c]),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()});let x=!1;h.addEventListener("pointerdown",b=>{x=!0}),h.addEventListener("pointerup",()=>{x=!1}),h.addEventListener("pointermove",b=>{x&&(r[p]=parseFloat(this._mapLinear(b.offsetX,0,h.clientWidth,a,s).toFixed(2)),d[c]=parseFloat(this._mapLinear(b.offsetY,0,h.clientHeight,o,n).toFixed(2)),t&&t(r[p],r[c]),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate())});const y=document.createElement("div");y.className="p-gui__vector2-line p-gui__vector2-line-x",h.append(y);const E=document.createElement("div");E.className="p-gui__vector2-line p-gui__vector2-line-y",h.append(E);const m=document.createElement("div");m.className="p-gui__vector2-dot",h.append(m),m.style.left=this._mapLinear(r[p],a,s,0,h.clientWidth)+"px",m.style.top=this._mapLinear(d[c],n,o,h.clientHeight,0)+"px",Object.defineProperty(r,p,{set:b=>{this.propReferences[l]=b,m.style.left=this._mapLinear(b,a,s,0,h.clientWidth)+"px",_.textContent=String(b)+", "+d[c]},get:()=>this.propReferences[l]}),Object.defineProperty(d,c,{set:b=>{this.propReferences[f]=b,m.style.top=this._mapLinear(b,n,o,h.clientHeight,0)+"px",_.textContent=r[p]+", "+String(b)},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||" ",a=!1,s=null,n=e.obj,o=e.prop,r;const p=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;if(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"),e.value!==void 0)(o!=null||n!=null)&&console.warn('[GUI] color() "obj" and "prop" parameters are ignored when a "value" parameter is used.');else if(o!=null&&n!=null){if(typeof o!="string")throw Error(`[GUI] color() "prop" parameter must be an string. Received: ${typeof o}.`);if(typeof n!="object")throw Error(`[GUI] color() "obj" parameter must be an object. Received: ${typeof n}.`);i==" "&&(i=o),s=this.propReferences.push(n[o])-1,a=!0}else(o!=null&&n==null||o==null&&n==null)&&console.warn('[GUI] color() "obj" and "prop" parameters must be used together.');this.imageContainer=null;const l=document.createElement("div");l.className="p-gui__color",l.textContent=i,p&&l.setAttribute("title",p),this.wrapper.append(l);const d=document.createElement("input");d.className="p-gui__color-picker",d.setAttribute("type","color"),d.value=r,l.append(d),typeof t=="function"&&d.addEventListener("input",()=>{a?n[o]=d.value:typeof t=="function"&&t(d.value),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),a&&Object.defineProperty(n,o,{set:c=>{this.propReferences[s]=c,d.value=c,typeof t=="function"&&t(c)},get:()=>this.propReferences[s]})}folder(e={}){let t=typeof e.closed=="boolean"?e.closed:!1,i=e.name||"",a=e.color||null,s=e.maxHeight||null;this.imageContainer=null;let n="p-gui__folder";this.folders.length==0&&(n+=" p-gui__folder--first"),t&&(n+=" p-gui__folder--closed");let o=a?`background-color: ${a};`:"";o+=s?`max-height: ${s}px;`:"";const r=document.createElement("div");r.className=n,r.style=o,this.wrapper.append(r);const p=document.createElement("div");p.innerHTML=`<span class="p-gui__folder-arrow"></span>${i}`,p.className="p-gui__folder-header",r.append(p),p.addEventListener("click",()=>{r.classList.toggle("p-gui__folder--closed")});let l=new A({isFolder:!0,folderOptions:{wrapper:r,parent:this,firstParent:this.firstParent}});return this.folders.push(l),l}_makeDraggable(){var e=this;this.header.addEventListener("pointerdown",t),this.header.addEventListener("pointerup",a);function t(s){s.preventDefault(),e.position.initX=e.position.x,e.position.initY=e.position.y,e.position.prevX=s.clientX,e.position.prevY=s.clientY,document.addEventListener("pointermove",i)}function i(s){s.preventDefault(),e.hasBeenDragged||(e.hasBeenDragged=!0,e.wrapper.setAttribute("data-dragged","true")),e.position.x=e.position.initX+s.clientX-e.position.prevX,e.position.y=e.position.initY+s.clientY-e.position.prevY,e.wrapper.style.transform="translate3d("+e.position.x+"px,"+e.position.y+"px,0)"}function a(s){document.removeEventListener("pointermove",i)}}toggleClose(){this.closed=!this.closed,this.closed?(this.previousInnerScroll=this.wrapper.scrollTop,this.wrapper.scrollTo(0,0)):this.wrapper.scrollTo(0,this.previousInnerScroll),this.wrapper.classList.toggle("p-gui--collapsed")}kill(){this.wrapper.remove()}_mapLinear(e,t,i,a,s){return a+(e-t)*(s-a)/(i-t)}}return A});
532
+ }`)}_folderConstructor(e){this.wrapper=e.wrapper,this.isFolder=!0,this.parent=e.parent,this.firstParent=e.firstParent}_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)`}_addStyles(e){this.stylesheet.innerHTML+=e}_addWrapper(){this.wrapper=document.createElement("div"),this.wrapper.id="p-gui-"+this.instanceId,this.wrapper.className="p-gui",this.container.append(this.wrapper),this.header=document.createElement("div"),this.header.className="p-gui__header",this.header.textContent=this.name,this.header.style=`${this.backgroundColor?"border-color: "+this.backgroundColor+";":""}`,this.wrapper.append(this.header);const e=document.createElement("div");e.className="p-gui__header-close",e.addEventListener("click",this.toggleClose.bind(this)),this.header.append(e)}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;const a=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;this.imageContainer=null;const s=document.createElement("div");s.className="p-gui__button",s.textContent=i,a&&s.setAttribute("title",a),s.addEventListener("click",()=>{t&&t(),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),this.wrapper.append(s),typeof e.color=="string"&&(s.style.setProperty("--color-accent",e.color),s.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 a=i.replace(/^.*[\\\/]/,""),s;e.name==null?s=a:s=typeof e.name=="string"&&e.name||" ";const r=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?s:null,o=e.selected===!0,n=e.selectionBorder!==!1;let c="";e.width&&(typeof e.width=="number"&&(e.width+="px"),c+=`flex: 0 0 calc(${e.width} - 5px); `),e.height&&(typeof e.height=="number"&&(e.height+="px"),c+=`height: ${e.height}; `),this.imageContainer||(this.imageContainer=document.createElement("div"),this.imageContainer.className="p-gui__image-container",this.wrapper.append(this.imageContainer));const l=document.createElement("div");l.className="p-gui__image",l.style="background-image: url("+i+"); "+c,r&&l.setAttribute("title",r),this.imageContainer.append(l),o&&n&&l.classList.add("p-gui__image--selected");const d=document.createElement("div");return d.className="p-gui__image-text",d.textContent=s,l.append(d),l.addEventListener("click",()=>{let h=l.parentElement.querySelectorAll(".p-gui__image--selected");for(let g=0;g<h.length;g++)h[g].classList.remove("p-gui__image--selected");n&&l.classList.add("p-gui__image--selected"),typeof t=="function"&&t({path:i,text:s}),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),l}slider(e={},t){const i=new A(this,e,t);this.wrapper.append(i)}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||" ",a=!1,s=null,r=e.obj,o=e.prop,n=typeof e.value=="boolean"?e.value:null;if(n!==null)(o!=null||r!=null)&&console.warn('[GUI] toggle() "obj" and "prop" parameters are ignored when a "value" parameter is used.');else if(o!=null&&r!=null){if(typeof o!="string")throw Error(`[GUI] toggle() "prop" parameter must be an string. Received: ${typeof o}.`);if(typeof r!="object")throw Error(`[GUI] toggle() "obj" parameter must be an object. Received: ${typeof r}.`);i==" "&&(i=o),s=this.propReferences.push(r[o])-1,a=!0}else(o!=null&&r==null||o==null&&r==null)&&console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');const c=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;this.imageContainer=null;const l=document.createElement("div");l.textContent=i,l.className="p-gui__switch",c&&l.setAttribute("title",c),this.wrapper.append(l),l.addEventListener("click",g=>{const p=g.target.childNodes[1];let u=!0;p.classList.contains("p-gui__switch-checkbox--active")&&(u=!1),p.classList.toggle("p-gui__switch-checkbox--active"),a?r[o]=u:typeof t=="function"&&t(u),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()});let d=(()=>a?r[o]?" p-gui__switch-checkbox--active":"":n?" p-gui__switch-checkbox--active":"")();const h=document.createElement("div");h.className="p-gui__switch-checkbox"+d,l.append(h),a&&Object.defineProperty(r,o,{set:g=>{this.propReferences[s]=g,g?h.classList.add("p-gui__switch-checkbox--active"):h.classList.remove("p-gui__switch-checkbox--active"),typeof t=="function"&&t(g)},get:()=>this.propReferences[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:" ",a=!1,s=null,r=e.obj,o=e.prop,n=Array.isArray(e.values)?e.values:null,c,l=typeof n[0]!="string";const d=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;if(t=typeof t=="function"?t:null,e.value!==void 0||e.value===void 0&&r===void 0&&o===void 0)(o!=null||r!=null)&&console.warn('[GUI] list() "obj" and "prop" parameters are ignored when a "value" parameter is used.'),c=(()=>{if(!n)return null;if(typeof e.value=="string")return n.indexOf(e.value);if(typeof e.value=="number")return e.value})();else if(o!=null&&r!=null){if(typeof o!="string")throw Error(`[GUI] list() "prop" parameter must be an string. Received: ${typeof o}.`);if(typeof r!="object")throw Error(`[GUI] list() "obj" parameter must be an object. Received: ${typeof r}.`);c=(()=>{if(!n)return null;if(typeof r[o]=="string")return l?n.find(p=>p.value===r[o]).value:n.indexOf(r[o]);if(typeof r[o]=="number")return l?n.find(p=>p.value===r[o]).value:r[o]})(),s=this.propReferences.push(r[o])-1,a=!0}else(o!=null&&r==null||o==null&&r==null)&&console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');this.imageContainer=null;let h=document.createElement("div");h.className="p-gui__list",h.textContent=i,d&&h.setAttribute("title",d),this.wrapper.append(h);let g=document.createElement("select");h.append(g),g.className="p-gui__list-dropdown",g.addEventListener("change",p=>{a?r[o]=p.target.value:t&&t(p.target.value),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),n&&n.forEach((p,u)=>{const v=l?p.name:p,x=l?p.value:p;let _=document.createElement("option");_.setAttribute("value",x),_.textContent=v,g.append(_),(!l&&c==u||l&&c==x)&&_.setAttribute("selected","")}),a&&Object.defineProperty(r,o,{set:p=>{let u,v,x;l?(x=n.find(w=>w.value==p),v=(x==null?void 0:x.value)||n[0].value,u=n.indexOf(x)):(typeof p=="string"&&(u=n.indexOf(p),v=p),typeof p=="number"&&(u=p,v=n[p])),this.propReferences[s]=l?v:p;const _=g.querySelector("[selected]");_&&_.removeAttribute("selected"),g.querySelectorAll("option")[u].setAttribute("selected",""),typeof t=="function"&&t(l?x:v,u)},get:()=>this.propReferences[s]})}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||" ",a=!1,s=null,r=e.obj,o=e.prop,n;const c=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;if(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}".`):n=e.value),n||(n="#000000"),e.value!==void 0)(o!=null||r!=null)&&console.warn('[GUI] color() "obj" and "prop" parameters are ignored when a "value" parameter is used.');else if(o!=null&&r!=null){if(typeof o!="string")throw Error(`[GUI] color() "prop" parameter must be an string. Received: ${typeof o}.`);if(typeof r!="object")throw Error(`[GUI] color() "obj" parameter must be an object. Received: ${typeof r}.`);i==" "&&(i=o),s=this.propReferences.push(r[o])-1,a=!0}else(o!=null&&r==null||o==null&&r==null)&&console.warn('[GUI] color() "obj" and "prop" parameters must be used together.');this.imageContainer=null;const l=document.createElement("div");l.className="p-gui__color",l.textContent=i,c&&l.setAttribute("title",c),this.wrapper.append(l);const d=document.createElement("input");d.className="p-gui__color-picker",d.setAttribute("type","color"),d.value=n,l.append(d),typeof t=="function"&&d.addEventListener("input",()=>{a?r[o]=d.value:typeof t=="function"&&t(d.value),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),a&&Object.defineProperty(r,o,{set:h=>{this.propReferences[s]=h,d.value=h,typeof t=="function"&&t(h)},get:()=>this.propReferences[s]})}folder(e={}){let t=typeof e.closed=="boolean"?e.closed:!1,i=e.name||"",a=e.color||null,s=e.maxHeight||null;this.imageContainer=null;let r="p-gui__folder";this.folders.length==0&&(r+=" p-gui__folder--first"),t&&(r+=" p-gui__folder--closed");let o=a?`background-color: ${a};`:"";o+=s?`max-height: ${s}px;`:"";const n=document.createElement("div");n.className=r,n.style=o,this.wrapper.append(n);const c=document.createElement("div");c.innerHTML=`<span class="p-gui__folder-arrow"></span>${i}`,c.className="p-gui__folder-header",n.append(c),c.addEventListener("click",()=>{n.classList.toggle("p-gui__folder--closed")});let l=new E({isFolder:!0,folderOptions:{wrapper:n,parent:this,firstParent:this.firstParent}});return this.folders.push(l),l}_makeDraggable(){var e=this;this.header.addEventListener("pointerdown",t),this.header.addEventListener("pointerup",a);function t(s){s.preventDefault(),e.position.initX=e.position.x,e.position.initY=e.position.y,e.position.prevX=s.clientX,e.position.prevY=s.clientY,document.addEventListener("pointermove",i)}function i(s){s.preventDefault(),e.hasBeenDragged||(e.hasBeenDragged=!0,e.wrapper.setAttribute("data-dragged","true")),e.position.x=e.position.initX+s.clientX-e.position.prevX,e.position.y=e.position.initY+s.clientY-e.position.prevY,e.wrapper.style.transform="translate3d("+e.position.x+"px,"+e.position.y+"px,0)"}function a(s){document.removeEventListener("pointermove",i)}}toggleClose(){this.closed=!this.closed,this.closed?(this.previousInnerScroll=this.wrapper.scrollTop,this.wrapper.scrollTo(0,0)):this.wrapper.scrollTo(0,this.previousInnerScroll),this.wrapper.classList.toggle("p-gui--collapsed")}kill(){this.wrapper.remove()}_mapLinear(e,t,i,a,s){return a+(e-t)*(s-a)/(i-t)}_countDecimals(e){const t=e.toString(),i=t.indexOf(".");return i===-1?0:t.length-i-1}}return E});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perfect-gui",
3
- "version": "4.11.5",
3
+ "version": "4.11.7",
4
4
  "description": "GUI for JavaScript",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -16,6 +16,7 @@ export default class Slider {
16
16
  this.min = params.min ?? 0;
17
17
  this.max = params.max ?? 1;
18
18
  this.step = params.step || (this.max - this.min) / 100;
19
+ this.decimals = this.parent._countDecimals(this.step);
19
20
  this.callback = typeof callback == 'function' ? callback : null;
20
21
 
21
22
  // callback mode
@@ -91,6 +92,8 @@ export default class Slider {
91
92
  setTimeout(() => {
92
93
  const handleWidth = this.handle.offsetWidth;
93
94
  this.handle.position = this._mapLinear(this.valueInput.value, this.min, this.max, handleWidth / 2, 88 - handleWidth / 2);
95
+ this.handle.position = Math.min(this.handle.position, 88 - handleWidth / 2);
96
+ this.handle.position = Math.max(this.handle.position, handleWidth / 2);
94
97
  this.handle.style.transform = `translate(-50%, -50%) translateX(${this.handle.position}px)`;
95
98
  this.filling.style.width = `${this.handle.position}px`;
96
99
  }, 0); // wait for render
@@ -166,8 +169,7 @@ export default class Slider {
166
169
  const prevValue = parseFloat((currentValue - this.step).toFixed(9));
167
170
 
168
171
  if (newValue >= nextValue || newValue <= prevValue) {
169
- const decimals = this._countDecimals(this.step);
170
- newValue = newValue.toFixed(decimals);
172
+ newValue = newValue.toFixed(this.decimals);
171
173
 
172
174
  this.valueInput.value = newValue;
173
175
 
@@ -182,24 +184,6 @@ export default class Slider {
182
184
  }
183
185
  }
184
186
 
185
- _countDecimals(num) {
186
- // Convert the number to a string
187
- const numStr = num.toString();
188
-
189
- // Find the position of the decimal point
190
- const decimalIndex = numStr.indexOf('.');
191
-
192
- // If there is no decimal point, return 0
193
- if (decimalIndex === -1) {
194
- return 0;
195
- }
196
-
197
- // Calculate the number of digits after the decimal point
198
- const decimalPlaces = numStr.length - decimalIndex - 1;
199
-
200
- return decimalPlaces;
201
- }
202
-
203
187
  _updateHandlePositionFromValue() {
204
188
  const sliderWidth = this.ctrlDiv.offsetWidth;
205
189
  const handleWidth = this.handle.offsetWidth;
@@ -0,0 +1,126 @@
1
+ export default function vector2( params = {}, callback) {
2
+ if (typeof params != 'object') {
3
+ throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof params}.`);
4
+ }
5
+
6
+ let name = typeof params.name == 'string' ? params.name || ' ' : ' ';
7
+
8
+ const minX = params.x.min ?? 0;
9
+ const maxX = params.x.max ?? 1;
10
+ const minY = params.y.min ?? 0;
11
+ const maxY = params.y.max ?? 1;
12
+ const stepX = params.x.step || (maxX - minX) / 100;
13
+ const stepY = params.y.step || (maxY - minY) / 100;
14
+ const decimalsX = this._countDecimals(stepX);
15
+ const decimalsY = this._countDecimals(stepY);
16
+
17
+ const objectX = params.x.obj;
18
+ const propX = params.x.prop;
19
+ const propXReferenceIndex = this.propReferences.push(objectX[propX]) - 1;
20
+
21
+ const objectY = params.y.obj;
22
+ const propY = params.y.prop;
23
+ const propYReferenceIndex = this.propReferences.push(objectY[propY]) - 1;
24
+
25
+ const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? name : null);
26
+
27
+ callback = typeof callback == 'function' ? callback : null;
28
+
29
+ this.imageContainer = null;
30
+
31
+ const container = document.createElement('div');
32
+ container.className = 'p-gui__vector2';
33
+ container.textContent = name;
34
+ if ( tooltip ) {
35
+ container.setAttribute('title', tooltip);
36
+ }
37
+ this.wrapper.append(container);
38
+
39
+ const vector_value = document.createElement('div');
40
+ vector_value.className = 'p-gui__vector-value';
41
+ vector_value.textContent = objectX[propX] + ', ' + objectY[propY];
42
+ container.append(vector_value);
43
+
44
+ const area = document.createElement('div');
45
+ area.className = 'p-gui__vector2-area';
46
+ container.append(area);
47
+ area.addEventListener('click', evt => {
48
+ const newX = parseFloat(this._mapLinear(evt.offsetX, 0, area.clientWidth, minX, maxX));
49
+ const newY = parseFloat(this._mapLinear(evt.offsetY, 0, area.clientHeight, maxY, minY));
50
+ objectX[propX] = newX.toFixed(decimalsX);
51
+ objectY[propY] = newY.toFixed(decimalsY);
52
+
53
+ if (callback) {
54
+ callback(objectX[propX], objectX[propY]);
55
+ }
56
+
57
+ if (this.onUpdate) {
58
+ this.onUpdate();
59
+ } else if (this.isFolder && this.firstParent.onUpdate) {
60
+ this.firstParent.onUpdate();
61
+ }
62
+ });
63
+
64
+ let pointer_is_down = false;
65
+ area.addEventListener('pointerdown', (evt) => {
66
+ pointer_is_down = true;
67
+ });
68
+ area.addEventListener('pointerup', () => {
69
+ pointer_is_down = false;
70
+ });
71
+ area.addEventListener('pointermove', (evt) => {
72
+ if (pointer_is_down) {
73
+ const newX = parseFloat(this._mapLinear(evt.offsetX, 0, area.clientWidth, minX, maxX));
74
+ const newY = parseFloat(this._mapLinear(evt.offsetY, 0, area.clientHeight, maxY, minY));
75
+ objectX[propX] = newX.toFixed(decimalsX);
76
+ objectY[propY] = newY.toFixed(decimalsY);
77
+
78
+ if (callback) {
79
+ callback(objectX[propX], objectX[propY]);
80
+ }
81
+
82
+ if (this.onUpdate) {
83
+ this.onUpdate();
84
+ } else if (this.isFolder && this.firstParent.onUpdate) {
85
+ this.firstParent.onUpdate();
86
+ }
87
+ }
88
+ });
89
+
90
+ const line_x = document.createElement('div');
91
+ line_x.className = 'p-gui__vector2-line p-gui__vector2-line-x';
92
+ area.append(line_x);
93
+
94
+ const line_y = document.createElement('div');
95
+ line_y.className = 'p-gui__vector2-line p-gui__vector2-line-y';
96
+ area.append(line_y);
97
+
98
+ const dot = document.createElement('div');
99
+ dot.className = 'p-gui__vector2-dot';
100
+ area.append(dot);
101
+
102
+ dot.style.left = this._mapLinear(objectX[propX], minX, maxX, 0, area.clientWidth) + 'px';
103
+ dot.style.top = this._mapLinear(objectY[propY], minY, maxY, area.clientHeight, 0) + 'px';
104
+
105
+ Object.defineProperty( objectX, propX, {
106
+ set: val => {
107
+ this.propReferences[propXReferenceIndex] = val;
108
+ dot.style.left = this._mapLinear(val, minX, maxX, 0, area.clientWidth) + 'px';
109
+ vector_value.textContent = String( val ) + ', ' + objectY[propY];
110
+ },
111
+ get: () => {
112
+ return this.propReferences[propXReferenceIndex];
113
+ }
114
+ });
115
+
116
+ Object.defineProperty( objectY, propY, {
117
+ set: val => {
118
+ this.propReferences[propYReferenceIndex] = val;
119
+ dot.style.top = this._mapLinear(val, minY, maxY, area.clientHeight, 0) + 'px';
120
+ vector_value.textContent = objectX[propX] + ', ' + String( val );
121
+ },
122
+ get: () => {
123
+ return this.propReferences[propYReferenceIndex];
124
+ }
125
+ });
126
+ }
package/src/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import Slider from './components/Slider';
2
+ import vector2 from './components/vector2';
2
3
  import styles from './styles/styles';
3
4
 
4
5
  export default class GUI {
@@ -80,6 +81,8 @@ export default class GUI {
80
81
 
81
82
  this.closed = false;
82
83
  if (options.closed) this.toggleClose();
84
+
85
+ this.vector2 = vector2;
83
86
  }
84
87
 
85
88
  _styleInstance() {
@@ -625,125 +628,6 @@ export default class GUI {
625
628
  }
626
629
  }
627
630
 
628
- vector2( params = {}, callback) {
629
- if (typeof params != 'object') {
630
- throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof params}.`);
631
- }
632
-
633
- let name = typeof params.name == 'string' ? params.name || ' ' : ' ';
634
-
635
- const minX = params.x.min ?? 0;
636
- const maxX = params.x.max ?? 1;
637
- const minY = params.y.min ?? 0;
638
- const maxY = params.y.max ?? 1;
639
-
640
- const objectX = params.x.obj;
641
- const propX = params.x.prop;
642
- const propXReferenceIndex = this.propReferences.push(objectX[propX]) - 1;
643
-
644
- const objectY = params.y.obj;
645
- const propY = params.y.prop;
646
- const propYReferenceIndex = this.propReferences.push(objectY[propY]) - 1;
647
-
648
- const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? name : null);
649
-
650
- callback = typeof callback == 'function' ? callback : null;
651
-
652
- this.imageContainer = null;
653
-
654
- const container = document.createElement('div');
655
- container.className = 'p-gui__vector2';
656
- container.textContent = name;
657
- if ( tooltip ) {
658
- container.setAttribute('title', tooltip);
659
- }
660
- this.wrapper.append(container);
661
-
662
- const vector_value = document.createElement('div');
663
- vector_value.className = 'p-gui__vector-value';
664
- vector_value.textContent = objectX[propX] + ', ' + objectY[propY];
665
- container.append(vector_value);
666
-
667
- const area = document.createElement('div');
668
- area.className = 'p-gui__vector2-area';
669
- container.append(area);
670
- area.addEventListener('click', evt => {
671
- objectX[propX] = parseFloat(this._mapLinear(evt.offsetX, 0, area.clientWidth, minX, maxX).toFixed(2));
672
- objectY[propY] = parseFloat(this._mapLinear(evt.offsetY, 0, area.clientHeight, maxY, minY).toFixed(2));
673
-
674
- if (callback) {
675
- callback(objectX[propX], objectX[propY]);
676
- }
677
-
678
- if (this.onUpdate) {
679
- this.onUpdate();
680
- } else if (this.isFolder && this.firstParent.onUpdate) {
681
- this.firstParent.onUpdate();
682
- }
683
- });
684
-
685
- let pointer_is_down = false;
686
- area.addEventListener('pointerdown', (evt) => {
687
- pointer_is_down = true;
688
- });
689
- area.addEventListener('pointerup', () => {
690
- pointer_is_down = false;
691
- });
692
- area.addEventListener('pointermove', (evt) => {
693
- if (pointer_is_down) {
694
- objectX[propX] = parseFloat(this._mapLinear(evt.offsetX, 0, area.clientWidth, minX, maxX).toFixed(2));
695
- objectY[propY] = parseFloat(this._mapLinear(evt.offsetY, 0, area.clientHeight, maxY, minY).toFixed(2));
696
-
697
- if (callback) {
698
- callback(objectX[propX], objectX[propY]);
699
- }
700
-
701
- if (this.onUpdate) {
702
- this.onUpdate();
703
- } else if (this.isFolder && this.firstParent.onUpdate) {
704
- this.firstParent.onUpdate();
705
- }
706
- }
707
- });
708
-
709
- const line_x = document.createElement('div');
710
- line_x.className = 'p-gui__vector2-line p-gui__vector2-line-x';
711
- area.append(line_x);
712
-
713
- const line_y = document.createElement('div');
714
- line_y.className = 'p-gui__vector2-line p-gui__vector2-line-y';
715
- area.append(line_y);
716
-
717
- const dot = document.createElement('div');
718
- dot.className = 'p-gui__vector2-dot';
719
- area.append(dot);
720
-
721
- dot.style.left = this._mapLinear(objectX[propX], minX, maxX, 0, area.clientWidth) + 'px';
722
- dot.style.top = this._mapLinear(objectY[propY], minY, maxY, area.clientHeight, 0) + 'px';
723
-
724
- Object.defineProperty( objectX, propX, {
725
- set: val => {
726
- this.propReferences[propXReferenceIndex] = val;
727
- dot.style.left = this._mapLinear(val, minX, maxX, 0, area.clientWidth) + 'px';
728
- vector_value.textContent = String( val ) + ', ' + objectY[propY];
729
- },
730
- get: () => {
731
- return this.propReferences[propXReferenceIndex];
732
- }
733
- });
734
-
735
- Object.defineProperty( objectY, propY, {
736
- set: val => {
737
- this.propReferences[propYReferenceIndex] = val;
738
- dot.style.top = this._mapLinear(val, minY, maxY, area.clientHeight, 0) + 'px';
739
- vector_value.textContent = objectX[propX] + ', ' + String( val );
740
- },
741
- get: () => {
742
- return this.propReferences[propYReferenceIndex];
743
- }
744
- });
745
- }
746
-
747
631
  color(params = {}, callback) {
748
632
  if (typeof params != 'object') {
749
633
  throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof params}.`);
@@ -947,4 +831,22 @@ export default class GUI {
947
831
  _mapLinear( x, a1, a2, b1, b2 ) {
948
832
  return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
949
833
  }
834
+
835
+ _countDecimals(num) {
836
+ // Convert the number to a string
837
+ const numStr = num.toString();
838
+
839
+ // Find the position of the decimal point
840
+ const decimalIndex = numStr.indexOf('.');
841
+
842
+ // If there is no decimal point, return 0
843
+ if (decimalIndex === -1) {
844
+ return 0;
845
+ }
846
+
847
+ // Calculate the number of digits after the decimal point
848
+ const decimalPlaces = numStr.length - decimalIndex - 1;
849
+
850
+ return decimalPlaces;
851
+ }
950
852
  }
@@ -1,11 +1,11 @@
1
- import _button from "./_button"
2
- import _slider from "./_slider"
3
- import _list from "./_list"
4
- import _switch from "./_switch"
5
- import _color from "./_color"
6
- import _vector2 from "./_vector2"
7
- import _image from "./_image"
8
- import _folder from "./_folder"
1
+ import _button from "./_button.css.js"
2
+ import _slider from "./_slider.css.js"
3
+ import _list from "./_list.css.js"
4
+ import _switch from "./_switch.css.js"
5
+ import _color from "./_color.css.js"
6
+ import _vector2 from "./_vector2.css.js"
7
+ import _image from "./_image.css.js"
8
+ import _folder from "./_folder.css.js"
9
9
 
10
10
  /**
11
11
  * JS instead of CSS to avoid
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes