perfect-gui 4.11.6 → 4.11.8

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 R {
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 o = 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, o !== 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;
20
- const o = typeof t.tooltip == "string" ? t.tooltip : t.tooltip === !0 ? a : null;
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.'), o = (this.max - this.min) / 2;
20
+ const r = 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", r && n.setAttribute("title", r);
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] : o, 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);
47
- let o;
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;
46
+ const i = this.ctrlDiv.offsetWidth, a = this.handle.offsetWidth, s = e.clientX - this.ctrlDiv.prevPosition, o = parseFloat(this.valueInput.value);
47
+ let r;
48
+ t ? r = e.offsetX : r = this.handle.position + s, r = Math.max(a / 2, Math.min(r, i - a / 2));
49
+ let n = this.min + (this.max - this.min) * (r - a / 2) / (i - a);
50
+ n > o ? n = this._quantizeFloor(n, this.step) : n = this._quantizeCeil(n, this.step), n = parseFloat(n.toFixed(9));
51
+ const c = parseFloat((o + this.step).toFixed(9)), l = parseFloat((o - 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(${r}px)`, this.handle.position = r, 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,7 @@ class k {
79
72
  return t * Math.floor(e / t);
80
73
  }
81
74
  }
82
- const E = (
75
+ const P = (
83
76
  /* css */
84
77
  `
85
78
  .p-gui__button {
@@ -102,7 +95,7 @@ const E = (
102
95
  margin-inline: 0;
103
96
  }
104
97
  `
105
- ), U = (
98
+ ), O = (
106
99
  /* css */
107
100
  `
108
101
  .p-gui__slider {
@@ -196,7 +189,7 @@ const E = (
196
189
  outline: none;
197
190
  }
198
191
  `
199
- ), j = (
192
+ ), $ = (
200
193
  /* css */
201
194
  `
202
195
  .p-gui__list {
@@ -233,7 +226,7 @@ const E = (
233
226
  background: rgba(255, 255, 255, .1);
234
227
  }
235
228
  `
236
- ), I = (
229
+ ), D = (
237
230
  /* css */
238
231
  `
239
232
  .p-gui__switch {
@@ -270,7 +263,7 @@ const E = (
270
263
  box-shadow: 0 0 7px #00ff89;
271
264
  }
272
265
  `
273
- ), C = (
266
+ ), F = (
274
267
  /* css */
275
268
  `
276
269
  .p-gui__color {
@@ -308,7 +301,7 @@ const E = (
308
301
  border: none;
309
302
  }
310
303
  `
311
- ), R = (
304
+ ), L = (
312
305
  /* css */
313
306
  `
314
307
  .p-gui__vector2 {
@@ -373,7 +366,7 @@ const E = (
373
366
  position: absolute;
374
367
  }
375
368
  `
376
- ), P = (
369
+ ), H = (
377
370
  /* css */
378
371
  `
379
372
  .p-gui__image-container {
@@ -429,7 +422,7 @@ const E = (
429
422
 
430
423
  }
431
424
  `
432
- ), O = (
425
+ ), N = (
433
426
  /* css */
434
427
  `
435
428
  .p-gui__folder {
@@ -483,7 +476,7 @@ const E = (
483
476
  }
484
477
  `
485
478
  );
486
- function $(w) {
479
+ function M(U) {
487
480
  return (
488
481
  /* css */
489
482
  `
@@ -498,7 +491,7 @@ function $(w) {
498
491
  --color-accent-hover: #218fda;
499
492
  --transition: .1s linear;
500
493
 
501
- position: ${w};
494
+ position: ${U};
502
495
  top: 0;
503
496
  left: 0;
504
497
  transform: translate3d(0,0,0);
@@ -616,31 +609,31 @@ function $(w) {
616
609
  border-color: rgba(255,255,255,.2);
617
610
  }
618
611
 
619
- ${E}
620
-
621
612
  ${P}
622
613
 
623
- ${j}
614
+ ${H}
615
+
616
+ ${$}
624
617
 
625
- ${I}
618
+ ${D}
626
619
 
627
- ${U}
620
+ ${O}
628
621
 
629
- ${C}
622
+ ${F}
630
623
 
631
- ${R}
624
+ ${L}
632
625
 
633
- ${O}
626
+ ${N}
634
627
  `
635
628
  );
636
629
  }
637
- class A {
630
+ class C {
638
631
  constructor(e = {}) {
639
632
  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
633
  this._folderConstructor(e.folderOptions);
641
634
  return;
642
635
  }
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();
636
+ 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();
644
637
  }
645
638
  _styleInstance() {
646
639
  let e = this._getScrollbarWidth(this.container);
@@ -712,50 +705,50 @@ class A {
712
705
  throw typeof e.path == null ? Error("[GUI] image() path must be provided.") : Error("[GUI] image() path must be a string.");
713
706
  let a = i.replace(/^.*[\\\/]/, ""), s;
714
707
  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));
708
+ const o = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null, r = e.selected === !0, n = e.selectionBorder !== !1;
709
+ let c = "";
710
+ 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
711
  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");
712
+ l.className = "p-gui__image", l.style = "background-image: url(" + i + "); " + c, o && l.setAttribute("title", o), this.imageContainer.append(l), r && n && l.classList.add("p-gui__image--selected");
720
713
  const d = document.createElement("div");
721
714
  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();
715
+ let p = l.parentElement.querySelectorAll(".p-gui__image--selected");
716
+ for (let h = 0; h < p.length; h++)
717
+ p[h].classList.remove("p-gui__image--selected");
718
+ 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
719
  }), l;
727
720
  }
728
721
  slider(e = {}, t) {
729
- const i = new k(this, e, t);
722
+ const i = new R(this, e, t);
730
723
  this.wrapper.append(i);
731
724
  }
732
725
  toggle(e = {}, t) {
733
726
  if (typeof e != "object")
734
727
  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) {
739
- if (typeof o != "string")
740
- 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;
728
+ let i = typeof e.name == "string" && e.name || " ", a = !1, s = null, o = e.obj, r = e.prop, n = typeof e.value == "boolean" ? e.value : null;
729
+ if (n !== null)
730
+ (r != null || o != null) && console.warn('[GUI] toggle() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
731
+ else if (r != null && o != null) {
732
+ if (typeof r != "string")
733
+ throw Error(`[GUI] toggle() "prop" parameter must be an string. Received: ${typeof r}.`);
734
+ if (typeof o != "object")
735
+ throw Error(`[GUI] toggle() "obj" parameter must be an object. Received: ${typeof o}.`);
736
+ i == " " && (i = r), s = this.propReferences.push(o[r]) - 1, a = !0;
744
737
  } 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;
738
+ (r != null && o == null || r == null && o == null) && console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');
739
+ const c = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
747
740
  this.imageContainer = null;
748
741
  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();
742
+ l.textContent = i, l.className = "p-gui__switch", c && l.setAttribute("title", c), this.wrapper.append(l), l.addEventListener("click", (h) => {
743
+ const u = h.target.childNodes[1];
744
+ let f = !0;
745
+ u.classList.contains("p-gui__switch-checkbox--active") && (f = !1), u.classList.toggle("p-gui__switch-checkbox--active"), a ? o[r] = f : typeof t == "function" && t(f), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
753
746
  });
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);
747
+ let d = (() => a ? o[r] ? " p-gui__switch-checkbox--active" : "" : n ? " p-gui__switch-checkbox--active" : "")();
748
+ const p = document.createElement("div");
749
+ p.className = "p-gui__switch-checkbox" + d, l.append(p), a && Object.defineProperty(o, r, {
750
+ set: (h) => {
751
+ this.propReferences[s] = h, h ? p.classList.add("p-gui__switch-checkbox--active") : p.classList.remove("p-gui__switch-checkbox--active"), typeof t == "function" && t(h);
759
752
  },
760
753
  get: () => this.propReferences[s]
761
754
  });
@@ -763,134 +756,138 @@ class A {
763
756
  list(e = {}, t) {
764
757
  if (typeof e != "object")
765
758
  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";
759
+ let i = typeof e.name == "string" ? e.name : " ", a = !1, s = null, o = e.obj, r = e.prop, n = Array.isArray(e.values) ? e.values : null, c, l = typeof n[0] != "string";
767
760
  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)
761
+ if (t = typeof t == "function" ? t : null, e.value !== void 0 || e.value === void 0 && o === void 0 && r === void 0)
762
+ (r != null || o != null) && console.warn('[GUI] list() "obj" and "prop" parameters are ignored when a "value" parameter is used.'), c = (() => {
763
+ if (!n)
771
764
  return null;
772
765
  if (typeof e.value == "string")
773
- return r.indexOf(e.value);
766
+ return n.indexOf(e.value);
774
767
  if (typeof e.value == "number")
775
768
  return e.value;
776
769
  })();
777
- else if (o != null && n != null) {
778
- if (typeof o != "string")
779
- 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)
770
+ else if (r != null && o != null) {
771
+ if (typeof r != "string")
772
+ throw Error(`[GUI] list() "prop" parameter must be an string. Received: ${typeof r}.`);
773
+ if (typeof o != "object")
774
+ throw Error(`[GUI] list() "obj" parameter must be an object. Received: ${typeof o}.`);
775
+ c = (() => {
776
+ if (!n)
784
777
  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;
778
+ if (typeof o[r] == "string")
779
+ return l ? n.find((u) => u.value === o[r]).value : n.indexOf(o[r]);
780
+ if (typeof o[r] == "number")
781
+ return l ? n.find((u) => u.value === o[r]).value : o[r];
782
+ })(), s = this.propReferences.push(o[r]) - 1, a = !0;
790
783
  } else
791
- (o != null && n == null || o == null && n == null) && console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');
784
+ (r != null && o == null || r == null && o == null) && console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');
792
785
  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;
786
+ let p = document.createElement("div");
787
+ p.className = "p-gui__list", p.textContent = i, d && p.setAttribute("title", d), this.wrapper.append(p);
788
+ let h = document.createElement("select");
789
+ p.append(h), h.className = "p-gui__list-dropdown", h.addEventListener("change", (u) => {
790
+ a ? o[r] = u.target.value : t && t(u.target.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
791
+ }), n && n.forEach((u, f) => {
792
+ const g = l ? u.name : u, m = l ? u.value : u;
800
793
  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, {
794
+ x.setAttribute("value", m), x.textContent = g, h.append(x), (!l && c == f || l && c == m) && x.setAttribute("selected", "");
795
+ }), a && Object.defineProperty(o, r, {
803
796
  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);
797
+ let f, g, m;
798
+ l ? (m = n.find((v) => v.value == u), g = (m == null ? void 0 : m.value) || n[0].value, f = n.indexOf(m)) : (typeof u == "string" && (f = n.indexOf(u), g = u), typeof u == "number" && (f = u, g = n[u])), this.propReferences[s] = l ? g : u;
799
+ const x = h.querySelector("[selected]");
800
+ x && x.removeAttribute("selected"), h.querySelectorAll("option")[f].setAttribute("selected", ""), typeof t == "function" && t(l ? m : g, f);
808
801
  },
809
802
  get: () => this.propReferences[s]
810
803
  });
811
804
  }
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
805
  color(e = {}, t) {
852
806
  if (typeof e != "object")
853
807
  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) {
859
- if (typeof o != "string")
860
- 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;
808
+ let i = typeof e.name == "string" && e.name || " ", a = !1, s = null, o = e.obj, r = e.prop, n;
809
+ const c = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
810
+ 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)
811
+ (r != null || o != null) && console.warn('[GUI] color() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
812
+ else if (r != null && o != null) {
813
+ if (typeof r != "string")
814
+ throw Error(`[GUI] color() "prop" parameter must be an string. Received: ${typeof r}.`);
815
+ if (typeof o != "object")
816
+ throw Error(`[GUI] color() "obj" parameter must be an object. Received: ${typeof o}.`);
817
+ i == " " && (i = r), s = this.propReferences.push(o[r]) - 1, a = !0;
864
818
  } else
865
- (o != null && n == null || o == null && n == null) && console.warn('[GUI] color() "obj" and "prop" parameters must be used together.');
819
+ (r != null && o == null || r == null && o == null) && console.warn('[GUI] color() "obj" and "prop" parameters must be used together.');
866
820
  this.imageContainer = null;
867
821
  const l = document.createElement("div");
868
- l.className = "p-gui__color", l.textContent = i, p && l.setAttribute("title", p), this.wrapper.append(l);
822
+ l.className = "p-gui__color", l.textContent = i, c && l.setAttribute("title", c), this.wrapper.append(l);
869
823
  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);
824
+ d.className = "p-gui__color-picker", d.setAttribute("type", "color"), d.value = n, l.append(d), typeof t == "function" && d.addEventListener("input", () => {
825
+ a ? o[r] = d.value : typeof t == "function" && t(d.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
826
+ }), a && Object.defineProperty(o, r, {
827
+ set: (p) => {
828
+ this.propReferences[s] = p, d.value = p, typeof t == "function" && t(p);
875
829
  },
876
830
  get: () => this.propReferences[s]
877
831
  });
878
832
  }
833
+ vector2(e = {}, t) {
834
+ if (typeof e != "object")
835
+ throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof e}.`);
836
+ let i = typeof e.name == "string" && e.name || " ";
837
+ const a = e.x.min ?? 0, s = e.x.max ?? 1, o = e.y.min ?? 0, r = e.y.max ?? 1, n = e.x.step || (s - a) / 100, c = e.y.step || (r - o) / 100, l = this._countDecimals(n), d = this._countDecimals(c), p = e.x.obj, h = e.x.prop, u = this.propReferences.push(p[h]) - 1, f = e.y.obj, g = e.y.prop, m = this.propReferences.push(f[g]) - 1, x = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
838
+ t = typeof t == "function" ? t : null, this.imageContainer = null;
839
+ const v = document.createElement("div");
840
+ v.className = "p-gui__vector2", v.textContent = i, x && v.setAttribute("title", x), this.wrapper.append(v);
841
+ const y = document.createElement("div");
842
+ y.className = "p-gui__vector-value", y.textContent = p[h] + ", " + f[g], v.append(y);
843
+ const b = document.createElement("div");
844
+ b.className = "p-gui__vector2-area", v.append(b), b.addEventListener("click", (_) => {
845
+ const k = parseFloat(this._mapLinear(_.offsetX, 0, b.clientWidth, a, s)), E = parseFloat(this._mapLinear(_.offsetY, 0, b.clientHeight, r, o));
846
+ p[h] = k.toFixed(l), f[g] = E.toFixed(d), t && t(p[h], p[g]), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
847
+ });
848
+ let A = !1;
849
+ b.addEventListener("pointerdown", (_) => {
850
+ A = !0;
851
+ }), b.addEventListener("pointerup", () => {
852
+ A = !1;
853
+ }), b.addEventListener("pointermove", (_) => {
854
+ if (A) {
855
+ const k = parseFloat(this._mapLinear(_.offsetX, 0, b.clientWidth, a, s)), E = parseFloat(this._mapLinear(_.offsetY, 0, b.clientHeight, r, o));
856
+ p[h] = k.toFixed(l), f[g] = E.toFixed(d), t && t(p[h], p[g]), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
857
+ }
858
+ });
859
+ const j = document.createElement("div");
860
+ j.className = "p-gui__vector2-line p-gui__vector2-line-x", b.append(j);
861
+ const I = document.createElement("div");
862
+ I.className = "p-gui__vector2-line p-gui__vector2-line-y", b.append(I);
863
+ const w = document.createElement("div");
864
+ w.className = "p-gui__vector2-dot", b.append(w), w.style.left = this._mapLinear(p[h], a, s, 0, b.clientWidth) + "px", w.style.top = this._mapLinear(f[g], o, r, b.clientHeight, 0) + "px", Object.defineProperty(p, h, {
865
+ set: (_) => {
866
+ this.propReferences[u] = _, w.style.left = this._mapLinear(_, a, s, 0, b.clientWidth) + "px", y.textContent = String(_) + ", " + f[g];
867
+ },
868
+ get: () => this.propReferences[u]
869
+ }), Object.defineProperty(f, g, {
870
+ set: (_) => {
871
+ this.propReferences[m] = _, w.style.top = this._mapLinear(_, o, r, b.clientHeight, 0) + "px", y.textContent = p[h] + ", " + String(_);
872
+ },
873
+ get: () => this.propReferences[m]
874
+ });
875
+ }
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");
884
- let o = a ? `background-color: ${a};` : "";
885
- 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");
879
+ let o = "p-gui__folder";
880
+ this.folders.length == 0 && (o += " p-gui__folder--first"), t && (o += " p-gui__folder--closed");
881
+ let r = a ? `background-color: ${a};` : "";
882
+ r += s ? `max-height: ${s}px;` : "";
883
+ const n = document.createElement("div");
884
+ n.className = o, n.style = r, 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 C({ 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
+ C 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(y,A){typeof exports=="object"&&typeof module<"u"?module.exports=A():typeof define=="function"&&define.amd?define(A):(y=typeof globalThis<"u"?globalThis:y||self,y["Perfect GUI"]=A())})(this,function(){"use strict";class y{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 o=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,o!==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.'),o=(this.max-this.min)/2;const r=typeof t.tooltip=="string"?t.tooltip:t.tooltip===!0?a:null;this.imageContainer=null;const n=document.createElement("div");n.className="p-gui__slider",r&&n.setAttribute("title",r);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]:o,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,o=parseFloat(this.valueInput.value);let r;t?r=e.offsetX:r=this.handle.position+s,r=Math.max(a/2,Math.min(r,i-a/2));let n=this.min+(this.max-this.min)*(r-a/2)/(i-a);n>o?n=this._quantizeFloor(n,this.step):n=this._quantizeCeil(n,this.step),n=parseFloat(n.toFixed(9));const c=parseFloat((o+this.step).toFixed(9)),l=parseFloat((o-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(${r}px)`,this.handle.position=r,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)}}const A=`
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(C){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: ${C};
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}
510
+ ${A}
511
511
 
512
- ${P}
512
+ ${H}
513
513
 
514
- ${j}
514
+ ${$}
515
515
 
516
- ${I}
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()}_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 o=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?s:null,r=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,o&&l.setAttribute("title",o),this.imageContainer.append(l),r&&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 p=l.parentElement.querySelectorAll(".p-gui__image--selected");for(let h=0;h<p.length;h++)p[h].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 y(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,o=e.obj,r=e.prop,n=typeof e.value=="boolean"?e.value:null;if(n!==null)(r!=null||o!=null)&&console.warn('[GUI] toggle() "obj" and "prop" parameters are ignored when a "value" parameter is used.');else if(r!=null&&o!=null){if(typeof r!="string")throw Error(`[GUI] toggle() "prop" parameter must be an string. Received: ${typeof r}.`);if(typeof o!="object")throw Error(`[GUI] toggle() "obj" parameter must be an object. Received: ${typeof o}.`);i==" "&&(i=r),s=this.propReferences.push(o[r])-1,a=!0}else(r!=null&&o==null||r==null&&o==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",h=>{const u=h.target.childNodes[1];let f=!0;u.classList.contains("p-gui__switch-checkbox--active")&&(f=!1),u.classList.toggle("p-gui__switch-checkbox--active"),a?o[r]=f:typeof t=="function"&&t(f),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()});let d=(()=>a?o[r]?" p-gui__switch-checkbox--active":"":n?" p-gui__switch-checkbox--active":"")();const p=document.createElement("div");p.className="p-gui__switch-checkbox"+d,l.append(p),a&&Object.defineProperty(o,r,{set:h=>{this.propReferences[s]=h,h?p.classList.add("p-gui__switch-checkbox--active"):p.classList.remove("p-gui__switch-checkbox--active"),typeof t=="function"&&t(h)},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,o=e.obj,r=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&&o===void 0&&r===void 0)(r!=null||o!=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(r!=null&&o!=null){if(typeof r!="string")throw Error(`[GUI] list() "prop" parameter must be an string. Received: ${typeof r}.`);if(typeof o!="object")throw Error(`[GUI] list() "obj" parameter must be an object. Received: ${typeof o}.`);c=(()=>{if(!n)return null;if(typeof o[r]=="string")return l?n.find(u=>u.value===o[r]).value:n.indexOf(o[r]);if(typeof o[r]=="number")return l?n.find(u=>u.value===o[r]).value:o[r]})(),s=this.propReferences.push(o[r])-1,a=!0}else(r!=null&&o==null||r==null&&o==null)&&console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');this.imageContainer=null;let p=document.createElement("div");p.className="p-gui__list",p.textContent=i,d&&p.setAttribute("title",d),this.wrapper.append(p);let h=document.createElement("select");p.append(h),h.className="p-gui__list-dropdown",h.addEventListener("change",u=>{a?o[r]=u.target.value:t&&t(u.target.value),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),n&&n.forEach((u,f)=>{const g=l?u.name:u,m=l?u.value:u;let x=document.createElement("option");x.setAttribute("value",m),x.textContent=g,h.append(x),(!l&&c==f||l&&c==m)&&x.setAttribute("selected","")}),a&&Object.defineProperty(o,r,{set:u=>{let f,g,m;l?(m=n.find(v=>v.value==u),g=(m==null?void 0:m.value)||n[0].value,f=n.indexOf(m)):(typeof u=="string"&&(f=n.indexOf(u),g=u),typeof u=="number"&&(f=u,g=n[u])),this.propReferences[s]=l?g:u;const x=h.querySelector("[selected]");x&&x.removeAttribute("selected"),h.querySelectorAll("option")[f].setAttribute("selected",""),typeof t=="function"&&t(l?m:g,f)},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,o=e.obj,r=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)(r!=null||o!=null)&&console.warn('[GUI] color() "obj" and "prop" parameters are ignored when a "value" parameter is used.');else if(r!=null&&o!=null){if(typeof r!="string")throw Error(`[GUI] color() "prop" parameter must be an string. Received: ${typeof r}.`);if(typeof o!="object")throw Error(`[GUI] color() "obj" parameter must be an object. Received: ${typeof o}.`);i==" "&&(i=r),s=this.propReferences.push(o[r])-1,a=!0}else(r!=null&&o==null||r==null&&o==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?o[r]=d.value:typeof t=="function"&&t(d.value),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),a&&Object.defineProperty(o,r,{set:p=>{this.propReferences[s]=p,d.value=p,typeof t=="function"&&t(p)},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,o=e.y.min??0,r=e.y.max??1,n=e.x.step||(s-a)/100,c=e.y.step||(r-o)/100,l=this._countDecimals(n),d=this._countDecimals(c),p=e.x.obj,h=e.x.prop,u=this.propReferences.push(p[h])-1,f=e.y.obj,g=e.y.prop,m=this.propReferences.push(f[g])-1,x=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;t=typeof t=="function"?t:null,this.imageContainer=null;const v=document.createElement("div");v.className="p-gui__vector2",v.textContent=i,x&&v.setAttribute("title",x),this.wrapper.append(v);const k=document.createElement("div");k.className="p-gui__vector-value",k.textContent=p[h]+", "+f[g],v.append(k);const b=document.createElement("div");b.className="p-gui__vector2-area",v.append(b),b.addEventListener("click",_=>{const j=parseFloat(this._mapLinear(_.offsetX,0,b.clientWidth,a,s)),I=parseFloat(this._mapLinear(_.offsetY,0,b.clientHeight,r,o));p[h]=j.toFixed(l),f[g]=I.toFixed(d),t&&t(p[h],p[g]),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()});let U=!1;b.addEventListener("pointerdown",_=>{U=!0}),b.addEventListener("pointerup",()=>{U=!1}),b.addEventListener("pointermove",_=>{if(U){const j=parseFloat(this._mapLinear(_.offsetX,0,b.clientWidth,a,s)),I=parseFloat(this._mapLinear(_.offsetY,0,b.clientHeight,r,o));p[h]=j.toFixed(l),f[g]=I.toFixed(d),t&&t(p[h],p[g]),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}});const R=document.createElement("div");R.className="p-gui__vector2-line p-gui__vector2-line-x",b.append(R);const P=document.createElement("div");P.className="p-gui__vector2-line p-gui__vector2-line-y",b.append(P);const w=document.createElement("div");w.className="p-gui__vector2-dot",b.append(w),w.style.left=this._mapLinear(p[h],a,s,0,b.clientWidth)+"px",w.style.top=this._mapLinear(f[g],o,r,b.clientHeight,0)+"px",Object.defineProperty(p,h,{set:_=>{this.propReferences[u]=_,w.style.left=this._mapLinear(_,a,s,0,b.clientWidth)+"px",k.textContent=String(_)+", "+f[g]},get:()=>this.propReferences[u]}),Object.defineProperty(f,g,{set:_=>{this.propReferences[m]=_,w.style.top=this._mapLinear(_,o,r,b.clientHeight,0)+"px",k.textContent=p[h]+", "+String(_)},get:()=>this.propReferences[m]})}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 o="p-gui__folder";this.folders.length==0&&(o+=" p-gui__folder--first"),t&&(o+=" p-gui__folder--closed");let r=a?`background-color: ${a};`:"";r+=s?`max-height: ${s}px;`:"";const n=document.createElement("div");n.className=o,n.style=r,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.8",
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;
package/src/index.js CHANGED
@@ -81,7 +81,7 @@ export default class GUI {
81
81
  this.closed = false;
82
82
  if (options.closed) this.toggleClose();
83
83
  }
84
-
84
+
85
85
  _styleInstance() {
86
86
  let scrollbar_width = this._getScrollbarWidth(this.container);
87
87
  if (this.screenCorner.x == 'left') {
@@ -625,125 +625,6 @@ export default class GUI {
625
625
  }
626
626
  }
627
627
 
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
628
  color(params = {}, callback) {
748
629
  if (typeof params != 'object') {
749
630
  throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof params}.`);
@@ -849,6 +730,133 @@ export default class GUI {
849
730
  }
850
731
  }
851
732
 
733
+ vector2( params = {}, callback) {
734
+ if (typeof params != 'object') {
735
+ throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof params}.`);
736
+ }
737
+
738
+ let name = typeof params.name == 'string' ? params.name || ' ' : ' ';
739
+
740
+ const minX = params.x.min ?? 0;
741
+ const maxX = params.x.max ?? 1;
742
+ const minY = params.y.min ?? 0;
743
+ const maxY = params.y.max ?? 1;
744
+ const stepX = params.x.step || (maxX - minX) / 100;
745
+ const stepY = params.y.step || (maxY - minY) / 100;
746
+ const decimalsX = this._countDecimals(stepX);
747
+ const decimalsY = this._countDecimals(stepY);
748
+
749
+ const objectX = params.x.obj;
750
+ const propX = params.x.prop;
751
+ const propXReferenceIndex = this.propReferences.push(objectX[propX]) - 1;
752
+
753
+ const objectY = params.y.obj;
754
+ const propY = params.y.prop;
755
+ const propYReferenceIndex = this.propReferences.push(objectY[propY]) - 1;
756
+
757
+ const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? name : null);
758
+
759
+ callback = typeof callback == 'function' ? callback : null;
760
+
761
+ this.imageContainer = null;
762
+
763
+ const container = document.createElement('div');
764
+ container.className = 'p-gui__vector2';
765
+ container.textContent = name;
766
+ if ( tooltip ) {
767
+ container.setAttribute('title', tooltip);
768
+ }
769
+ this.wrapper.append(container);
770
+
771
+ const vector_value = document.createElement('div');
772
+ vector_value.className = 'p-gui__vector-value';
773
+ vector_value.textContent = objectX[propX] + ', ' + objectY[propY];
774
+ container.append(vector_value);
775
+
776
+ const area = document.createElement('div');
777
+ area.className = 'p-gui__vector2-area';
778
+ container.append(area);
779
+ area.addEventListener('click', evt => {
780
+ const newX = parseFloat(this._mapLinear(evt.offsetX, 0, area.clientWidth, minX, maxX));
781
+ const newY = parseFloat(this._mapLinear(evt.offsetY, 0, area.clientHeight, maxY, minY));
782
+ objectX[propX] = newX.toFixed(decimalsX);
783
+ objectY[propY] = newY.toFixed(decimalsY);
784
+
785
+ if (callback) {
786
+ callback(objectX[propX], objectX[propY]);
787
+ }
788
+
789
+ if (this.onUpdate) {
790
+ this.onUpdate();
791
+ } else if (this.isFolder && this.firstParent.onUpdate) {
792
+ this.firstParent.onUpdate();
793
+ }
794
+ });
795
+
796
+ let pointer_is_down = false;
797
+ area.addEventListener('pointerdown', (evt) => {
798
+ pointer_is_down = true;
799
+ });
800
+ area.addEventListener('pointerup', () => {
801
+ pointer_is_down = false;
802
+ });
803
+ area.addEventListener('pointermove', (evt) => {
804
+ if (pointer_is_down) {
805
+ const newX = parseFloat(this._mapLinear(evt.offsetX, 0, area.clientWidth, minX, maxX));
806
+ const newY = parseFloat(this._mapLinear(evt.offsetY, 0, area.clientHeight, maxY, minY));
807
+ objectX[propX] = newX.toFixed(decimalsX);
808
+ objectY[propY] = newY.toFixed(decimalsY);
809
+
810
+ if (callback) {
811
+ callback(objectX[propX], objectX[propY]);
812
+ }
813
+
814
+ if (this.onUpdate) {
815
+ this.onUpdate();
816
+ } else if (this.isFolder && this.firstParent.onUpdate) {
817
+ this.firstParent.onUpdate();
818
+ }
819
+ }
820
+ });
821
+
822
+ const line_x = document.createElement('div');
823
+ line_x.className = 'p-gui__vector2-line p-gui__vector2-line-x';
824
+ area.append(line_x);
825
+
826
+ const line_y = document.createElement('div');
827
+ line_y.className = 'p-gui__vector2-line p-gui__vector2-line-y';
828
+ area.append(line_y);
829
+
830
+ const dot = document.createElement('div');
831
+ dot.className = 'p-gui__vector2-dot';
832
+ area.append(dot);
833
+
834
+ dot.style.left = this._mapLinear(objectX[propX], minX, maxX, 0, area.clientWidth) + 'px';
835
+ dot.style.top = this._mapLinear(objectY[propY], minY, maxY, area.clientHeight, 0) + 'px';
836
+
837
+ Object.defineProperty( objectX, propX, {
838
+ set: val => {
839
+ this.propReferences[propXReferenceIndex] = val;
840
+ dot.style.left = this._mapLinear(val, minX, maxX, 0, area.clientWidth) + 'px';
841
+ vector_value.textContent = String( val ) + ', ' + objectY[propY];
842
+ },
843
+ get: () => {
844
+ return this.propReferences[propXReferenceIndex];
845
+ }
846
+ });
847
+
848
+ Object.defineProperty( objectY, propY, {
849
+ set: val => {
850
+ this.propReferences[propYReferenceIndex] = val;
851
+ dot.style.top = this._mapLinear(val, minY, maxY, area.clientHeight, 0) + 'px';
852
+ vector_value.textContent = objectX[propX] + ', ' + String( val );
853
+ },
854
+ get: () => {
855
+ return this.propReferences[propYReferenceIndex];
856
+ }
857
+ });
858
+ }
859
+
852
860
  folder(options = {}) {
853
861
  let closed = typeof options.closed == 'boolean' ? options.closed : false;
854
862
  let name = options.name || '';
@@ -947,4 +955,22 @@ export default class GUI {
947
955
  _mapLinear( x, a1, a2, b1, b2 ) {
948
956
  return b1 + ( x - a1 ) * ( b2 - b1 ) / ( a2 - a1 );
949
957
  }
958
+
959
+ _countDecimals(num) {
960
+ // Convert the number to a string
961
+ const numStr = num.toString();
962
+
963
+ // Find the position of the decimal point
964
+ const decimalIndex = numStr.indexOf('.');
965
+
966
+ // If there is no decimal point, return 0
967
+ if (decimalIndex === -1) {
968
+ return 0;
969
+ }
970
+
971
+ // Calculate the number of digits after the decimal point
972
+ const decimalPlaces = numStr.length - decimalIndex - 1;
973
+
974
+ return decimalPlaces;
975
+ }
950
976
  }
@@ -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