perfect-gui 4.11.7 → 4.11.9

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 C {
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 C {
6
6
  this.isObject = !1;
7
7
  let s = null;
8
8
  this.obj = t.obj, this.prop = t.prop;
9
- let r = typeof t.value == "number" ? t.value : null;
10
- if (this.min = t.min ?? 0, this.max = t.max ?? 1, this.step = t.step || (this.max - this.min) / 100, this.decimals = this.parent._countDecimals(this.step), this.callback = typeof i == "function" ? i : null, r !== null)
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 C {
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.'), r = (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
22
  const n = document.createElement("div");
23
- n.className = "p-gui__slider", o && n.setAttribute("title", o);
23
+ n.className = "p-gui__slider", r && n.setAttribute("title", r);
24
24
  const c = document.createElement("div");
25
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] : r, n.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", () => {
@@ -43,13 +43,13 @@ class C {
43
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, r = 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 n = this.min + (this.max - this.min) * (o - a / 2) / (i - a);
50
- n > r ? n = this._quantizeFloor(n, this.step) : n = this._quantizeCeil(n, this.step), n = parseFloat(n.toFixed(9));
51
- const c = parseFloat((r + this.step).toFixed(9)), l = parseFloat((r - this.step).toFixed(9));
52
- (n >= c || n <= l) && (n = n.toFixed(this.decimals), this.valueInput.value = n, this.ctrlDiv.prevPosition = e.clientX, this.handle.style.transform = `translate(-50%, -50%) translateX(${o}px)`, this.handle.position = o, this.filling.style.width = this.handle.position + "px", this._triggerCallbacks());
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());
53
53
  }
54
54
  _updateHandlePositionFromValue() {
55
55
  const e = this.ctrlDiv.offsetWidth, t = this.handle.offsetWidth;
@@ -72,49 +72,6 @@ class C {
72
72
  return t * Math.floor(e / t);
73
73
  }
74
74
  }
75
- function R(f = {}, e) {
76
- if (typeof f != "object")
77
- throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof f}.`);
78
- let t = typeof f.name == "string" && f.name || " ";
79
- const i = f.x.min ?? 0, a = f.x.max ?? 1, s = f.y.min ?? 0, r = f.y.max ?? 1, o = f.x.step || (a - i) / 100, n = f.y.step || (r - s) / 100, c = this._countDecimals(o), l = this._countDecimals(n), d = f.x.obj, h = f.x.prop, g = this.propReferences.push(d[h]) - 1, p = f.y.obj, u = f.y.prop, v = this.propReferences.push(p[u]) - 1, x = typeof f.tooltip == "string" ? f.tooltip : f.tooltip === !0 ? t : null;
80
- e = typeof e == "function" ? e : null, this.imageContainer = null;
81
- const _ = document.createElement("div");
82
- _.className = "p-gui__vector2", _.textContent = t, x && _.setAttribute("title", x), this.wrapper.append(_);
83
- const w = document.createElement("div");
84
- w.className = "p-gui__vector-value", w.textContent = d[h] + ", " + p[u], _.append(w);
85
- const b = document.createElement("div");
86
- b.className = "p-gui__vector2-area", _.append(b), b.addEventListener("click", (m) => {
87
- const k = parseFloat(this._mapLinear(m.offsetX, 0, b.clientWidth, i, a)), E = parseFloat(this._mapLinear(m.offsetY, 0, b.clientHeight, r, s));
88
- d[h] = k.toFixed(c), p[u] = E.toFixed(l), e && e(d[h], d[u]), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
89
- });
90
- let A = !1;
91
- b.addEventListener("pointerdown", (m) => {
92
- A = !0;
93
- }), b.addEventListener("pointerup", () => {
94
- A = !1;
95
- }), b.addEventListener("pointermove", (m) => {
96
- if (A) {
97
- const k = parseFloat(this._mapLinear(m.offsetX, 0, b.clientWidth, i, a)), E = parseFloat(this._mapLinear(m.offsetY, 0, b.clientHeight, r, s));
98
- d[h] = k.toFixed(c), p[u] = E.toFixed(l), e && e(d[h], d[u]), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
99
- }
100
- });
101
- const U = document.createElement("div");
102
- U.className = "p-gui__vector2-line p-gui__vector2-line-x", b.append(U);
103
- const j = document.createElement("div");
104
- j.className = "p-gui__vector2-line p-gui__vector2-line-y", b.append(j);
105
- const y = document.createElement("div");
106
- y.className = "p-gui__vector2-dot", b.append(y), y.style.left = this._mapLinear(d[h], i, a, 0, b.clientWidth) + "px", y.style.top = this._mapLinear(p[u], s, r, b.clientHeight, 0) + "px", Object.defineProperty(d, h, {
107
- set: (m) => {
108
- this.propReferences[g] = m, y.style.left = this._mapLinear(m, i, a, 0, b.clientWidth) + "px", w.textContent = String(m) + ", " + p[u];
109
- },
110
- get: () => this.propReferences[g]
111
- }), Object.defineProperty(p, u, {
112
- set: (m) => {
113
- this.propReferences[v] = m, y.style.top = this._mapLinear(m, s, r, b.clientHeight, 0) + "px", w.textContent = d[h] + ", " + String(m);
114
- },
115
- get: () => this.propReferences[v]
116
- });
117
- }
118
75
  const P = (
119
76
  /* css */
120
77
  `
@@ -519,7 +476,7 @@ const P = (
519
476
  }
520
477
  `
521
478
  );
522
- function M(f) {
479
+ function M(U) {
523
480
  return (
524
481
  /* css */
525
482
  `
@@ -534,7 +491,7 @@ function M(f) {
534
491
  --color-accent-hover: #218fda;
535
492
  --transition: .1s linear;
536
493
 
537
- position: ${f};
494
+ position: ${U};
538
495
  top: 0;
539
496
  left: 0;
540
497
  transform: translate3d(0,0,0);
@@ -670,13 +627,13 @@ function M(f) {
670
627
  `
671
628
  );
672
629
  }
673
- class I {
630
+ class C {
674
631
  constructor(e = {}) {
675
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) {
676
633
  this._folderConstructor(e.folderOptions);
677
634
  return;
678
635
  }
679
- typeof e.onUpdate == "function" && (this.onUpdate = e.onUpdate), this.name = e != null && typeof e.name == "string" ? e.name : "", this.backgroundColor = e.color || null, this.opacity = e.opacity || 1, this.container == document.body ? this.maxHeight = window.innerHeight : this.maxHeight = Math.min(this.container.clientHeight, window.innerHeight), e.maxHeight && (this.initMaxHeight = e.maxHeight, this.maxHeight = Math.min(this.initMaxHeight, this.maxHeight)), this.screenCorner = this._parseScreenCorner(e.position), window.perfectGUI || (window.perfectGUI = {}), window.perfectGUI.instanceCounter == null ? window.perfectGUI.instanceCounter = 0 : window.perfectGUI.instanceCounter++, this.instanceId = window.perfectGUI.instanceCounter, this.wrapperWidth = e.width || 290, this.stylesheet = document.createElement("style"), this.stylesheet.setAttribute("type", "text/css"), this.stylesheet.setAttribute("id", "lm-gui-stylesheet"), document.head.append(this.stylesheet), this.instanceId == 0 && this._addStyles(`${M(this.position_type)}`), this._styleInstance(), this._addWrapper(), this.wrapper.setAttribute("data-corner-x", this.screenCorner.x), this.wrapper.setAttribute("data-corner-y", this.screenCorner.y), e.autoRepositioning != !1 && window.addEventListener("resize", this._handleResize.bind(this)), this._handleResize(), this.hasBeenDragged = !1, e.draggable == !0 && this._makeDraggable(), this.closed = !1, e.closed && this.toggleClose(), this.vector2 = R;
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();
680
637
  }
681
638
  _styleInstance() {
682
639
  let e = this._getScrollbarWidth(this.container);
@@ -748,50 +705,50 @@ class I {
748
705
  throw typeof e.path == null ? Error("[GUI] image() path must be provided.") : Error("[GUI] image() path must be a string.");
749
706
  let a = i.replace(/^.*[\\\/]/, ""), s;
750
707
  e.name == null ? s = a : s = typeof e.name == "string" && e.name || " ";
751
- const r = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null, o = e.selected === !0, n = e.selectionBorder !== !1;
708
+ const o = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null, r = e.selected === !0, n = e.selectionBorder !== !1;
752
709
  let c = "";
753
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));
754
711
  const l = document.createElement("div");
755
- l.className = "p-gui__image", l.style = "background-image: url(" + i + "); " + c, r && l.setAttribute("title", r), this.imageContainer.append(l), o && n && l.classList.add("p-gui__image--selected");
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");
756
713
  const d = document.createElement("div");
757
714
  return d.className = "p-gui__image-text", d.textContent = s, l.append(d), l.addEventListener("click", () => {
758
- let h = l.parentElement.querySelectorAll(".p-gui__image--selected");
759
- for (let g = 0; g < h.length; g++)
760
- h[g].classList.remove("p-gui__image--selected");
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");
761
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();
762
719
  }), l;
763
720
  }
764
721
  slider(e = {}, t) {
765
- const i = new C(this, e, t);
722
+ const i = new R(this, e, t);
766
723
  this.wrapper.append(i);
767
724
  }
768
725
  toggle(e = {}, t) {
769
726
  if (typeof e != "object")
770
727
  throw Error(`[GUI] toggle() first parameter must be an object. Received: ${typeof e}.`);
771
- let i = typeof e.name == "string" && e.name || " ", a = !1, s = null, r = e.obj, o = e.prop, n = typeof e.value == "boolean" ? e.value : null;
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;
772
729
  if (n !== null)
773
- (o != null || r != null) && console.warn('[GUI] toggle() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
774
- else if (o != null && r != null) {
775
- if (typeof o != "string")
776
- throw Error(`[GUI] toggle() "prop" parameter must be an string. Received: ${typeof o}.`);
777
- if (typeof r != "object")
778
- throw Error(`[GUI] toggle() "obj" parameter must be an object. Received: ${typeof r}.`);
779
- i == " " && (i = o), s = this.propReferences.push(r[o]) - 1, a = !0;
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;
780
737
  } else
781
- (o != null && r == null || o == null && r == null) && console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');
738
+ (r != null && o == null || r == null && o == null) && console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');
782
739
  const c = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
783
740
  this.imageContainer = null;
784
741
  const l = document.createElement("div");
785
- l.textContent = i, l.className = "p-gui__switch", c && l.setAttribute("title", c), this.wrapper.append(l), l.addEventListener("click", (g) => {
786
- const p = g.target.childNodes[1];
787
- let u = !0;
788
- p.classList.contains("p-gui__switch-checkbox--active") && (u = !1), p.classList.toggle("p-gui__switch-checkbox--active"), a ? r[o] = u : typeof t == "function" && t(u), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
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();
789
746
  });
790
- let d = (() => a ? r[o] ? " p-gui__switch-checkbox--active" : "" : n ? " p-gui__switch-checkbox--active" : "")();
791
- const h = document.createElement("div");
792
- h.className = "p-gui__switch-checkbox" + d, l.append(h), a && Object.defineProperty(r, o, {
793
- set: (g) => {
794
- this.propReferences[s] = g, g ? h.classList.add("p-gui__switch-checkbox--active") : h.classList.remove("p-gui__switch-checkbox--active"), typeof t == "function" && t(g);
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);
795
752
  },
796
753
  get: () => this.propReferences[s]
797
754
  });
@@ -799,10 +756,10 @@ class I {
799
756
  list(e = {}, t) {
800
757
  if (typeof e != "object")
801
758
  throw Error(`[GUI] list() first parameter must be an object. Received: ${typeof e}.`);
802
- let i = typeof e.name == "string" ? e.name : " ", a = !1, s = null, r = e.obj, o = e.prop, n = Array.isArray(e.values) ? e.values : null, c, l = typeof n[0] != "string";
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";
803
760
  const d = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
804
- if (t = typeof t == "function" ? t : null, e.value !== void 0 || e.value === void 0 && r === void 0 && o === void 0)
805
- (o != null || r != null) && console.warn('[GUI] list() "obj" and "prop" parameters are ignored when a "value" parameter is used.'), c = (() => {
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 = (() => {
806
763
  if (!n)
807
764
  return null;
808
765
  if (typeof e.value == "string")
@@ -810,37 +767,37 @@ class I {
810
767
  if (typeof e.value == "number")
811
768
  return e.value;
812
769
  })();
813
- else if (o != null && r != null) {
814
- if (typeof o != "string")
815
- throw Error(`[GUI] list() "prop" parameter must be an string. Received: ${typeof o}.`);
816
- if (typeof r != "object")
817
- throw Error(`[GUI] list() "obj" parameter must be an object. Received: ${typeof 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}.`);
818
775
  c = (() => {
819
776
  if (!n)
820
777
  return null;
821
- if (typeof r[o] == "string")
822
- return l ? n.find((p) => p.value === r[o]).value : n.indexOf(r[o]);
823
- if (typeof r[o] == "number")
824
- return l ? n.find((p) => p.value === r[o]).value : r[o];
825
- })(), s = this.propReferences.push(r[o]) - 1, a = !0;
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;
826
783
  } else
827
- (o != null && r == null || o == null && r == 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.');
828
785
  this.imageContainer = null;
829
- let h = document.createElement("div");
830
- h.className = "p-gui__list", h.textContent = i, d && h.setAttribute("title", d), this.wrapper.append(h);
831
- let g = document.createElement("select");
832
- h.append(g), g.className = "p-gui__list-dropdown", g.addEventListener("change", (p) => {
833
- a ? r[o] = p.target.value : t && t(p.target.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
834
- }), n && n.forEach((p, u) => {
835
- const v = l ? p.name : p, x = l ? p.value : p;
836
- let _ = document.createElement("option");
837
- _.setAttribute("value", x), _.textContent = v, g.append(_), (!l && c == u || l && c == x) && _.setAttribute("selected", "");
838
- }), a && Object.defineProperty(r, o, {
839
- set: (p) => {
840
- let u, v, x;
841
- l ? (x = n.find((w) => w.value == p), v = (x == null ? void 0 : x.value) || n[0].value, u = n.indexOf(x)) : (typeof p == "string" && (u = n.indexOf(p), v = p), typeof p == "number" && (u = p, v = n[p])), this.propReferences[s] = l ? v : p;
842
- const _ = g.querySelector("[selected]");
843
- _ && _.removeAttribute("selected"), g.querySelectorAll("option")[u].setAttribute("selected", ""), typeof t == "function" && t(l ? x : v, u);
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;
793
+ let x = document.createElement("option");
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, {
796
+ set: (u) => {
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);
844
801
  },
845
802
  get: () => this.propReferences[s]
846
803
  });
@@ -848,45 +805,88 @@ class I {
848
805
  color(e = {}, t) {
849
806
  if (typeof e != "object")
850
807
  throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof e}.`);
851
- let i = typeof e.name == "string" && e.name || " ", a = !1, s = null, r = e.obj, o = e.prop, n;
808
+ let i = typeof e.name == "string" && e.name || " ", a = !1, s = null, o = e.obj, r = e.prop, n;
852
809
  const c = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
853
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)
854
- (o != null || r != null) && console.warn('[GUI] color() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
855
- else if (o != null && r != null) {
856
- if (typeof o != "string")
857
- throw Error(`[GUI] color() "prop" parameter must be an string. Received: ${typeof o}.`);
858
- if (typeof r != "object")
859
- throw Error(`[GUI] color() "obj" parameter must be an object. Received: ${typeof r}.`);
860
- i == " " && (i = o), s = this.propReferences.push(r[o]) - 1, a = !0;
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;
861
818
  } else
862
- (o != null && r == null || o == null && r == 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.');
863
820
  this.imageContainer = null;
864
821
  const l = document.createElement("div");
865
822
  l.className = "p-gui__color", l.textContent = i, c && l.setAttribute("title", c), this.wrapper.append(l);
866
823
  const d = document.createElement("input");
867
824
  d.className = "p-gui__color-picker", d.setAttribute("type", "color"), d.value = n, l.append(d), typeof t == "function" && d.addEventListener("input", () => {
868
- a ? r[o] = d.value : typeof t == "function" && t(d.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
869
- }), a && Object.defineProperty(r, o, {
870
- set: (h) => {
871
- this.propReferences[s] = h, d.value = h, typeof t == "function" && t(h);
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);
872
829
  },
873
830
  get: () => this.propReferences[s]
874
831
  });
875
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
+ }
876
876
  folder(e = {}) {
877
877
  let t = typeof e.closed == "boolean" ? e.closed : !1, i = e.name || "", a = e.color || null, s = e.maxHeight || null;
878
878
  this.imageContainer = null;
879
- let r = "p-gui__folder";
880
- this.folders.length == 0 && (r += " p-gui__folder--first"), t && (r += " p-gui__folder--closed");
881
- let o = a ? `background-color: ${a};` : "";
882
- o += s ? `max-height: ${s}px;` : "";
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
883
  const n = document.createElement("div");
884
- n.className = r, n.style = o, this.wrapper.append(n);
884
+ n.className = o, n.style = r, this.wrapper.append(n);
885
885
  const c = document.createElement("div");
886
886
  c.innerHTML = `<span class="p-gui__folder-arrow"></span>${i}`, c.className = "p-gui__folder-header", n.append(c), c.addEventListener("click", () => {
887
887
  n.classList.toggle("p-gui__folder--closed");
888
888
  });
889
- let l = new I({ isFolder: !0, folderOptions: {
889
+ let l = new C({ isFolder: !0, folderOptions: {
890
890
  wrapper: n,
891
891
  parent: this,
892
892
  firstParent: this.firstParent
@@ -921,5 +921,5 @@ class I {
921
921
  }
922
922
  }
923
923
  export {
924
- I as default
924
+ C as default
925
925
  };
@@ -1,4 +1,4 @@
1
- (function(A,k){typeof exports=="object"&&typeof module<"u"?module.exports=k():typeof define=="function"&&define.amd?define(k):(A=typeof globalThis<"u"?globalThis:A||self,A["Perfect GUI"]=k())})(this,function(){"use strict";class A{constructor(e,t={},i){if(this.parent=e,this.propReferences=[],typeof t!="object")throw Error(`[GUI] slider() first parameter must be an object. Received: ${typeof t}.`);let a=typeof t.name=="string"&&t.name||" ";this.isObject=!1;let s=null;this.obj=t.obj,this.prop=t.prop;let r=typeof t.value=="number"?t.value:null;if(this.min=t.min??0,this.max=t.max??1,this.step=t.step||(this.max-this.min)/100,this.decimals=this.parent._countDecimals(this.step),this.callback=typeof i=="function"?i:null,r!==null)(this.prop!=null||this.obj!=null)&&console.warn('[GUI] slider() "obj" and "prop" parameters are ignored when a "value" parameter is used.');else if(this.prop!=null&&this.obj!=null){if(typeof this.prop!="string")throw Error(`[GUI] slider() "prop" parameter must be an string. Received: ${typeof this.prop}.`);if(typeof this.obj!="object")throw Error(`[GUI] slider() "obj" parameter must be an object. Received: ${typeof this.obj}.`);a==" "&&(a=this.prop),s=this.propReferences.push(this.obj[this.prop])-1,this.isObject=!0}else(this.prop!=null&&this.obj==null||this.prop==null&&this.obj!=null)&&console.warn('[GUI] slider() "obj" and "prop" parameters must be used together.'),r=(this.max-this.min)/2;const o=typeof t.tooltip=="string"?t.tooltip:t.tooltip===!0?a:null;this.imageContainer=null;const n=document.createElement("div");n.className="p-gui__slider",o&&n.setAttribute("title",o);const c=document.createElement("div");c.className="p-gui__slider-name",c.textContent=a,n.append(c),this.ctrlDiv=document.createElement("div"),this.ctrlDiv.className="p-gui__slider-ctrl",this.ctrlDiv.setAttribute("type","range"),this.ctrlDiv.setAttribute("min",this.min),this.ctrlDiv.setAttribute("max",this.max),n.append(this.ctrlDiv);const l=document.createElement("div");return l.className="p-gui__slider-bar",this.ctrlDiv.append(l),this.handle=document.createElement("div"),this.handle.className="p-gui__slider-handle",this.ctrlDiv.append(this.handle),this.filling=document.createElement("div"),this.filling.className="p-gui__slider-filling",l.append(this.filling),this.valueInput=document.createElement("input"),this.valueInput.className="p-gui__slider-value",this.valueInput.value=this.isObject?this.obj[this.prop]:r,n.append(this.valueInput),setTimeout(()=>{const d=this.handle.offsetWidth;this.handle.position=this._mapLinear(this.valueInput.value,this.min,this.max,d/2,88-d/2),this.handle.position=Math.min(this.handle.position,88-d/2),this.handle.position=Math.max(this.handle.position,d/2),this.handle.style.transform=`translate(-50%, -50%) translateX(${this.handle.position}px)`,this.filling.style.width=`${this.handle.position}px`},0),this.valueInput.addEventListener("change",()=>{this._updateHandlePositionFromValue(),this._triggerCallbacks()}),this.ctrlDiv.addEventListener("pointerdown",d=>{this.ctrlDiv.pointerDown=!0,this.ctrlDiv.prevPosition=d.clientX,this._updateHandlePositionFromPointer(d,!0)}),window.addEventListener("pointerup",d=>{this.ctrlDiv.pointerDown=!1}),window.addEventListener("pointermove",d=>{this.ctrlDiv.pointerDown&&(this.ctrlDiv.pointerDelta=d.clientX-this.ctrlDiv.prevPosition,this._updateHandlePositionFromPointer(d))}),this.isObject&&Object.defineProperty(this.obj,this.prop,{set:d=>{this.propReferences[s]=d,this.valueInput.value=d,this._updateHandlePositionFromValue(),this.callback&&this.callback(parseFloat(this.valueInput.value))},get:()=>this.propReferences[s]}),n}_updateHandlePositionFromPointer(e,t=!1){const i=this.ctrlDiv.offsetWidth,a=this.handle.offsetWidth,s=e.clientX-this.ctrlDiv.prevPosition,r=parseFloat(this.valueInput.value);let o;t?o=e.offsetX:o=this.handle.position+s,o=Math.max(a/2,Math.min(o,i-a/2));let n=this.min+(this.max-this.min)*(o-a/2)/(i-a);n>r?n=this._quantizeFloor(n,this.step):n=this._quantizeCeil(n,this.step),n=parseFloat(n.toFixed(9));const c=parseFloat((r+this.step).toFixed(9)),l=parseFloat((r-this.step).toFixed(9));(n>=c||n<=l)&&(n=n.toFixed(this.decimals),this.valueInput.value=n,this.ctrlDiv.prevPosition=e.clientX,this.handle.style.transform=`translate(-50%, -50%) translateX(${o}px)`,this.handle.position=o,this.filling.style.width=this.handle.position+"px",this._triggerCallbacks())}_updateHandlePositionFromValue(){const e=this.ctrlDiv.offsetWidth,t=this.handle.offsetWidth;let i=this._mapLinear(this.valueInput.value,this.min,this.max,t/2,e-t/2);i=Math.max(t/2,Math.min(i,e-t/2)),this.handle.style.transform=`translate(-50%, -50%) translateX(${i}px)`,this.handle.position=i,this.filling.style.width=this.handle.position+"px"}_triggerCallbacks(){this.isObject?this.obj[this.prop]=parseFloat(this.valueInput.value):this.callback&&this.callback(parseFloat(this.valueInput.value)),this.parent.onUpdate?this.parent.onUpdate():this.parent.isFolder&&this.parent.firstParent.onUpdate&&this.parent.firstParent.onUpdate()}_mapLinear(e,t,i,a,s){return a+(e-t)*(s-a)/(i-t)}_quantize(e,t){return t*Math.round(e/t)}_quantizeCeil(e,t){return t*Math.ceil(e/t)}_quantizeFloor(e,t){return t*Math.floor(e/t)}}function k(f={},e){if(typeof f!="object")throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof f}.`);let t=typeof f.name=="string"&&f.name||" ";const i=f.x.min??0,a=f.x.max??1,s=f.y.min??0,r=f.y.max??1,o=f.x.step||(a-i)/100,n=f.y.step||(r-s)/100,c=this._countDecimals(o),l=this._countDecimals(n),d=f.x.obj,h=f.x.prop,g=this.propReferences.push(d[h])-1,p=f.y.obj,u=f.y.prop,v=this.propReferences.push(p[u])-1,x=typeof f.tooltip=="string"?f.tooltip:f.tooltip===!0?t:null;e=typeof e=="function"?e:null,this.imageContainer=null;const _=document.createElement("div");_.className="p-gui__vector2",_.textContent=t,x&&_.setAttribute("title",x),this.wrapper.append(_);const w=document.createElement("div");w.className="p-gui__vector-value",w.textContent=d[h]+", "+p[u],_.append(w);const b=document.createElement("div");b.className="p-gui__vector2-area",_.append(b),b.addEventListener("click",m=>{const j=parseFloat(this._mapLinear(m.offsetX,0,b.clientWidth,i,a)),I=parseFloat(this._mapLinear(m.offsetY,0,b.clientHeight,r,s));d[h]=j.toFixed(c),p[u]=I.toFixed(l),e&&e(d[h],d[u]),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()});let U=!1;b.addEventListener("pointerdown",m=>{U=!0}),b.addEventListener("pointerup",()=>{U=!1}),b.addEventListener("pointermove",m=>{if(U){const j=parseFloat(this._mapLinear(m.offsetX,0,b.clientWidth,i,a)),I=parseFloat(this._mapLinear(m.offsetY,0,b.clientHeight,r,s));d[h]=j.toFixed(c),p[u]=I.toFixed(l),e&&e(d[h],d[u]),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}});const C=document.createElement("div");C.className="p-gui__vector2-line p-gui__vector2-line-x",b.append(C);const R=document.createElement("div");R.className="p-gui__vector2-line p-gui__vector2-line-y",b.append(R);const y=document.createElement("div");y.className="p-gui__vector2-dot",b.append(y),y.style.left=this._mapLinear(d[h],i,a,0,b.clientWidth)+"px",y.style.top=this._mapLinear(p[u],s,r,b.clientHeight,0)+"px",Object.defineProperty(d,h,{set:m=>{this.propReferences[g]=m,y.style.left=this._mapLinear(m,i,a,0,b.clientWidth)+"px",w.textContent=String(m)+", "+p[u]},get:()=>this.propReferences[g]}),Object.defineProperty(p,u,{set:m=>{this.propReferences[v]=m,y.style.top=this._mapLinear(m,s,r,b.clientHeight,0)+"px",w.textContent=d[h]+", "+String(m)},get:()=>this.propReferences[v]})}const P=`
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;
@@ -377,7 +377,7 @@
377
377
  .p-gui__folder--closed .p-gui__folder-arrow {
378
378
  transform: rotate(0deg);
379
379
  }
380
- `;function M(f){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: ${f};
392
+ position: ${C};
393
393
  top: 0;
394
394
  left: 0;
395
395
  transform: translate3d(0,0,0);
@@ -507,7 +507,7 @@
507
507
  border-color: rgba(255,255,255,.2);
508
508
  }
509
509
 
510
- ${P}
510
+ ${A}
511
511
 
512
512
  ${H}
513
513
 
@@ -522,11 +522,11 @@
522
522
  ${L}
523
523
 
524
524
  ${N}
525
- `}class E{constructor(e={}){if(this.firstParent=this,e.container?(this.container=typeof e.container=="string"?document.querySelector(e.container):e.container,this.position_type="absolute"):(this.container=document.body,this.position_type="fixed"),this.propReferences=[],this.folders=[],e.isFolder){this._folderConstructor(e.folderOptions);return}typeof e.onUpdate=="function"&&(this.onUpdate=e.onUpdate),this.name=e!=null&&typeof e.name=="string"?e.name:"",this.backgroundColor=e.color||null,this.opacity=e.opacity||1,this.container==document.body?this.maxHeight=window.innerHeight:this.maxHeight=Math.min(this.container.clientHeight,window.innerHeight),e.maxHeight&&(this.initMaxHeight=e.maxHeight,this.maxHeight=Math.min(this.initMaxHeight,this.maxHeight)),this.screenCorner=this._parseScreenCorner(e.position),window.perfectGUI||(window.perfectGUI={}),window.perfectGUI.instanceCounter==null?window.perfectGUI.instanceCounter=0:window.perfectGUI.instanceCounter++,this.instanceId=window.perfectGUI.instanceCounter,this.wrapperWidth=e.width||290,this.stylesheet=document.createElement("style"),this.stylesheet.setAttribute("type","text/css"),this.stylesheet.setAttribute("id","lm-gui-stylesheet"),document.head.append(this.stylesheet),this.instanceId==0&&this._addStyles(`${M(this.position_type)}`),this._styleInstance(),this._addWrapper(),this.wrapper.setAttribute("data-corner-x",this.screenCorner.x),this.wrapper.setAttribute("data-corner-y",this.screenCorner.y),e.autoRepositioning!=!1&&window.addEventListener("resize",this._handleResize.bind(this)),this._handleResize(),this.hasBeenDragged=!1,e.draggable==!0&&this._makeDraggable(),this.closed=!1,e.closed&&this.toggleClose(),this.vector2=k}_styleInstance(){let e=this._getScrollbarWidth(this.container);if(this.screenCorner.x=="left"?this.xOffset=0:this.xOffset=this.container.clientWidth-this.wrapperWidth-e,this.instanceId>0){let t=this.container.querySelectorAll(".p-gui");for(let i=0;i<t.length;i++)this.screenCorner.y==t[i].dataset.cornerY&&(this.screenCorner.x=="left"&&t[i].dataset.cornerX=="left"?this.xOffset+=t[i].offsetWidth:this.screenCorner.x=="right"&&t[i].dataset.cornerX=="right"&&(this.xOffset-=t[i].offsetWidth))}this.yOffset=0,this.position={prevX:this.xOffset,prevY:this.yOffset,x:this.xOffset,y:this.yOffset},this._addStyles(`#p-gui-${this.instanceId} {
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 r=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?s:null,o=e.selected===!0,n=e.selectionBorder!==!1;let c="";e.width&&(typeof e.width=="number"&&(e.width+="px"),c+=`flex: 0 0 calc(${e.width} - 5px); `),e.height&&(typeof e.height=="number"&&(e.height+="px"),c+=`height: ${e.height}; `),this.imageContainer||(this.imageContainer=document.createElement("div"),this.imageContainer.className="p-gui__image-container",this.wrapper.append(this.imageContainer));const l=document.createElement("div");l.className="p-gui__image",l.style="background-image: url("+i+"); "+c,r&&l.setAttribute("title",r),this.imageContainer.append(l),o&&n&&l.classList.add("p-gui__image--selected");const d=document.createElement("div");return d.className="p-gui__image-text",d.textContent=s,l.append(d),l.addEventListener("click",()=>{let h=l.parentElement.querySelectorAll(".p-gui__image--selected");for(let g=0;g<h.length;g++)h[g].classList.remove("p-gui__image--selected");n&&l.classList.add("p-gui__image--selected"),typeof t=="function"&&t({path:i,text:s}),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),l}slider(e={},t){const i=new A(this,e,t);this.wrapper.append(i)}toggle(e={},t){if(typeof e!="object")throw Error(`[GUI] toggle() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"&&e.name||" ",a=!1,s=null,r=e.obj,o=e.prop,n=typeof e.value=="boolean"?e.value:null;if(n!==null)(o!=null||r!=null)&&console.warn('[GUI] toggle() "obj" and "prop" parameters are ignored when a "value" parameter is used.');else if(o!=null&&r!=null){if(typeof o!="string")throw Error(`[GUI] toggle() "prop" parameter must be an string. Received: ${typeof o}.`);if(typeof r!="object")throw Error(`[GUI] toggle() "obj" parameter must be an object. Received: ${typeof r}.`);i==" "&&(i=o),s=this.propReferences.push(r[o])-1,a=!0}else(o!=null&&r==null||o==null&&r==null)&&console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');const c=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;this.imageContainer=null;const l=document.createElement("div");l.textContent=i,l.className="p-gui__switch",c&&l.setAttribute("title",c),this.wrapper.append(l),l.addEventListener("click",g=>{const p=g.target.childNodes[1];let u=!0;p.classList.contains("p-gui__switch-checkbox--active")&&(u=!1),p.classList.toggle("p-gui__switch-checkbox--active"),a?r[o]=u:typeof t=="function"&&t(u),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()});let d=(()=>a?r[o]?" p-gui__switch-checkbox--active":"":n?" p-gui__switch-checkbox--active":"")();const h=document.createElement("div");h.className="p-gui__switch-checkbox"+d,l.append(h),a&&Object.defineProperty(r,o,{set:g=>{this.propReferences[s]=g,g?h.classList.add("p-gui__switch-checkbox--active"):h.classList.remove("p-gui__switch-checkbox--active"),typeof t=="function"&&t(g)},get:()=>this.propReferences[s]})}list(e={},t){if(typeof e!="object")throw Error(`[GUI] list() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"?e.name:" ",a=!1,s=null,r=e.obj,o=e.prop,n=Array.isArray(e.values)?e.values:null,c,l=typeof n[0]!="string";const d=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;if(t=typeof t=="function"?t:null,e.value!==void 0||e.value===void 0&&r===void 0&&o===void 0)(o!=null||r!=null)&&console.warn('[GUI] list() "obj" and "prop" parameters are ignored when a "value" parameter is used.'),c=(()=>{if(!n)return null;if(typeof e.value=="string")return n.indexOf(e.value);if(typeof e.value=="number")return e.value})();else if(o!=null&&r!=null){if(typeof o!="string")throw Error(`[GUI] list() "prop" parameter must be an string. Received: ${typeof o}.`);if(typeof r!="object")throw Error(`[GUI] list() "obj" parameter must be an object. Received: ${typeof r}.`);c=(()=>{if(!n)return null;if(typeof r[o]=="string")return l?n.find(p=>p.value===r[o]).value:n.indexOf(r[o]);if(typeof r[o]=="number")return l?n.find(p=>p.value===r[o]).value:r[o]})(),s=this.propReferences.push(r[o])-1,a=!0}else(o!=null&&r==null||o==null&&r==null)&&console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');this.imageContainer=null;let h=document.createElement("div");h.className="p-gui__list",h.textContent=i,d&&h.setAttribute("title",d),this.wrapper.append(h);let g=document.createElement("select");h.append(g),g.className="p-gui__list-dropdown",g.addEventListener("change",p=>{a?r[o]=p.target.value:t&&t(p.target.value),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),n&&n.forEach((p,u)=>{const v=l?p.name:p,x=l?p.value:p;let _=document.createElement("option");_.setAttribute("value",x),_.textContent=v,g.append(_),(!l&&c==u||l&&c==x)&&_.setAttribute("selected","")}),a&&Object.defineProperty(r,o,{set:p=>{let u,v,x;l?(x=n.find(w=>w.value==p),v=(x==null?void 0:x.value)||n[0].value,u=n.indexOf(x)):(typeof p=="string"&&(u=n.indexOf(p),v=p),typeof p=="number"&&(u=p,v=n[p])),this.propReferences[s]=l?v:p;const _=g.querySelector("[selected]");_&&_.removeAttribute("selected"),g.querySelectorAll("option")[u].setAttribute("selected",""),typeof t=="function"&&t(l?x:v,u)},get:()=>this.propReferences[s]})}color(e={},t){if(typeof e!="object")throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof e}.`);let i=typeof e.name=="string"&&e.name||" ",a=!1,s=null,r=e.obj,o=e.prop,n;const c=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;if(typeof e.value=="string"&&(e.value.length!=7||e.value[0]!="#"?console.error(`[GUI] color() 'value' parameter must be an hexadecimal string in the format "#ffffff". Received: "${e.value}".`):n=e.value),n||(n="#000000"),e.value!==void 0)(o!=null||r!=null)&&console.warn('[GUI] color() "obj" and "prop" parameters are ignored when a "value" parameter is used.');else if(o!=null&&r!=null){if(typeof o!="string")throw Error(`[GUI] color() "prop" parameter must be an string. Received: ${typeof o}.`);if(typeof r!="object")throw Error(`[GUI] color() "obj" parameter must be an object. Received: ${typeof r}.`);i==" "&&(i=o),s=this.propReferences.push(r[o])-1,a=!0}else(o!=null&&r==null||o==null&&r==null)&&console.warn('[GUI] color() "obj" and "prop" parameters must be used together.');this.imageContainer=null;const l=document.createElement("div");l.className="p-gui__color",l.textContent=i,c&&l.setAttribute("title",c),this.wrapper.append(l);const d=document.createElement("input");d.className="p-gui__color-picker",d.setAttribute("type","color"),d.value=n,l.append(d),typeof t=="function"&&d.addEventListener("input",()=>{a?r[o]=d.value:typeof t=="function"&&t(d.value),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),a&&Object.defineProperty(r,o,{set:h=>{this.propReferences[s]=h,d.value=h,typeof t=="function"&&t(h)},get:()=>this.propReferences[s]})}folder(e={}){let t=typeof e.closed=="boolean"?e.closed:!1,i=e.name||"",a=e.color||null,s=e.maxHeight||null;this.imageContainer=null;let r="p-gui__folder";this.folders.length==0&&(r+=" p-gui__folder--first"),t&&(r+=" p-gui__folder--closed");let o=a?`background-color: ${a};`:"";o+=s?`max-height: ${s}px;`:"";const n=document.createElement("div");n.className=r,n.style=o,this.wrapper.append(n);const c=document.createElement("div");c.innerHTML=`<span class="p-gui__folder-arrow"></span>${i}`,c.className="p-gui__folder-header",n.append(c),c.addEventListener("click",()=>{n.classList.toggle("p-gui__folder--closed")});let l=new E({isFolder:!0,folderOptions:{wrapper:n,parent:this,firstParent:this.firstParent}});return this.folders.push(l),l}_makeDraggable(){var e=this;this.header.addEventListener("pointerdown",t),this.header.addEventListener("pointerup",a);function t(s){s.preventDefault(),e.position.initX=e.position.x,e.position.initY=e.position.y,e.position.prevX=s.clientX,e.position.prevY=s.clientY,document.addEventListener("pointermove",i)}function i(s){s.preventDefault(),e.hasBeenDragged||(e.hasBeenDragged=!0,e.wrapper.setAttribute("data-dragged","true")),e.position.x=e.position.initX+s.clientX-e.position.prevX,e.position.y=e.position.initY+s.clientY-e.position.prevY,e.wrapper.style.transform="translate3d("+e.position.x+"px,"+e.position.y+"px,0)"}function a(s){document.removeEventListener("pointermove",i)}}toggleClose(){this.closed=!this.closed,this.closed?(this.previousInnerScroll=this.wrapper.scrollTop,this.wrapper.scrollTo(0,0)):this.wrapper.scrollTo(0,this.previousInnerScroll),this.wrapper.classList.toggle("p-gui--collapsed")}kill(){this.wrapper.remove()}_mapLinear(e,t,i,a,s){return a+(e-t)*(s-a)/(i-t)}_countDecimals(e){const t=e.toString(),i=t.indexOf(".");return i===-1?0:t.length-i-1}}return E});
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.7",
3
+ "version": "4.11.9",
4
4
  "description": "GUI for JavaScript",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -0,0 +1,27 @@
1
+ import GUI from '../index.js';
2
+
3
+ /*
4
+ GUI.prototype.materialFolder = materialFolder;
5
+ gui.materialFolder({name: 'material', obj: material})
6
+ */
7
+ export function materialFolder(params = {}) {
8
+ const material = params.obj;
9
+
10
+ if (material.isMeshStandardMaterial) {
11
+ console.error('[GUI materialFolder]', 'materialFolder() only works with meshStandardMaterial');
12
+ }
13
+
14
+ const folder = this.folder({ name: params.name });
15
+
16
+ folder.slider({ obj: material, prop: 'roughness' });
17
+ folder.slider({ obj: material, prop: 'metalness' });
18
+ folder.color({ name: 'color', obj: material, value: '#'+material.color.getHexString() }, val => {
19
+ material.color.set(val)
20
+ });
21
+ folder.slider({ obj: material, prop: 'envMapIntensity' });
22
+ return folder;
23
+ }
24
+
25
+ export function threejsColor() {
26
+
27
+ }
package/src/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import Slider from './components/Slider';
2
- import vector2 from './components/vector2';
3
2
  import styles from './styles/styles';
4
3
 
5
4
  export default class GUI {
@@ -81,10 +80,8 @@ export default class GUI {
81
80
 
82
81
  this.closed = false;
83
82
  if (options.closed) this.toggleClose();
84
-
85
- this.vector2 = vector2;
86
83
  }
87
-
84
+
88
85
  _styleInstance() {
89
86
  let scrollbar_width = this._getScrollbarWidth(this.container);
90
87
  if (this.screenCorner.x == 'left') {
@@ -195,6 +192,7 @@ export default class GUI {
195
192
  this.wrapper = document.createElement('div');
196
193
  this.wrapper.id = 'p-gui-'+this.instanceId;
197
194
  this.wrapper.className = 'p-gui';
195
+ this.wrapper.setAttribute('data-lenis-prevent', '');
198
196
  this.container.append(this.wrapper);
199
197
 
200
198
  this.header = document.createElement('div');
@@ -733,6 +731,133 @@ export default class GUI {
733
731
  }
734
732
  }
735
733
 
734
+ vector2( params = {}, callback) {
735
+ if (typeof params != 'object') {
736
+ throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof params}.`);
737
+ }
738
+
739
+ let name = typeof params.name == 'string' ? params.name || ' ' : ' ';
740
+
741
+ const minX = params.x.min ?? 0;
742
+ const maxX = params.x.max ?? 1;
743
+ const minY = params.y.min ?? 0;
744
+ const maxY = params.y.max ?? 1;
745
+ const stepX = params.x.step || (maxX - minX) / 100;
746
+ const stepY = params.y.step || (maxY - minY) / 100;
747
+ const decimalsX = this._countDecimals(stepX);
748
+ const decimalsY = this._countDecimals(stepY);
749
+
750
+ const objectX = params.x.obj;
751
+ const propX = params.x.prop;
752
+ const propXReferenceIndex = this.propReferences.push(objectX[propX]) - 1;
753
+
754
+ const objectY = params.y.obj;
755
+ const propY = params.y.prop;
756
+ const propYReferenceIndex = this.propReferences.push(objectY[propY]) - 1;
757
+
758
+ const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? name : null);
759
+
760
+ callback = typeof callback == 'function' ? callback : null;
761
+
762
+ this.imageContainer = null;
763
+
764
+ const container = document.createElement('div');
765
+ container.className = 'p-gui__vector2';
766
+ container.textContent = name;
767
+ if ( tooltip ) {
768
+ container.setAttribute('title', tooltip);
769
+ }
770
+ this.wrapper.append(container);
771
+
772
+ const vector_value = document.createElement('div');
773
+ vector_value.className = 'p-gui__vector-value';
774
+ vector_value.textContent = objectX[propX] + ', ' + objectY[propY];
775
+ container.append(vector_value);
776
+
777
+ const area = document.createElement('div');
778
+ area.className = 'p-gui__vector2-area';
779
+ container.append(area);
780
+ area.addEventListener('click', evt => {
781
+ const newX = parseFloat(this._mapLinear(evt.offsetX, 0, area.clientWidth, minX, maxX));
782
+ const newY = parseFloat(this._mapLinear(evt.offsetY, 0, area.clientHeight, maxY, minY));
783
+ objectX[propX] = newX.toFixed(decimalsX);
784
+ objectY[propY] = newY.toFixed(decimalsY);
785
+
786
+ if (callback) {
787
+ callback(objectX[propX], objectX[propY]);
788
+ }
789
+
790
+ if (this.onUpdate) {
791
+ this.onUpdate();
792
+ } else if (this.isFolder && this.firstParent.onUpdate) {
793
+ this.firstParent.onUpdate();
794
+ }
795
+ });
796
+
797
+ let pointer_is_down = false;
798
+ area.addEventListener('pointerdown', (evt) => {
799
+ pointer_is_down = true;
800
+ });
801
+ area.addEventListener('pointerup', () => {
802
+ pointer_is_down = false;
803
+ });
804
+ area.addEventListener('pointermove', (evt) => {
805
+ if (pointer_is_down) {
806
+ const newX = parseFloat(this._mapLinear(evt.offsetX, 0, area.clientWidth, minX, maxX));
807
+ const newY = parseFloat(this._mapLinear(evt.offsetY, 0, area.clientHeight, maxY, minY));
808
+ objectX[propX] = newX.toFixed(decimalsX);
809
+ objectY[propY] = newY.toFixed(decimalsY);
810
+
811
+ if (callback) {
812
+ callback(objectX[propX], objectX[propY]);
813
+ }
814
+
815
+ if (this.onUpdate) {
816
+ this.onUpdate();
817
+ } else if (this.isFolder && this.firstParent.onUpdate) {
818
+ this.firstParent.onUpdate();
819
+ }
820
+ }
821
+ });
822
+
823
+ const line_x = document.createElement('div');
824
+ line_x.className = 'p-gui__vector2-line p-gui__vector2-line-x';
825
+ area.append(line_x);
826
+
827
+ const line_y = document.createElement('div');
828
+ line_y.className = 'p-gui__vector2-line p-gui__vector2-line-y';
829
+ area.append(line_y);
830
+
831
+ const dot = document.createElement('div');
832
+ dot.className = 'p-gui__vector2-dot';
833
+ area.append(dot);
834
+
835
+ dot.style.left = this._mapLinear(objectX[propX], minX, maxX, 0, area.clientWidth) + 'px';
836
+ dot.style.top = this._mapLinear(objectY[propY], minY, maxY, area.clientHeight, 0) + 'px';
837
+
838
+ Object.defineProperty( objectX, propX, {
839
+ set: val => {
840
+ this.propReferences[propXReferenceIndex] = val;
841
+ dot.style.left = this._mapLinear(val, minX, maxX, 0, area.clientWidth) + 'px';
842
+ vector_value.textContent = String( val ) + ', ' + objectY[propY];
843
+ },
844
+ get: () => {
845
+ return this.propReferences[propXReferenceIndex];
846
+ }
847
+ });
848
+
849
+ Object.defineProperty( objectY, propY, {
850
+ set: val => {
851
+ this.propReferences[propYReferenceIndex] = val;
852
+ dot.style.top = this._mapLinear(val, minY, maxY, area.clientHeight, 0) + 'px';
853
+ vector_value.textContent = objectX[propX] + ', ' + String( val );
854
+ },
855
+ get: () => {
856
+ return this.propReferences[propYReferenceIndex];
857
+ }
858
+ });
859
+ }
860
+
736
861
  folder(options = {}) {
737
862
  let closed = typeof options.closed == 'boolean' ? options.closed : false;
738
863
  let name = options.name || '';
@@ -1,126 +0,0 @@
1
- export default function vector2( params = {}, callback) {
2
- if (typeof params != 'object') {
3
- throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof params}.`);
4
- }
5
-
6
- let name = typeof params.name == 'string' ? params.name || ' ' : ' ';
7
-
8
- const minX = params.x.min ?? 0;
9
- const maxX = params.x.max ?? 1;
10
- const minY = params.y.min ?? 0;
11
- const maxY = params.y.max ?? 1;
12
- const stepX = params.x.step || (maxX - minX) / 100;
13
- const stepY = params.y.step || (maxY - minY) / 100;
14
- const decimalsX = this._countDecimals(stepX);
15
- const decimalsY = this._countDecimals(stepY);
16
-
17
- const objectX = params.x.obj;
18
- const propX = params.x.prop;
19
- const propXReferenceIndex = this.propReferences.push(objectX[propX]) - 1;
20
-
21
- const objectY = params.y.obj;
22
- const propY = params.y.prop;
23
- const propYReferenceIndex = this.propReferences.push(objectY[propY]) - 1;
24
-
25
- const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? name : null);
26
-
27
- callback = typeof callback == 'function' ? callback : null;
28
-
29
- this.imageContainer = null;
30
-
31
- const container = document.createElement('div');
32
- container.className = 'p-gui__vector2';
33
- container.textContent = name;
34
- if ( tooltip ) {
35
- container.setAttribute('title', tooltip);
36
- }
37
- this.wrapper.append(container);
38
-
39
- const vector_value = document.createElement('div');
40
- vector_value.className = 'p-gui__vector-value';
41
- vector_value.textContent = objectX[propX] + ', ' + objectY[propY];
42
- container.append(vector_value);
43
-
44
- const area = document.createElement('div');
45
- area.className = 'p-gui__vector2-area';
46
- container.append(area);
47
- area.addEventListener('click', evt => {
48
- const newX = parseFloat(this._mapLinear(evt.offsetX, 0, area.clientWidth, minX, maxX));
49
- const newY = parseFloat(this._mapLinear(evt.offsetY, 0, area.clientHeight, maxY, minY));
50
- objectX[propX] = newX.toFixed(decimalsX);
51
- objectY[propY] = newY.toFixed(decimalsY);
52
-
53
- if (callback) {
54
- callback(objectX[propX], objectX[propY]);
55
- }
56
-
57
- if (this.onUpdate) {
58
- this.onUpdate();
59
- } else if (this.isFolder && this.firstParent.onUpdate) {
60
- this.firstParent.onUpdate();
61
- }
62
- });
63
-
64
- let pointer_is_down = false;
65
- area.addEventListener('pointerdown', (evt) => {
66
- pointer_is_down = true;
67
- });
68
- area.addEventListener('pointerup', () => {
69
- pointer_is_down = false;
70
- });
71
- area.addEventListener('pointermove', (evt) => {
72
- if (pointer_is_down) {
73
- const newX = parseFloat(this._mapLinear(evt.offsetX, 0, area.clientWidth, minX, maxX));
74
- const newY = parseFloat(this._mapLinear(evt.offsetY, 0, area.clientHeight, maxY, minY));
75
- objectX[propX] = newX.toFixed(decimalsX);
76
- objectY[propY] = newY.toFixed(decimalsY);
77
-
78
- if (callback) {
79
- callback(objectX[propX], objectX[propY]);
80
- }
81
-
82
- if (this.onUpdate) {
83
- this.onUpdate();
84
- } else if (this.isFolder && this.firstParent.onUpdate) {
85
- this.firstParent.onUpdate();
86
- }
87
- }
88
- });
89
-
90
- const line_x = document.createElement('div');
91
- line_x.className = 'p-gui__vector2-line p-gui__vector2-line-x';
92
- area.append(line_x);
93
-
94
- const line_y = document.createElement('div');
95
- line_y.className = 'p-gui__vector2-line p-gui__vector2-line-y';
96
- area.append(line_y);
97
-
98
- const dot = document.createElement('div');
99
- dot.className = 'p-gui__vector2-dot';
100
- area.append(dot);
101
-
102
- dot.style.left = this._mapLinear(objectX[propX], minX, maxX, 0, area.clientWidth) + 'px';
103
- dot.style.top = this._mapLinear(objectY[propY], minY, maxY, area.clientHeight, 0) + 'px';
104
-
105
- Object.defineProperty( objectX, propX, {
106
- set: val => {
107
- this.propReferences[propXReferenceIndex] = val;
108
- dot.style.left = this._mapLinear(val, minX, maxX, 0, area.clientWidth) + 'px';
109
- vector_value.textContent = String( val ) + ', ' + objectY[propY];
110
- },
111
- get: () => {
112
- return this.propReferences[propXReferenceIndex];
113
- }
114
- });
115
-
116
- Object.defineProperty( objectY, propY, {
117
- set: val => {
118
- this.propReferences[propYReferenceIndex] = val;
119
- dot.style.top = this._mapLinear(val, minY, maxY, area.clientHeight, 0) + 'px';
120
- vector_value.textContent = objectX[propX] + ', ' + String( val );
121
- },
122
- get: () => {
123
- return this.propReferences[propYReferenceIndex];
124
- }
125
- });
126
- }