perfect-gui 4.11.15 → 4.12.0

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.
package/README.md CHANGED
@@ -47,7 +47,7 @@ gui.button('Click me', callback);
47
47
  ## Options
48
48
  ```javascript
49
49
  const gui = new GUI({
50
- name: 'My GUI',
50
+ label: 'My GUI',
51
51
  // Name of the panel.
52
52
  // Default is null.
53
53
 
@@ -2,7 +2,7 @@ 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}.`);
5
- let a = typeof t.name == "string" && t.name || " ";
5
+ let l = typeof t.label == "string" && t.label || " ";
6
6
  this.isObject = !1;
7
7
  let s = null;
8
8
  this.obj = t.obj, this.prop = t.prop;
@@ -14,17 +14,17 @@ class R {
14
14
  throw Error(`[GUI] slider() "prop" parameter must be an string. Received: ${typeof this.prop}.`);
15
15
  if (typeof this.obj != "object")
16
16
  throw Error(`[GUI] slider() "obj" parameter must be an object. Received: ${typeof this.obj}.`);
17
- a == " " && (a = this.prop), s = this.propReferences.push(this.obj[this.prop]) - 1, this.isObject = !0;
17
+ l == " " && (l = this.prop), s = this.propReferences.push(this.obj[this.prop]) - 1, this.isObject = !0;
18
18
  } else
19
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;
20
+ const r = typeof t.tooltip == "string" ? t.tooltip : t.tooltip === !0 ? l : null;
21
21
  this.imageContainer = null;
22
22
  const n = document.createElement("div");
23
23
  n.className = "p-gui__slider", r && n.setAttribute("title", r);
