perfect-gui 4.12.0 → 4.12.4
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 +3 -13
- package/dist/{perfect-gui.mjs → perfect-gui.js} +346 -325
- package/package.json +2 -1
- package/src/components/Button.js +44 -0
- package/src/components/Color.js +108 -0
- package/src/components/Image.js +87 -0
- package/src/components/List.js +171 -0
- package/src/components/Slider.js +25 -25
- package/src/components/Toggle.js +117 -0
- package/src/components/Vector2.js +145 -0
- package/src/index.js +26 -624
- package/src/styles/_folder.css.js +1 -1
- package/src/styles/_slider.css.js +3 -3
- package/src/styles/_toggle.css.js +34 -0
- package/src/styles/styles.js +5 -5
- package/vite.config.js +2 -1
- package/dist/perfect-gui.umd.js +0 -536
- package/src/styles/_switch.css.js +0 -35
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export default class Toggle {
|
|
2
|
+
constructor(parent, params = {}, callback) {
|
|
3
|
+
this.parent = parent;
|
|
4
|
+
|
|
5
|
+
if (typeof params != 'object') {
|
|
6
|
+
throw Error(`[GUI] toggle() first parameter must be an object. Received: ${typeof params}.`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let label = typeof params.label == 'string' ? params.label || ' ' : ' ';
|
|
10
|
+
let isObject = false;
|
|
11
|
+
let propReferenceIndex = null;
|
|
12
|
+
let obj = params.obj;
|
|
13
|
+
let prop = params.prop;
|
|
14
|
+
let value = typeof params.value === 'boolean' ? params.value : null;
|
|
15
|
+
|
|
16
|
+
// callback mode
|
|
17
|
+
if ( value !== null ) {
|
|
18
|
+
if (prop != undefined || obj != undefined) {
|
|
19
|
+
console.warn(`[GUI] toggle() "obj" and "prop" parameters are ignored when a "value" parameter is used.`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// object-binding
|
|
24
|
+
else if (prop != undefined && obj != undefined) {
|
|
25
|
+
if (typeof prop != 'string') {
|
|
26
|
+
throw Error(`[GUI] toggle() "prop" parameter must be an string. Received: ${typeof prop}.`);
|
|
27
|
+
}
|
|
28
|
+
if (typeof obj != 'object') {
|
|
29
|
+
throw Error(`[GUI] toggle() "obj" parameter must be an object. Received: ${typeof obj}.`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (label == ' ') {
|
|
33
|
+
label = prop;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
propReferenceIndex = this.parent.propReferences.push(obj[prop]) - 1;
|
|
37
|
+
isObject = true;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
if ((prop != undefined && obj == undefined) || (prop == undefined && obj == undefined)) {
|
|
41
|
+
console.warn(`[GUI] toggle() "obj" and "prop" parameters must be used together.`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
|
|
46
|
+
|
|
47
|
+
const container = document.createElement('div');
|
|
48
|
+
container.textContent = label;
|
|
49
|
+
container.className = 'p-gui__toggle';
|
|
50
|
+
if ( tooltip ) {
|
|
51
|
+
container.setAttribute('title', tooltip);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
container.addEventListener('click', (ev) => {
|
|
55
|
+
const checkbox = ev.target.childNodes[1];
|
|
56
|
+
|
|
57
|
+
let value = true;
|
|
58
|
+
|
|
59
|
+
if (checkbox.classList.contains('p-gui__toggle-checkbox--active')) {
|
|
60
|
+
value = false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
checkbox.classList.toggle('p-gui__toggle-checkbox--active');
|
|
64
|
+
|
|
65
|
+
if ( isObject ) {
|
|
66
|
+
obj[prop] = value;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
else {
|
|
70
|
+
if (typeof callback == 'function') {
|
|
71
|
+
callback(value);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (this.parent.onUpdate) {
|
|
76
|
+
this.parent.onUpdate();
|
|
77
|
+
} else if (this.parent.isFolder && this.parent.firstParent.onUpdate) {
|
|
78
|
+
this.parent.firstParent.onUpdate();
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
let activeClass = (() => {
|
|
83
|
+
if (!isObject) {
|
|
84
|
+
return value ? ' p-gui__toggle-checkbox--active' : '';
|
|
85
|
+
} else {
|
|
86
|
+
return obj[prop] ? ' p-gui__toggle-checkbox--active' : '';
|
|
87
|
+
}
|
|
88
|
+
})();
|
|
89
|
+
|
|
90
|
+
const checkbox = document.createElement('div');
|
|
91
|
+
checkbox.className = 'p-gui__toggle-checkbox' + activeClass;
|
|
92
|
+
container.append(checkbox);
|
|
93
|
+
|
|
94
|
+
if ( isObject ) {
|
|
95
|
+
Object.defineProperty( obj, prop, {
|
|
96
|
+
set: val => {
|
|
97
|
+
this.parent.propReferences[propReferenceIndex] = val;
|
|
98
|
+
|
|
99
|
+
if (val) {
|
|
100
|
+
checkbox.classList.add('p-gui__toggle-checkbox--active');
|
|
101
|
+
} else {
|
|
102
|
+
checkbox.classList.remove('p-gui__toggle-checkbox--active');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (typeof callback == 'function') {
|
|
106
|
+
callback(val);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
get: () => {
|
|
110
|
+
return this.parent.propReferences[propReferenceIndex];
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return container;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
export default class Vector2 {
|
|
2
|
+
constructor(parent, params = {}, callback) {
|
|
3
|
+
this.parent = parent;
|
|
4
|
+
|
|
5
|
+
if (typeof params != 'object') {
|
|
6
|
+
throw Error(`[GUI] vector2() first parameter must be an object. Received: ${typeof params}.`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let label = typeof params.label == 'string' ? params.label || ' ' : ' ';
|
|
10
|
+
|
|
11
|
+
const minX = params.x.min ?? 0;
|
|
12
|
+
const maxX = params.x.max ?? 1;
|
|
13
|
+
const minY = params.y.min ?? 0;
|
|
14
|
+
const maxY = params.y.max ?? 1;
|
|
15
|
+
const stepX = params.x.step || (maxX - minX) / 100;
|
|
16
|
+
const stepY = params.y.step || (maxY - minY) / 100;
|
|
17
|
+
const decimalsX = this.parent._countDecimals(stepX);
|
|
18
|
+
const decimalsY = this.parent._countDecimals(stepY);
|
|
19
|
+
|
|
20
|
+
const objectX = params.x.obj;
|
|
21
|
+
const propX = params.x.prop;
|
|
22
|
+
const propXReferenceIndex = this.parent.propReferences.push(objectX[propX]) - 1;
|
|
23
|
+
|
|
24
|
+
const objectY = params.y.obj;
|
|
25
|
+
const propY = params.y.prop;
|
|
26
|
+
const propYReferenceIndex = this.parent.propReferences.push(objectY[propY]) - 1;
|
|
27
|
+
|
|
28
|
+
const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
|
|
29
|
+
|
|
30
|
+
callback = typeof callback == 'function' ? callback : null;
|
|
31
|
+
|
|
32
|
+
const container = document.createElement('div');
|
|
33
|
+
container.className = 'p-gui__vector2';
|
|
34
|
+
container.textContent = label;
|
|
35
|
+
if ( tooltip ) {
|
|
36
|
+
container.setAttribute('title', tooltip);
|
|
37
|
+
}
|
|
38
|
+
this.parent.wrapper.append(container);
|
|
39
|
+
|
|
40
|
+
const vector_value = document.createElement('div');
|
|
41
|
+
vector_value.className = 'p-gui__vector-value';
|
|
42
|
+
vector_value.textContent = objectX[propX] + ', ' + objectY[propY];
|
|
43
|
+
container.append(vector_value);
|
|
44
|
+
|
|
45
|
+
const area = document.createElement('div');
|
|
46
|
+
area.className = 'p-gui__vector2-area';
|
|
47
|
+
container.append(area);
|
|
48
|
+
area.addEventListener('click', evt => {
|
|
49
|
+
const newX = parseFloat(this.parent._mapLinear(evt.offsetX, 0, area.clientWidth, minX, maxX));
|
|
50
|
+
const newY = parseFloat(this.parent._mapLinear(evt.offsetY, 0, area.clientHeight, maxY, minY));
|
|
51
|
+
objectX[propX] = newX.toFixed(decimalsX);
|
|
52
|
+
objectY[propY] = newY.toFixed(decimalsY);
|
|
53
|
+
|
|
54
|
+
if (callback) {
|
|
55
|
+
callback(objectX[propX], objectX[propY]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (this.parent.onUpdate) {
|
|
59
|
+
this.parent.onUpdate();
|
|
60
|
+
} else if (this.parent.isFolder && this.parent.firstParent.onUpdate) {
|
|
61
|
+
this.parent.firstParent.onUpdate();
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const handlePointerMove = (evt) => {
|
|
66
|
+
const rect = area.getBoundingClientRect();
|
|
67
|
+
const offsetX = evt.clientX - rect.left;
|
|
68
|
+
const offsetY = evt.clientY - rect.top;
|
|
69
|
+
|
|
70
|
+
// Calculate new values and clamp them within min/max bounds
|
|
71
|
+
const mappedX = this.parent._mapLinear(offsetX, 0, area.clientWidth, minX, maxX);
|
|
72
|
+
const mappedY = this.parent._mapLinear(offsetY, 0, area.clientHeight, maxY, minY);
|
|
73
|
+
|
|
74
|
+
const clampedX = Math.max(minX, Math.min(maxX, mappedX));
|
|
75
|
+
const clampedY = Math.max(minY, Math.min(maxY, mappedY));
|
|
76
|
+
|
|
77
|
+
objectX[propX] = parseFloat(clampedX.toFixed(decimalsX));
|
|
78
|
+
objectY[propY] = parseFloat(clampedY.toFixed(decimalsY));
|
|
79
|
+
|
|
80
|
+
if (callback) {
|
|
81
|
+
callback(objectX[propX], objectY[propY]);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (this.parent.onUpdate) {
|
|
85
|
+
this.parent.onUpdate();
|
|
86
|
+
} else if (this.parent.isFolder && this.parent.firstParent.onUpdate) {
|
|
87
|
+
this.parent.firstParent.onUpdate();
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
area.addEventListener('pointerdown', (evt) => {
|
|
92
|
+
// Call handlePointerMove immediately to update position on click
|
|
93
|
+
handlePointerMove(evt);
|
|
94
|
+
|
|
95
|
+
// Attach pointermove to document to capture movements everywhere
|
|
96
|
+
document.addEventListener('pointermove', handlePointerMove);
|
|
97
|
+
|
|
98
|
+
// Clean up on pointerup
|
|
99
|
+
document.addEventListener('pointerup', () => {
|
|
100
|
+
document.removeEventListener('pointermove', handlePointerMove);
|
|
101
|
+
}, {once: true});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
const line_x = document.createElement('div');
|
|
107
|
+
line_x.className = 'p-gui__vector2-line p-gui__vector2-line-x';
|
|
108
|
+
area.append(line_x);
|
|
109
|
+
|
|
110
|
+
const line_y = document.createElement('div');
|
|
111
|
+
line_y.className = 'p-gui__vector2-line p-gui__vector2-line-y';
|
|
112
|
+
area.append(line_y);
|
|
113
|
+
|
|
114
|
+
const dot = document.createElement('div');
|
|
115
|
+
dot.className = 'p-gui__vector2-dot';
|
|
116
|
+
area.append(dot);
|
|
117
|
+
|
|
118
|
+
dot.style.left = this.parent._mapLinear(objectX[propX], minX, maxX, 0, area.clientWidth) + 'px';
|
|
119
|
+
dot.style.top = this.parent._mapLinear(objectY[propY], minY, maxY, area.clientHeight, 0) + 'px';
|
|
120
|
+
|
|
121
|
+
Object.defineProperty( objectX, propX, {
|
|
122
|
+
set: val => {
|
|
123
|
+
this.parent.propReferences[propXReferenceIndex] = val;
|
|
124
|
+
dot.style.left = this.parent._mapLinear(val, minX, maxX, 0, area.clientWidth) + 'px';
|
|
125
|
+
vector_value.textContent = String( val ) + ', ' + objectY[propY];
|
|
126
|
+
},
|
|
127
|
+
get: () => {
|
|
128
|
+
return this.parent.propReferences[propXReferenceIndex];
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
Object.defineProperty( objectY, propY, {
|
|
133
|
+
set: val => {
|
|
134
|
+
this.parent.propReferences[propYReferenceIndex] = val;
|
|
135
|
+
dot.style.top = this.parent._mapLinear(val, minY, maxY, area.clientHeight, 0) + 'px';
|
|
136
|
+
vector_value.textContent = objectX[propX] + ', ' + String( val );
|
|
137
|
+
},
|
|
138
|
+
get: () => {
|
|
139
|
+
return this.parent.propReferences[propYReferenceIndex];
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
return container;
|
|
144
|
+
}
|
|
145
|
+
}
|