perfect-gui 4.11.6 → 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,15 +16,15 @@ 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
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", () => {
@@ -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.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]}),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 m=document.createElement("option");m.setAttribute("value",h),m.textContent=_,f.append(m),(!l&&p==g||l&&p==h)&&m.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 m=f.querySelector("[selected]");m&&m.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 m=!1;h.addEventListener("pointerdown",b=>{m=!0}),h.addEventListener("pointerup",()=>{m=!1}),h.addEventListener("pointermove",b=>{m&&(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 x=document.createElement("div");x.className="p-gui__vector2-dot",h.append(x),x.style.left=this._mapLinear(r[p],a,s,0,h.clientWidth)+"px",x.style.top=this._mapLinear(d[c],n,o,h.clientHeight,0)+"px",Object.defineProperty(r,p,{set:b=>{this.propReferences[l]=b,x.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,x.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.6",
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
@@ -168,8 +169,7 @@ export default class Slider {
168
169
  const prevValue = parseFloat((currentValue - this.step).toFixed(9));
169
170
 
170
171
  if (newValue >= nextValue || newValue <= prevValue) {
171
- const decimals = this._countDecimals(this.step);
172
- newValue = newValue.toFixed(decimals);
172
+ newValue = newValue.toFixed(this.decimals);
173
173
 
174
174
  this.valueInput.value = newValue;
175
175
 
@@ -184,24 +184,6 @@ export default class Slider {
184
184
  }
185
185
  }
186
186
 
187
- _countDecimals(num) {
188
- // Convert the number to a string
189
- const numStr = num.toString();
190
-
191
- // Find the position of the decimal point
192
- const decimalIndex = numStr.indexOf('.');
193
-
194
- // If there is no decimal point, return 0
195
- if (decimalIndex === -1) {
196
- return 0;
197
- }
198
-
199
- // Calculate the number of digits after the decimal point
200
- const decimalPlaces = numStr.length - decimalIndex - 1;
201
-
202
- return decimalPlaces;
203
- }
204
-
205
187
  _updateHandlePositionFromValue() {
206
188
  const sliderWidth = this.ctrlDiv.offsetWidth;
207
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