24
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
- 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] : o, n.append(this.valueInput), setTimeout(() => {
25
+ c.className = "p-gui__slider-name", c.textContent = l, 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
+ const a = document.createElement("div");
27
+ return a.className = "p-gui__slider-bar", this.ctrlDiv.append(a), 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", a.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 R {
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, o = parseFloat(this.valueInput.value);
46
+ const i = this.ctrlDiv.offsetWidth, l = this.handle.offsetWidth, s = e.clientX - this.ctrlDiv.prevPosition, o = parseFloat(this.valueInput.value);
47
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);
48
+ t ? r = e.offsetX : r = this.handle.position + s, r = Math.max(l / 2, Math.min(r, i - l / 2));
49
+ let n = this.min + (this.max - this.min) * (r - l / 2) / (i - l);
50
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());
51
+ const c = parseFloat((o + this.step).toFixed(9)), a = parseFloat((o - this.step).toFixed(9));
52
+ (n >= c || n <= a) && (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;
@@ -59,8 +59,8 @@ class R {
59
59
  _triggerCallbacks() {
60
60
  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();
61
61
  }
62
- _mapLinear(e, t, i, a, s) {
63
- return a + (e - t) * (s - a) / (i - t);
62
+ _mapLinear(e, t, i, l, s) {
63
+ return l + (e - t) * (s - l) / (i - t);
64
64
  }
65
65
  _quantize(e, t) {
66
66
  return t * Math.round(e / t);
@@ -106,6 +106,7 @@ const P = (
106
106
  gap: 10px;
107
107
  color: var(--color-text-dark);
108
108
  transition: color var(--transition);
109
+ padding: 3px;
109
110
  }
110
111
 
111
112
  .p-gui__slider:hover {
@@ -214,7 +215,7 @@ const P = (
214
215
  top: 0;
215
216
  bottom: 0;
216
217
  margin: auto;
217
- height: 21px;
218
+ height: calc(100% - 4px);
218
219
  cursor: pointer;
219
220
  border-radius: 3px;
220
221
  border: 1px solid var(--color-border-2);
@@ -286,7 +287,7 @@ const P = (
286
287
  top: 0;
287
288
  bottom: 0;
288
289
  margin: auto;
289
- height: 21px;
290
+ height: calc(100% - 4px);
290
291
  cursor: pointer;
291
292
  border-radius: 3px;
292
293
  border: 1px solid var(--color-border-2);
@@ -449,12 +450,12 @@ const P = (
449
450
  }
450
451
 
451
452
  .p-gui__folder--closed {
452
- height: 32px;
453
+ height: 25px;
453
454
  overflow: hidden;
454
455
  }
455
456
 
456
457
  .p-gui__folder-header {
457
- padding: 10px 5px;
458
+ padding: 5px 3px;
458
459
  background-color: rgba(0, 0, 0, .5);
459
460
  color: white;
460
461
  cursor: pointer;
@@ -481,7 +482,7 @@ const P = (
481
482
  }
482
483
  `
483
484
  );
484
- function M(U) {
485
+ function M(j) {
485
486
  return (
486
487
  /* css */
487
488
  `
@@ -496,7 +497,7 @@ function M(U) {
496
497
  --color-accent-hover: #dddddd;
497
498
  --transition: .1s linear;
498
499
 
499
- position: ${U};
500
+ position: ${j};
500
501
  top: 0;
501
502
  left: 0;
502
503
  transform: translate3d(0,0,0);
@@ -593,7 +594,7 @@ function M(U) {
593
594
  .p-gui__vector2,
594
595
  .p-gui__color {
595
596
  width: 100%;
596
- padding: 7px;
597
+ padding: 5px 3px;
597
598
  cursor: pointer;
598
599
  position: relative;
599
600
  box-sizing: border-box;
@@ -630,13 +631,13 @@ function M(U) {
630
631
  `
631
632
  );
632
633
  }
633
- class C {
634
+ class U {
634
635
  constructor(e = {}) {
635
636
  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) {
636
637
  this._folderConstructor(e.folderOptions);
637
638
  return;
638
639
  }
639
- 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();
640
+ typeof e.onUpdate == "function" && (this.onUpdate = e.onUpdate), this.label = e != null && typeof e.label == "string" ? e.label : "", 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();
640
641
  }
641
642
  _styleInstance() {
642
643
  let e = this._getScrollbarWidth(this.container);
@@ -684,17 +685,17 @@ class C {
684
685
  this.stylesheet.innerHTML += e;
685
686
  }
686
687
  _addWrapper() {
687
- this.wrapper = document.createElement("div"), this.wrapper.id = "p-gui-" + this.instanceId, this.wrapper.className = "p-gui", this.wrapper.setAttribute("data-lenis-prevent", ""), 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);
688
+ this.wrapper = document.createElement("div"), this.wrapper.id = "p-gui-" + this.instanceId, this.wrapper.className = "p-gui", this.wrapper.setAttribute("data-lenis-prevent", ""), this.container.append(this.wrapper), this.header = document.createElement("div"), this.header.className = "p-gui__header", this.header.textContent = this.label, this.header.style = `${this.backgroundColor ? "border-color: " + this.backgroundColor + ";" : ""}`, this.wrapper.append(this.header);
688
689
  const e = document.createElement("div");
689
690
  e.className = "p-gui__header-close", e.addEventListener("click", this.toggleClose.bind(this)), this.header.append(e);
690
691
  }
691
692
  button(e, t) {
692
693
  let i = "";
693
- typeof e != "string" ? typeof e == "object" && (e != null && e.hasOwnProperty("name")) ? i = e.name == "" ? " " : e.name : i = " " : i = e == "" ? " " : e;
694
- const a = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
694
+ typeof e != "string" ? typeof e == "object" && (e != null && e.hasOwnProperty("label")) ? i = e.label == "" ? " " : e.label : i = " " : i = e == "" ? " " : e;
695
+ const l = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
695
696
  this.imageContainer = null;
696
697
  const s = document.createElement("div");
697
- s.className = "p-gui__button", s.textContent = i, a && s.setAttribute("title", a), s.addEventListener("click", () => {
698
+ s.className = "p-gui__button", s.textContent = i, l && s.setAttribute("title", l), s.addEventListener("click", () => {
698
699
  t && t(), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
699
700
  }), 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));
700
701
  }
@@ -706,20 +707,20 @@ class C {
706
707
  i = e.path;
707
708
  else
708
709
  throw typeof e.path == null ? Error("[GUI] image() path must be provided.") : Error("[GUI] image() path must be a string.");
709
- let a = i.replace(/^.*[\\\/]/, ""), s;
710
- e.name == null ? s = a : s = typeof e.name == "string" && e.name || " ";
710
+ let l = i.replace(/^.*[\\\/]/, ""), s;
711
+ e.label == null ? s = l : s = typeof e.label == "string" && e.label || " ";
711
712
  const o = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? s : null, r = e.selected === !0, n = e.selectionBorder !== !1;
712
713
  let c = "";
713
714
  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));
714
- const l = document.createElement("div");
715
- 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");
715
+ const a = document.createElement("div");
716
+ a.className = "p-gui__image", a.style = "background-image: url(" + i + "); " + c, o && a.setAttribute("title", o), this.imageContainer.append(a), r && n && a.classList.add("p-gui__image--selected");
716
717
  const d = document.createElement("div");
717
- return d.className = "p-gui__image-text", d.textContent = s, l.append(d), l.addEventListener("click", () => {
718
- let p = l.parentElement.querySelectorAll(".p-gui__image--selected");
718
+ return d.className = "p-gui__image-text", d.textContent = s, a.append(d), a.addEventListener("click", () => {
719
+ let p = a.parentElement.querySelectorAll(".p-gui__image--selected");
719
720
  for (let h = 0; h < p.length; h++)
720
721
  p[h].classList.remove("p-gui__image--selected");
721
- 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();
722
- }), l;
722
+ n && a.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();
723
+ }), a;
723
724
  }
724
725
  slider(e = {}, t) {
725
726
  const i = new R(this, e, t);
@@ -728,7 +729,7 @@ class C {
728
729
  toggle(e = {}, t) {
729
730
  if (typeof e != "object")
730
731
  throw Error(`[GUI] toggle() first parameter must be an object. Received: ${typeof e}.`);
731
- 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;
732
+ let i = typeof e.label == "string" && e.label || " ", l = !1, s = null, o = e.obj, r = e.prop, n = typeof e.value == "boolean" ? e.value : null;
732
733
  if (n !== null)
733
734
  (r != null || o != null) && console.warn('[GUI] toggle() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
734
735
  else if (r != null && o != null) {
@@ -736,20 +737,20 @@ class C {
736
737
  throw Error(`[GUI] toggle() "prop" parameter must be an string. Received: ${typeof r}.`);
737
738
  if (typeof o != "object")
738
739
  throw Error(`[GUI] toggle() "obj" parameter must be an object. Received: ${typeof o}.`);
739
- i == " " && (i = r), s = this.propReferences.push(o[r]) - 1, a = !0;
740
+ i == " " && (i = r), s = this.propReferences.push(o[r]) - 1, l = !0;
740
741
  } else
741
742
  (r != null && o == null || r == null && o == null) && console.warn('[GUI] toggle() "obj" and "prop" parameters must be used together.');
742
743
  const c = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
743
744
  this.imageContainer = null;
744
- const l = document.createElement("div");
745
- l.textContent = i, l.className = "p-gui__switch", c && l.setAttribute("title", c), this.wrapper.append(l), l.addEventListener("click", (h) => {
745
+ const a = document.createElement("div");
746
+ a.textContent = i, a.className = "p-gui__switch", c && a.setAttribute("title", c), this.wrapper.append(a), a.addEventListener("click", (h) => {
746
747
  const u = h.target.childNodes[1];
747
748
  let f = !0;
748
- 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();
749
+ u.classList.contains("p-gui__switch-checkbox--active") && (f = !1), u.classList.toggle("p-gui__switch-checkbox--active"), l ? o[r] = f : typeof t == "function" && t(f), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
749
750
  });
750
- let d = (() => a ? o[r] ? " p-gui__switch-checkbox--active" : "" : n ? " p-gui__switch-checkbox--active" : "")();
751
+ let d = (() => l ? o[r] ? " p-gui__switch-checkbox--active" : "" : n ? " p-gui__switch-checkbox--active" : "")();
751
752
  const p = document.createElement("div");
752
- p.className = "p-gui__switch-checkbox" + d, l.append(p), a && Object.defineProperty(o, r, {
753
+ p.className = "p-gui__switch-checkbox" + d, a.append(p), l && Object.defineProperty(o, r, {
753
754
  set: (h) => {
754
755
  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);
755
756
  },
@@ -759,7 +760,7 @@ class C {
759
760
  list(e = {}, t) {
760
761
  if (typeof e != "object")
761
762
  throw Error(`[GUI] list() first parameter must be an object. Received: ${typeof e}.`);
762
- 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";
763
+ let i = typeof e.label == "string" ? e.label : " ", l = !1, s = null, o = e.obj, r = e.prop, n = Array.isArray(e.values) ? e.values : null, c, a = typeof n[0] != "string";
763
764
  const d = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
764
765
  if (t = typeof t == "function" ? t : null, e.value !== void 0 || e.value === void 0 && o === void 0 && r === void 0)
765
766
  (r != null || o != null) && console.warn('[GUI] list() "obj" and "prop" parameters are ignored when a "value" parameter is used.'), c = (() => {
@@ -779,10 +780,10 @@ class C {
779
780
  if (!n)
780
781
  return null;
781
782
  if (typeof o[r] == "string")
782
- return l ? n.find((u) => u.value === o[r]).value : n.indexOf(o[r]);
783
+ return a ? n.find((u) => u.value === o[r]).value : n.indexOf(o[r]);
783
784
  if (typeof o[r] == "number")
784
- return l ? n.find((u) => u.value === o[r]).value : o[r];
785
- })(), s = this.propReferences.push(o[r]) - 1, a = !0;
785
+ return a ? n.find((u) => u.value === o[r]).value : o[r];
786
+ })(), s = this.propReferences.push(o[r]) - 1, l = !0;
786
787
  } else
787
788
  (r != null && o == null || r == null && o == null) && console.warn('[GUI] list() "obj" and "prop" parameters must be used together.');
788
789
  this.imageContainer = null;
@@ -790,17 +791,17 @@ class C {
790
791
  p.className = "p-gui__list", p.textContent = i, d && p.setAttribute("title", d), this.wrapper.append(p);
791
792
  let h = document.createElement("select");
792
793
  p.append(h), h.className = "p-gui__list-dropdown", h.addEventListener("change", (u) => {
793
- a ? o[r] = u.target.value : t && t(u.target.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
794
+ l ? o[r] = u.target.value : t && t(u.target.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
794
795
  }), n && n.forEach((u, f) => {
795
- const g = l ? u.name : u, m = l ? u.value : u;
796
- let x = document.createElement("option");
797
- x.setAttribute("value", m), x.textContent = g, h.append(x), (!l && c == f || l && c == m) && x.setAttribute("selected", "");
798
- }), a && Object.defineProperty(o, r, {
796
+ const g = a ? u.label : u, x = a ? u.value : u;
797
+ let v = document.createElement("option");
798
+ v.setAttribute("value", x), v.textContent = g, h.append(v), (!a && c == f || a && c == x) && v.setAttribute("selected", "");
799
+ }), l && Object.defineProperty(o, r, {
799
800
  set: (u) => {
800
- let f, g, m;
801
- 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;
802
- const x = h.querySelector("[selected]");
803
- x && x.removeAttribute("selected"), h.querySelectorAll("option")[f].setAttribute("selected", ""), typeof t == "function" && t(l ? m : g, f);
801
+ let f, g, x;
802
+ a ? (x = n.find((m) => m.value == u), g = (x == null ? void 0 : x.value) || n[0].value, f = n.indexOf(x)) : (typeof u == "string" && (f = n.indexOf(u), g = u), typeof u == "number" && (f = u, g = n[u])), this.propReferences[s] = a ? g : u;
803
+ const v = h.querySelector("[selected]");
804
+ v && v.removeAttribute("selected"), h.querySelectorAll("option")[f].setAttribute("selected", ""), typeof t == "function" && t(a ? x : g, f);
804
805
  },
805
806
  get: () => this.propReferences[s]
806
807
  });
@@ -808,7 +809,7 @@ class C {
808
809
  color(e = {}, t) {
809
810
  if (typeof e != "object")
810
811
  throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof e}.`);
811
- let i = typeof e.name == "string" && e.name || " ", a = !1, s = null, o = e.obj, r = e.prop, n;
812
+ let i = typeof e.label == "string" && e.label || " ", l = !1, s = null, o = e.obj, r = e.prop, n;
812
813
  const c = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
813
814
  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)
814
815
  (r != null || o != null) && console.warn('[GUI] color() "obj" and "prop" parameters are ignored when a "value" parameter is used.');
@@ -817,16 +818,16 @@ class C {
817
818
  throw Error(`[GUI] color() "prop" parameter must be an string. Received: ${typeof r}.`);
818
819
  if (typeof o != "object")
819
820
  throw Error(`[GUI] color() "obj" parameter must be an object. Received: ${typeof o}.`);
820
- i == " " && (i = r), s = this.propReferences.push(o[r]) - 1, a = !0;
821
+ i == " " && (i = r), s = this.propReferences.push(o[r]) - 1, l = !0;
821
822
  } else
822
823
  (r != null && o == null || r == null && o == null) && console.warn('[GUI] color() "obj" and "prop" parameters must be used together.');
823
824
  this.imageContainer = null;
824
- const l = document.createElement("div");
825
- l.className = "p-gui__color", l.textContent = i, c && l.setAttribute("title", c), this.wrapper.append(l);
825
+ const a = document.createElement("div");
826
+ a.className = "p-gui__color", a.textContent = i, c && a.setAttribute("title", c), this.wrapper.append(a);
826
827
  const d = document.createElement("input");
827
- d.className = "p-gui__color-picker", d.setAttribute("type", "color"), d.value = n, l.append(d), typeof t == "function" && d.addEventListener("input", () => {
828
- a ? o[r] = d.value : typeof t == "function" && t(d.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
829
- }), a && Object.defineProperty(o, r, {
828
+ d.className = "p-gui__color-picker", d.setAttribute("type", "color"), d.value = n, a.append(d), typeof t == "function" && d.addEventListener("input", () => {
829
+ l ? o[r] = d.value : typeof t == "function" && t(d.value), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
830
+ }), l && Object.defineProperty(o, r, {
830
831
  set: (p) => {
831
832
  this.propReferences[s] = p, d.value = p, typeof t == "function" && t(p);
832
833
  },
@@ -836,17 +837,17 @@ class C {
836
837
  vector2(e = {}, t) {
837
838
  if (typeof e != "object")
838
839
  throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof e}.`);
839
- let i = typeof e.name == "string" && e.name || " ";
840
- 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;
840
+ let i = typeof e.label == "string" && e.label || " ";
841
+ const l = e.x.min ?? 0, s = e.x.max ?? 1, o = e.y.min ?? 0, r = e.y.max ?? 1, n = e.x.step || (s - l) / 100, c = e.y.step || (r - o) / 100, a = 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, x = this.propReferences.push(f[g]) - 1, v = typeof e.tooltip == "string" ? e.tooltip : e.tooltip === !0 ? i : null;
841
842
  t = typeof t == "function" ? t : null, this.imageContainer = null;
842
- const v = document.createElement("div");
843
- v.className = "p-gui__vector2", v.textContent = i, x && v.setAttribute("title", x), this.wrapper.append(v);
843
+ const m = document.createElement("div");
844
+ m.className = "p-gui__vector2", m.textContent = i, v && m.setAttribute("title", v), this.wrapper.append(m);
844
845
  const y = document.createElement("div");
845
- y.className = "p-gui__vector-value", y.textContent = p[h] + ", " + f[g], v.append(y);
846
+ y.className = "p-gui__vector-value", y.textContent = p[h] + ", " + f[g], m.append(y);
846
847
  const b = document.createElement("div");
847
- b.className = "p-gui__vector2-area", v.append(b), b.addEventListener("click", (_) => {
848
- const k = parseFloat(this._mapLinear(_.offsetX, 0, b.clientWidth, a, s)), E = parseFloat(this._mapLinear(_.offsetY, 0, b.clientHeight, r, o));
849
- 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();
848
+ b.className = "p-gui__vector2-area", m.append(b), b.addEventListener("click", (_) => {
849
+ const k = parseFloat(this._mapLinear(_.offsetX, 0, b.clientWidth, l, s)), E = parseFloat(this._mapLinear(_.offsetY, 0, b.clientHeight, r, o));
850
+ p[h] = k.toFixed(a), f[g] = E.toFixed(d), t && t(p[h], p[g]), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
850
851
  });
851
852
  let A = !1;
852
853
  b.addEventListener("pointerdown", (_) => {
@@ -855,33 +856,33 @@ class C {
855
856
  A = !1;
856
857
  }), b.addEventListener("pointermove", (_) => {
857
858
  if (A) {
858
- const k = parseFloat(this._mapLinear(_.offsetX, 0, b.clientWidth, a, s)), E = parseFloat(this._mapLinear(_.offsetY, 0, b.clientHeight, r, o));
859
- 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();
859
+ const k = parseFloat(this._mapLinear(_.offsetX, 0, b.clientWidth, l, s)), E = parseFloat(this._mapLinear(_.offsetY, 0, b.clientHeight, r, o));
860
+ p[h] = k.toFixed(a), f[g] = E.toFixed(d), t && t(p[h], p[g]), this.onUpdate ? this.onUpdate() : this.isFolder && this.firstParent.onUpdate && this.firstParent.onUpdate();
860
861
  }
861
862
  });
862
- const j = document.createElement("div");
863
- j.className = "p-gui__vector2-line p-gui__vector2-line-x", b.append(j);
864
863
  const I = document.createElement("div");
865
- I.className = "p-gui__vector2-line p-gui__vector2-line-y", b.append(I);
864
+ I.className = "p-gui__vector2-line p-gui__vector2-line-x", b.append(I);
865
+ const C = document.createElement("div");
866
+ C.className = "p-gui__vector2-line p-gui__vector2-line-y", b.append(C);
866
867
  const w = document.createElement("div");
867
- 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, {
868
+ w.className = "p-gui__vector2-dot", b.append(w), w.style.left = this._mapLinear(p[h], l, s, 0, b.clientWidth) + "px", w.style.top = this._mapLinear(f[g], o, r, b.clientHeight, 0) + "px", Object.defineProperty(p, h, {
868
869
  set: (_) => {
869
- this.propReferences[u] = _, w.style.left = this._mapLinear(_, a, s, 0, b.clientWidth) + "px", y.textContent = String(_) + ", " + f[g];
870
+ this.propReferences[u] = _, w.style.left = this._mapLinear(_, l, s, 0, b.clientWidth) + "px", y.textContent = String(_) + ", " + f[g];
870
871
  },
871
872
  get: () => this.propReferences[u]
872
873
  }), Object.defineProperty(f, g, {
873
874
  set: (_) => {
874
- this.propReferences[m] = _, w.style.top = this._mapLinear(_, o, r, b.clientHeight, 0) + "px", y.textContent = p[h] + ", " + String(_);
875
+ this.propReferences[x] = _, w.style.top = this._mapLinear(_, o, r, b.clientHeight, 0) + "px", y.textContent = p[h] + ", " + String(_);
875
876
  },
876
- get: () => this.propReferences[m]
877
+ get: () => this.propReferences[x]
877
878
  });
878
879
  }
879
880
  folder(e = {}) {
880
- let t = typeof e.closed == "boolean" ? e.closed : !1, i = e.name || "", a = e.color || null, s = e.maxHeight || null;
881
+ let t = typeof e.closed == "boolean" ? e.closed : !1, i = e.label || "", l = e.color || null, s = e.maxHeight || null;
881
882
  this.imageContainer = null;
882
883
  let o = "p-gui__folder";
883
884
  this.folders.length == 0 && (o += " p-gui__folder--first"), t && (o += " p-gui__folder--closed");
884
- let r = a ? `background-color: ${a};` : "";
885
+ let r = l ? `background-color: ${l};` : "";
885
886
  r += s ? `max-height: ${s}px;` : "";
886
887
  const n = document.createElement("div");
887
888
  n.className = o, n.style = r, this.wrapper.append(n);
@@ -889,23 +890,23 @@ class C {
889
890
  c.innerHTML = `<span class="p-gui__folder-arrow"></span>${i}`, c.className = "p-gui__folder-header", n.append(c), c.addEventListener("click", () => {
890
891
  n.classList.toggle("p-gui__folder--closed");
891
892
  });
892
- let l = new C({ isFolder: !0, folderOptions: {
893
+ let a = new U({ isFolder: !0, folderOptions: {
893
894
  wrapper: n,
894
895
  parent: this,
895
896
  firstParent: this.firstParent
896
897
  } });
897
- return this.folders.push(l), l;
898
+ return this.folders.push(a), a;
898
899
  }
899
900
  _makeDraggable() {
900
901
  var e = this;
901
- this.header.addEventListener("pointerdown", t), this.header.addEventListener("pointerup", a);
902
+ this.header.addEventListener("pointerdown", t), this.header.addEventListener("pointerup", l);
902
903
  function t(s) {
903
904
  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);
904
905
  }
905
906
  function i(s) {
906
907
  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)";
907
908
  }
908
- function a(s) {
909
+ function l(s) {
909
910
  document.removeEventListener("pointermove", i);
910
911
  }
911
912
  }
@@ -915,14 +916,18 @@ class C {
915
916
  kill() {
916
917
  this.wrapper.remove();
917
918
  }
918
- _mapLinear(e, t, i, a, s) {
919
- return a + (e - t) * (s - a) / (i - t);
919
+ _mapLinear(e, t, i, l, s) {
920
+ return l + (e - t) * (s - l) / (i - t);
920
921
  }
921
922
  _countDecimals(e) {
922
923
  const t = e.toString(), i = t.indexOf(".");
923
924
  return i === -1 ? 0 : t.length - i - 1;
924
925
  }
926
+ static registerPlugin(e) {
927
+ for (let t in e)
928
+ U.prototype[t] = e[t];
929
+ }
925
930
  }
926
931
  export {
927
- C as default
932
+ U as default
928
933
  };
@@ -1,4 +1,4 @@
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=`
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 l=typeof t.label=="string"&&t.label||" ";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}.`);l==" "&&(l=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?l: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=l,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 a=document.createElement("div");return a.className="p-gui__slider-bar",this.ctrlDiv.append(a),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",a.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,l=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(l/2,Math.min(r,i-l/2));let n=this.min+(this.max-this.min)*(r-l/2)/(i-l);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)),a=parseFloat((o-this.step).toFixed(9));(n>=c||n<=a)&&(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,l,s){return l+(e-t)*(s-l)/(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;
@@ -27,6 +27,7 @@
27
27
  gap: 10px;
28
28
  color: var(--color-text-dark);
29
29
  transition: color var(--transition);
30
+ padding: 3px;
30
31
  }
31
32
 
32
33
  .p-gui__slider:hover {
@@ -132,7 +133,7 @@
132
133
  top: 0;
133
134
  bottom: 0;
134
135
  margin: auto;
135
- height: 21px;
136
+ height: calc(100% - 4px);
136
137
  cursor: pointer;
137
138
  border-radius: 3px;
138
139
  border: 1px solid var(--color-border-2);
@@ -198,7 +199,7 @@
198
199
  top: 0;
199
200
  bottom: 0;
200
201
  margin: auto;
201
- height: 21px;
202
+ height: calc(100% - 4px);
202
203
  cursor: pointer;
203
204
  border-radius: 3px;
204
205
  border: 1px solid var(--color-border-2);
@@ -352,12 +353,12 @@
352
353
  }
353
354
 
354
355
  .p-gui__folder--closed {
355
- height: 32px;
356
+ height: 25px;
356
357
  overflow: hidden;
357
358
  }
358
359
 
359
360
  .p-gui__folder-header {
360
- padding: 10px 5px;
361
+ padding: 5px 3px;
361
362
  background-color: rgba(0, 0, 0, .5);
362
363
  color: white;
363
364
  cursor: pointer;
@@ -491,7 +492,7 @@
491
492
  .p-gui__vector2,
492
493
  .p-gui__color {
493
494
  width: 100%;
494
- padding: 7px;
495
+ padding: 5px 3px;
495
496
  cursor: pointer;
496
497
  position: relative;
497
498
  box-sizing: border-box;
@@ -525,11 +526,11 @@
525
526
  ${L}
526
527
 
527
528
  ${N}
528
- `}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} {
529
+ `}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.label=e!=null&&typeof e.label=="string"?e.label:"",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} {
529
530
  width: ${this.wrapperWidth}px;
530
531
  max-height: ${this.maxHeight}px;
531
532
  transform: translate3d(${this.xOffset}px,${this.yOffset}px,0);
532
533
  ${this.screenCorner.y=="top"?"":"top: auto; bottom: 0;"}
533
534
  ${this.backgroundColor?"background: "+this.backgroundColor+";":""}
534
535
  opacity: ${this.opacity};
535
- }`)}_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.wrapper.setAttribute("data-lenis-prevent",""),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});
536
+ }`)}_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.wrapper.setAttribute("data-lenis-prevent",""),this.container.append(this.wrapper),this.header=document.createElement("div"),this.header.className="p-gui__header",this.header.textContent=this.label,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("label"))?i=e.label==""?" ":e.label:i=" ":i=e==""?" ":e;const l=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,l&&s.setAttribute("title",l),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 l=i.replace(/^.*[\\\/]/,""),s;e.label==null?s=l:s=typeof e.label=="string"&&e.label||" ";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 a=document.createElement("div");a.className="p-gui__image",a.style="background-image: url("+i+"); "+c,o&&a.setAttribute("title",o),this.imageContainer.append(a),r&&n&&a.classList.add("p-gui__image--selected");const d=document.createElement("div");return d.className="p-gui__image-text",d.textContent=s,a.append(d),a.addEventListener("click",()=>{let p=a.parentElement.querySelectorAll(".p-gui__image--selected");for(let h=0;h<p.length;h++)p[h].classList.remove("p-gui__image--selected");n&&a.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()}),a}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.label=="string"&&e.label||" ",l=!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,l=!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 a=document.createElement("div");a.textContent=i,a.className="p-gui__switch",c&&a.setAttribute("title",c),this.wrapper.append(a),a.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"),l?o[r]=f:typeof t=="function"&&t(f),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()});let d=(()=>l?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,a.append(p),l&&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.label=="string"?e.label:" ",l=!1,s=null,o=e.obj,r=e.prop,n=Array.isArray(e.values)?e.values:null,c,a=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 a?n.find(u=>u.value===o[r]).value:n.indexOf(o[r]);if(typeof o[r]=="number")return a?n.find(u=>u.value===o[r]).value:o[r]})(),s=this.propReferences.push(o[r])-1,l=!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=>{l?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=a?u.label:u,x=a?u.value:u;let v=document.createElement("option");v.setAttribute("value",x),v.textContent=g,h.append(v),(!a&&c==f||a&&c==x)&&v.setAttribute("selected","")}),l&&Object.defineProperty(o,r,{set:u=>{let f,g,x;a?(x=n.find(m=>m.value==u),g=(x==null?void 0:x.value)||n[0].value,f=n.indexOf(x)):(typeof u=="string"&&(f=n.indexOf(u),g=u),typeof u=="number"&&(f=u,g=n[u])),this.propReferences[s]=a?g:u;const v=h.querySelector("[selected]");v&&v.removeAttribute("selected"),h.querySelectorAll("option")[f].setAttribute("selected",""),typeof t=="function"&&t(a?x: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.label=="string"&&e.label||" ",l=!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,l=!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 a=document.createElement("div");a.className="p-gui__color",a.textContent=i,c&&a.setAttribute("title",c),this.wrapper.append(a);const d=document.createElement("input");d.className="p-gui__color-picker",d.setAttribute("type","color"),d.value=n,a.append(d),typeof t=="function"&&d.addEventListener("input",()=>{l?o[r]=d.value:typeof t=="function"&&t(d.value),this.onUpdate?this.onUpdate():this.isFolder&&this.firstParent.onUpdate&&this.firstParent.onUpdate()}),l&&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.label=="string"&&e.label||" ";const l=e.x.min??0,s=e.x.max??1,o=e.y.min??0,r=e.y.max??1,n=e.x.step||(s-l)/100,c=e.y.step||(r-o)/100,a=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,x=this.propReferences.push(f[g])-1,v=typeof e.tooltip=="string"?e.tooltip:e.tooltip===!0?i:null;t=typeof t=="function"?t:null,this.imageContainer=null;const m=document.createElement("div");m.className="p-gui__vector2",m.textContent=i,v&&m.setAttribute("title",v),this.wrapper.append(m);const k=document.createElement("div");k.className="p-gui__vector-value",k.textContent=p[h]+", "+f[g],m.append(k);const b=document.createElement("div");b.className="p-gui__vector2-area",m.append(b),b.addEventListener("click",_=>{const j=parseFloat(this._mapLinear(_.offsetX,0,b.clientWidth,l,s)),I=parseFloat(this._mapLinear(_.offsetY,0,b.clientHeight,r,o));p[h]=j.toFixed(a),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,l,s)),I=parseFloat(this._mapLinear(_.offsetY,0,b.clientHeight,r,o));p[h]=j.toFixed(a),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],l,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(_,l,s,0,b.clientWidth)+"px",k.textContent=String(_)+", "+f[g]},get:()=>this.propReferences[u]}),Object.defineProperty(f,g,{set:_=>{this.propReferences[x]=_,w.style.top=this._mapLinear(_,o,r,b.clientHeight,0)+"px",k.textContent=p[h]+", "+String(_)},get:()=>this.propReferences[x]})}folder(e={}){let t=typeof e.closed=="boolean"?e.closed:!1,i=e.label||"",l=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=l?`background-color: ${l};`:"";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 a=new E({isFolder:!0,folderOptions:{wrapper:n,parent:this,firstParent:this.firstParent}});return this.folders.push(a),a}_makeDraggable(){var e=this;this.header.addEventListener("pointerdown",t),this.header.addEventListener("pointerup",l);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 l(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,l,s){return l+(e-t)*(s-l)/(i-t)}_countDecimals(e){const t=e.toString(),i=t.indexOf(".");return i===-1?0:t.length-i-1}static registerPlugin(e){for(let t in e)E.prototype[t]=e[t]}}return E});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "perfect-gui",
3
- "version": "4.11.15",
3
+ "version": "4.12.0",
4
4
  "description": "GUI for JavaScript",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -22,4 +22,4 @@
22
22
  "devDependencies": {
23
23
  "vite": "^4.5.0"
24
24
  }
25
- }
25
+ }
@@ -7,7 +7,7 @@ export default class Slider {
7
7
  throw Error(`[GUI] slider() first parameter must be an object. Received: ${typeof params}.`);
8
8
  }
9
9
 
10
- let name = typeof params.name == 'string' ? params.name || ' ' : ' ';
10
+ let label = typeof params.label == 'string' ? params.label || ' ' : ' ';
11
11
  this.isObject = false;
12
12
  let propReferenceIndex = null;
13
13
  this.obj = params.obj;
@@ -34,8 +34,8 @@ export default class Slider {
34
34
  throw Error(`[GUI] slider() "obj" parameter must be an object. Received: ${typeof this.obj}.`);
35
35
  }
36
36
 
37
- if (name == ' ') {
38
- name = this.prop;
37
+ if (label == ' ') {
38
+ label = this.prop;
39
39
  }
40
40
 
41
41
  propReferenceIndex = this.propReferences.push(this.obj[this.prop]) - 1;
@@ -48,7 +48,7 @@ export default class Slider {
48
48
 
49
49
  value = (this.max - this.min) / 2;
50
50
  }
51
- const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? name : null);
51
+ const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
52
52
 
53
53
  this.imageContainer = null;
54
54
 
@@ -61,7 +61,7 @@ export default class Slider {
61
61
 
62
62
  const slider_name = document.createElement('div');
63
63
  slider_name.className = 'p-gui__slider-name';
64
- slider_name.textContent = name;
64
+ slider_name.textContent = label;
65
65
  container.append(slider_name);
66
66
 
67
67
  this.ctrlDiv = document.createElement('div');
package/src/index.js CHANGED
@@ -25,8 +25,7 @@ export default class GUI {
25
25
  this.onUpdate = options.onUpdate;
26
26
  }
27
27
 
28
- this.name = (options != undefined && typeof options.name == "string") ? options.name : '';
29
-
28
+ this.label = (options != undefined && typeof options.label == "string") ? options.label : '';
30
29
  this.backgroundColor = options.color || null;
31
30
  this.opacity = options.opacity || 1;
32
31
 
@@ -197,7 +196,7 @@ export default class GUI {
197
196
 
198
197
  this.header = document.createElement('div');
199
198
  this.header.className = 'p-gui__header';
200
- this.header.textContent = this.name;
199
+ this.header.textContent = this.label;
201
200
  this.header.style = `${ this.backgroundColor ? 'border-color: ' + this.backgroundColor + ';' : ''}`;
202
201
  this.wrapper.append(this.header);
203
202
 
@@ -208,24 +207,24 @@ export default class GUI {
208
207
  }
209
208
 
210
209
  button(options, callback) {
211
- let name = '';
210
+ let label = '';
212
211
  if (typeof options != 'string') {
213
- if (typeof options == 'object' && options?.hasOwnProperty('name')) {
214
- name = options.name == '' ? ' ' : options.name;
212
+ if (typeof options == 'object' && options?.hasOwnProperty('label')) {
213
+ label = options.label == '' ? ' ' : options.label;
215
214
  } else {
216
- name = ' ';
215
+ label = ' ';
217
216
  }
218
217
  } else {
219
- name = options == '' ? ' ' : options;
218
+ label = options == '' ? ' ' : options;
220
219
  }
221
220
 
222
- const tooltip = (typeof options.tooltip === 'string') ? options.tooltip : (options.tooltip === true ? name : null);
221
+ const tooltip = (typeof options.tooltip === 'string') ? options.tooltip : (options.tooltip === true ? label : null);
223
222
 
224
223
  this.imageContainer = null;
225
224
 
226
225
  const el = document.createElement('div');
227
226
  el.className = 'p-gui__button';
228
- el.textContent = name;
227
+ el.textContent = label;
229
228
  if ( tooltip ) {
230
229
  el.setAttribute('title', tooltip);
231
230
  }
@@ -264,14 +263,14 @@ export default class GUI {
264
263
  }
265
264
  }
266
265
  let filename = path.replace(/^.*[\\\/]/, '');
267
- let name;
268
- if (params.name == undefined) {
269
- name = filename;
266
+ let label;
267
+ if (params.label == undefined) {
268
+ label = filename;
270
269
  } else {
271
- name = typeof params.name == 'string' ? params.name || ' ' : ' ';
270
+ label = typeof params.label == 'string' ? params.label || ' ' : ' ';
272
271
  }
273
272
 
274
- const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? name : null);
273
+ const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
275
274
 
276
275
  const selected = params.selected === true;
277
276
  const selectionBorder = params.selectionBorder !== false;
@@ -314,7 +313,7 @@ export default class GUI {
314
313
  // Text inside image
315
314
  const text = document.createElement('div');
316
315
  text.className = 'p-gui__image-text';
317
- text.textContent = name;
316
+ text.textContent = label;
318
317
  image.append(text);
319
318
 
320
319
  image.addEventListener('click', () => {
@@ -326,7 +325,7 @@ export default class GUI {
326
325
  image.classList.add('p-gui__image--selected');
327
326
  }
328
327
  if (typeof callback == 'function') {
329
- callback({ path, text: name });
328
+ callback({ path, text: label });
330
329
  }
331
330
  if (this.onUpdate) {
332
331
  this.onUpdate();
@@ -348,7 +347,7 @@ export default class GUI {
348
347
  throw Error(`[GUI] toggle() first parameter must be an object. Received: ${typeof params}.`);
349
348
  }
350
349
 
351
- let name = typeof params.name == 'string' ? params.name || ' ' : ' ';
350
+ let label = typeof params.label == 'string' ? params.label || ' ' : ' ';
352
351
  let isObject = false;
353
352
  let propReferenceIndex = null;
354
353
  let obj = params.obj;
@@ -371,8 +370,8 @@ export default class GUI {
371
370
  throw Error(`[GUI] toggle() "obj" parameter must be an object. Received: ${typeof obj}.`);
372
371
  }
373
372
 
374
- if (name == ' ') {
375
- name = prop;
373
+ if (label == ' ') {
374
+ label = prop;
376
375
  }
377
376
 
378
377
  propReferenceIndex = this.propReferences.push(obj[prop]) - 1;
@@ -384,12 +383,12 @@ export default class GUI {
384
383
  }
385
384
  }
386
385
 
387
- const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? name : null);
386
+ const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
388
387
 
389
388
  this.imageContainer = null;
390
389
 
391
390
  const container = document.createElement('div');
392
- container.textContent = name;
391
+ container.textContent = label;
393
392
  container.className = 'p-gui__switch';
394
393
  if ( tooltip ) {
395
394
  container.setAttribute('title', tooltip);
@@ -463,7 +462,7 @@ export default class GUI {
463
462
  throw Error(`[GUI] list() first parameter must be an object. Received: ${typeof params}.`);
464
463
  }
465
464
 
466
- let name = typeof params.name == 'string' ? params.name : ' ';
465
+ let label = typeof params.label == 'string' ? params.label : ' ';
467
466
  let isObject = false;
468
467
  let propReferenceIndex = null;
469
468
  let obj = params.obj;
@@ -471,7 +470,7 @@ export default class GUI {
471
470
  let values = Array.isArray(params.values) ? params.values : null;
472
471
  let value;
473
472
  let objectValues = typeof values[0] == 'string' ? false : true;
474
- const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? name : null);
473
+ const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
475
474
 
476
475
  callback = typeof callback == 'function' ? callback : null;
477
476
 
@@ -540,7 +539,7 @@ export default class GUI {
540
539
 
541
540
  let container = document.createElement('div');
542
541
  container.className = 'p-gui__list';
543
- container.textContent = name;
542
+ container.textContent = label;
544
543
  if (tooltip) {
545
544
  container.setAttribute('title', tooltip);
546
545
  }
@@ -569,7 +568,7 @@ export default class GUI {
569
568
  {
570
569
  values.forEach((item, index) =>
571
570
  {
572
- const optionName = objectValues ? item.name : item;
571
+ const optionName = objectValues ? item.label : item;
573
572
  const optionValue = objectValues ? item.value : item;
574
573
  let option = document.createElement('option');
575
574
  option.setAttribute('value', optionValue);
@@ -631,14 +630,14 @@ export default class GUI {
631
630
  throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof params}.`);
632
631
  }
633
632
 
634
- let name = typeof params.name == 'string' ? params.name || ' ' : ' ';
633
+ let label = typeof params.label == 'string' ? params.label || ' ' : ' ';
635
634
 
636
635
  let isObject = false;
637
636
  let propReferenceIndex = null;
638
637
  let obj = params.obj;
639
638
  let prop = params.prop;
640
639
  let value;
641
- const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? name : null);
640
+ const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
642
641
 
643
642
  if (typeof params.value == 'string') {
644
643
  if (params.value.length != 7 || params.value[0] != '#') {
@@ -666,8 +665,8 @@ export default class GUI {
666
665
  throw Error(`[GUI] color() "obj" parameter must be an object. Received: ${typeof obj}.`);
667
666
  }
668
667
 
669
- if (name == ' ') {
670
- name = prop;
668
+ if (label == ' ') {
669
+ label = prop;
671
670
  }
672
671
 
673
672
  propReferenceIndex = this.propReferences.push(obj[prop]) - 1;
@@ -683,7 +682,7 @@ export default class GUI {
683
682
 
684
683
  const container = document.createElement('div');
685
684
  container.className = 'p-gui__color';
686
- container.textContent = name;
685
+ container.textContent = label;
687
686
  if ( tooltip ) {
688
687
  container.setAttribute('title', tooltip);
689
688
  }
@@ -736,7 +735,7 @@ export default class GUI {
736
735
  throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof params}.`);
737
736
  }
738
737
 
739
- let name = typeof params.name == 'string' ? params.name || ' ' : ' ';
738
+ let label = typeof params.label == 'string' ? params.label || ' ' : ' ';
740
739
 
741
740
  const minX = params.x.min ?? 0;
742
741
  const maxX = params.x.max ?? 1;
@@ -755,7 +754,7 @@ export default class GUI {
755
754
  const propY = params.y.prop;
756
755
  const propYReferenceIndex = this.propReferences.push(objectY[propY]) - 1;
757
756
 
758
- const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? name : null);
757
+ const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
759
758
 
760
759
  callback = typeof callback == 'function' ? callback : null;
761
760
 
@@ -763,7 +762,7 @@ export default class GUI {
763
762
 
764
763
  const container = document.createElement('div');
765
764
  container.className = 'p-gui__vector2';
766
- container.textContent = name;
765
+ container.textContent = label;
767
766
  if ( tooltip ) {
768
767
  container.setAttribute('title', tooltip);
769
768
  }
@@ -860,7 +859,7 @@ export default class GUI {
860
859
 
861
860
  folder(options = {}) {
862
861
  let closed = typeof options.closed == 'boolean' ? options.closed : false;
863
- let name = options.name || '';
862
+ let label = options.label || '';
864
863
  let color = options.color || null;
865
864
  let maxHeight = options.maxHeight || null;
866
865
 
@@ -885,7 +884,7 @@ export default class GUI {
885
884
  this.wrapper.append(container);
886
885
 
887
886
  const folderHeader = document.createElement('div');
888
- folderHeader.innerHTML = `<span class="p-gui__folder-arrow"></span>${name}`;
887
+ folderHeader.innerHTML = `<span class="p-gui__folder-arrow"></span>${label}`;
889
888
  folderHeader.className = 'p-gui__folder-header';
890
889
  container.append(folderHeader);
891
890
  folderHeader.addEventListener('click', () => {
@@ -974,4 +973,10 @@ export default class GUI {
974
973
 
975
974
  return decimalPlaces;
976
975
  }
976
+
977
+ static registerPlugin(plugin) {
978
+ for (let i in plugin) {
979
+ GUI.prototype[i] = plugin[i];
980
+ }
981
+ }
977
982
  }
@@ -0,0 +1,57 @@
1
+ /*
2
+ GUI.prototype.threeMaterial = threeMaterial;
3
+ gui.threeMaterial({name: 'material', obj: material})
4
+ */
5
+ export function threeMaterial(params = {}) {
6
+ const material = params.obj;
7
+ const closed = params.closed ?? false;
8
+
9
+ if (material.isMeshStandardMaterial) {
10
+ const folder = this.folder({ name: params.name, closed });
11
+
12
+ folder.slider({ obj: material, prop: 'roughness' });
13
+ folder.slider({ obj: material, prop: 'metalness' });
14
+ folder.threeColor({ name: 'color', obj: material.color });
15
+ folder.slider({ obj: material, prop: 'envMapIntensity' });
16
+ folder.toggle({ obj: material, prop: 'transparent' }, () => material.needsUpdate = true);
17
+ folder.slider({ obj: material, prop: 'opacity' });
18
+
19
+ if (material.isMeshPhysicalMaterial) {
20
+ folder.slider({ obj: material, prop: 'transmission' });
21
+ folder.slider({ obj: material, prop: 'thickness' });
22
+ folder.slider({ obj: material, prop: 'ior' });
23
+ }
24
+
25
+ return folder;
26
+ }
27
+ else if (material.isMeshBasicMaterial) {
28
+ const folder = this.folder({ name: params.name, closed });
29
+
30
+ folder.threeColor({ name: 'color', obj: material.color });
31
+ folder.toggle({ obj: material, prop: 'transparent' }, () => material.needsUpdate = true);
32
+ folder.slider({ obj: material, prop: 'opacity' });
33
+
34
+ return folder;
35
+ }
36
+ else {
37
+ console.error('[GUI threeMaterial]', 'threeMaterial() doesn\'t support this material:', material);
38
+ }
39
+ }
40
+
41
+ /*
42
+ GUI.prototype.threeColor = threeColor;
43
+ gui.threeColor({name: 'color', obj: color})
44
+ */
45
+ export function threeColor(params = {}) {
46
+ const label = params.name ?? 'Color';
47
+ const color = params.obj;
48
+
49
+ if (!color) {
50
+ console.error('[GUI threeColor]', 'color object not provided');
51
+ return;
52
+ }
53
+
54
+ return this.color({ name: label, value: '#'+color.getHexString() }, val => {
55
+ color.set(val)
56
+ });
57
+ }
@@ -15,7 +15,7 @@ export default /* css */ `
15
15
  top: 0;
16
16
  bottom: 0;
17
17
  margin: auto;
18
- height: 21px;
18
+ height: calc(100% - 4px);
19
19
  cursor: pointer;
20
20
  border-radius: 3px;
21
21
  border: 1px solid var(--color-border-2);
@@ -19,12 +19,12 @@ export default /* css */ `
19
19
  }
20
20
 
21
21
  .p-gui__folder--closed {
22
- height: 32px;
22
+ height: 25px;
23
23
  overflow: hidden;
24
24
  }
25
25
 
26
26
  .p-gui__folder-header {
27
- padding: 10px 5px;
27
+ padding: 5px 3px;
28
28
  background-color: rgba(0, 0, 0, .5);
29
29
  color: white;
30
30
  cursor: pointer;
@@ -22,7 +22,7 @@ export default /* css */ `
22
22
  top: 0;
23
23
  bottom: 0;
24
24
  margin: auto;
25
- height: 21px;
25
+ height: calc(100% - 4px);
26
26
  cursor: pointer;
27
27
  border-radius: 3px;
28
28
  border: 1px solid var(--color-border-2);
@@ -8,6 +8,7 @@ export default /* css */ `
8
8
  gap: 10px;
9
9
  color: var(--color-text-dark);
10
10
  transition: color var(--transition);
11
+ padding: 3px;
11
12
  }
12
13
 
13
14
  .p-gui__slider:hover {
@@ -122,7 +122,7 @@ export default function( position_type ) {
122
122
  .p-gui__vector2,
123
123
  .p-gui__color {
124
124
  width: 100%;
125
- padding: 7px;
125
+ padding: 5px 3px;
126
126
  cursor: pointer;
127
127
  position: relative;
128
128
  box-sizing: border-box;
@@ -1,27 +0,0 @@
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
- }