perfect-gui 4.12.10 → 5.0.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 +2 -2
- package/dist/perfect-gui.js +378 -280
- package/package.json +1 -1
- package/src/components/Button.js +33 -20
- package/src/components/Color.js +64 -68
- package/src/components/Image.js +32 -16
- package/src/components/List.js +80 -76
- package/src/components/Slider.js +82 -54
- package/src/components/Toggle.js +59 -55
- package/src/components/Vector2.js +157 -72
- package/src/index.js +16 -17
package/src/components/Slider.js
CHANGED
|
@@ -1,54 +1,52 @@
|
|
|
1
1
|
export default class Slider {
|
|
2
|
-
constructor(parent,
|
|
2
|
+
constructor(parent, arg1, arg2, arg3) {
|
|
3
3
|
this.parent = parent;
|
|
4
4
|
this.propReferences = [];
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
let params = {};
|
|
7
|
+
let value = null;
|
|
8
|
+
|
|
9
|
+
if (arg1 && typeof arg1 === 'object' && typeof arg2 === 'string') {
|
|
10
|
+
this.obj = arg1;
|
|
11
|
+
this.prop = arg2;
|
|
12
|
+
this.isObject = true;
|
|
13
|
+
params = arg3 || {};
|
|
14
|
+
this.callback = null;
|
|
15
|
+
} else if (arg1 && typeof arg1 === 'object') {
|
|
16
|
+
this.isObject = false;
|
|
17
|
+
params = arg1;
|
|
18
|
+
value = typeof params.value == 'number' ? params.value : null;
|
|
19
|
+
} else {
|
|
20
|
+
throw Error(`[GUI] slider() invalid parameters.`);
|
|
8
21
|
}
|
|
9
22
|
|
|
10
23
|
let label = typeof params.label == 'string' ? params.label || ' ' : ' ';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
24
|
+
|
|
25
|
+
if (this.isObject && label == ' ') {
|
|
26
|
+
label = this.prop;
|
|
27
|
+
}
|
|
28
|
+
|
|
16
29
|
this.min = params.min ?? 0;
|
|
17
30
|
this.max = params.max ?? 1;
|
|
18
31
|
this.step = params.step || (this.max - this.min) / 100;
|
|
19
32
|
this.decimals = this.parent._countDecimals(this.step);
|
|
20
|
-
this.callback = typeof callback == 'function' ? callback : null;
|
|
21
33
|
|
|
22
|
-
|
|
23
|
-
if (value !== null) {
|
|
24
|
-
if (this.prop != undefined || this.obj != undefined) {
|
|
25
|
-
console.warn(`[GUI] slider() "obj" and "prop" parameters are ignored when a "value" parameter is used.`);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
// object-binding
|
|
29
|
-
else if (this.prop != undefined && this.obj != undefined) {
|
|
30
|
-
if (typeof this.prop != 'string') {
|
|
31
|
-
throw Error(`[GUI] slider() "prop" parameter must be an string. Received: ${typeof this.prop}.`);
|
|
32
|
-
}
|
|
33
|
-
if (typeof this.obj != 'object') {
|
|
34
|
-
throw Error(`[GUI] slider() "obj" parameter must be an object. Received: ${typeof this.obj}.`);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (label == ' ') {
|
|
38
|
-
label = this.prop;
|
|
39
|
-
}
|
|
34
|
+
let propReferenceIndex = null;
|
|
40
35
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
else {
|
|
45
|
-
if (
|
|
46
|
-
|
|
36
|
+
if (this.isObject) {
|
|
37
|
+
propReferenceIndex =
|
|
38
|
+
this.propReferences.push(this.obj[this.prop]) - 1;
|
|
39
|
+
} else {
|
|
40
|
+
if (value === null) {
|
|
41
|
+
value = (this.max - this.min) / 2;
|
|
47
42
|
}
|
|
48
|
-
|
|
49
|
-
value = (this.max - this.min) / 2;
|
|
50
43
|
}
|
|
51
|
-
const tooltip =
|
|
44
|
+
const tooltip =
|
|
45
|
+
typeof params.tooltip === 'string'
|
|
46
|
+
? params.tooltip
|
|
47
|
+
: params.tooltip === true
|
|
48
|
+
? label
|
|
49
|
+
: null;
|
|
52
50
|
|
|
53
51
|
const container = document.createElement('div');
|
|
54
52
|
container.className = 'p-gui__slider';
|
|
@@ -91,9 +89,21 @@ export default class Slider {
|
|
|
91
89
|
// init position
|
|
92
90
|
setTimeout(() => {
|
|
93
91
|
const handleWidth = this.handle.offsetWidth;
|
|
94
|
-
this.handle.position = this._mapLinear(
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
this.handle.position = this._mapLinear(
|
|
93
|
+
this.valueInput.value,
|
|
94
|
+
this.min,
|
|
95
|
+
this.max,
|
|
96
|
+
handleWidth / 2,
|
|
97
|
+
88 - handleWidth / 2,
|
|
98
|
+
);
|
|
99
|
+
this.handle.position = Math.min(
|
|
100
|
+
this.handle.position,
|
|
101
|
+
88 - handleWidth / 2,
|
|
102
|
+
);
|
|
103
|
+
this.handle.position = Math.max(
|
|
104
|
+
this.handle.position,
|
|
105
|
+
handleWidth / 2,
|
|
106
|
+
);
|
|
97
107
|
this.handle.style.transform = `translate(-50%, -50%) translateX(${this.handle.position}px)`;
|
|
98
108
|
this.filling.style.width = `${this.handle.position}px`;
|
|
99
109
|
}, 0); // wait for render
|
|
@@ -101,7 +111,7 @@ export default class Slider {
|
|
|
101
111
|
this.valueInput.addEventListener('change', () => {
|
|
102
112
|
this._updateHandlePositionFromValue();
|
|
103
113
|
this._triggerCallbacks();
|
|
104
|
-
})
|
|
114
|
+
});
|
|
105
115
|
|
|
106
116
|
this.ctrlDiv.addEventListener('pointerdown', (evt) => {
|
|
107
117
|
this.ctrlDiv.pointerDown = true;
|
|
@@ -115,14 +125,15 @@ export default class Slider {
|
|
|
115
125
|
|
|
116
126
|
window.addEventListener('pointermove', (evt) => {
|
|
117
127
|
if (this.ctrlDiv.pointerDown) {
|
|
118
|
-
this.ctrlDiv.pointerDelta =
|
|
128
|
+
this.ctrlDiv.pointerDelta =
|
|
129
|
+
evt.clientX - this.ctrlDiv.prevPosition;
|
|
119
130
|
this._updateHandlePositionFromPointer(evt);
|
|
120
131
|
}
|
|
121
132
|
});
|
|
122
133
|
|
|
123
134
|
if (this.isObject) {
|
|
124
135
|
Object.defineProperty(this.obj, this.prop, {
|
|
125
|
-
set: val => {
|
|
136
|
+
set: (val) => {
|
|
126
137
|
this.propReferences[propReferenceIndex] = val;
|
|
127
138
|
this.valueInput.value = val;
|
|
128
139
|
|
|
@@ -134,11 +145,9 @@ export default class Slider {
|
|
|
134
145
|
},
|
|
135
146
|
get: () => {
|
|
136
147
|
return this.propReferences[propReferenceIndex];
|
|
137
|
-
}
|
|
148
|
+
},
|
|
138
149
|
});
|
|
139
150
|
}
|
|
140
|
-
|
|
141
|
-
return container;
|
|
142
151
|
}
|
|
143
152
|
|
|
144
153
|
_updateHandlePositionFromPointer(evt, firstDown = false) {
|
|
@@ -154,9 +163,15 @@ export default class Slider {
|
|
|
154
163
|
handlePosition = this.handle.position + pointerDelta;
|
|
155
164
|
}
|
|
156
165
|
|
|
157
|
-
handlePosition = Math.max(
|
|
166
|
+
handlePosition = Math.max(
|
|
167
|
+
handleWidth / 2,
|
|
168
|
+
Math.min(handlePosition, sliderWidth - handleWidth / 2),
|
|
169
|
+
);
|
|
158
170
|
|
|
159
|
-
let newValue =
|
|
171
|
+
let newValue =
|
|
172
|
+
this.min +
|
|
173
|
+
((this.max - this.min) * (handlePosition - handleWidth / 2)) /
|
|
174
|
+
(sliderWidth - handleWidth);
|
|
160
175
|
if (newValue > currentValue) {
|
|
161
176
|
newValue = this._quantizeFloor(newValue, this.step);
|
|
162
177
|
} else {
|
|
@@ -187,9 +202,18 @@ export default class Slider {
|
|
|
187
202
|
_updateHandlePositionFromValue() {
|
|
188
203
|
const sliderWidth = this.ctrlDiv.offsetWidth;
|
|
189
204
|
const handleWidth = this.handle.offsetWidth;
|
|
190
|
-
let handlePosition = this._mapLinear(
|
|
191
|
-
|
|
192
|
-
|
|
205
|
+
let handlePosition = this._mapLinear(
|
|
206
|
+
this.valueInput.value,
|
|
207
|
+
this.min,
|
|
208
|
+
this.max,
|
|
209
|
+
handleWidth / 2,
|
|
210
|
+
sliderWidth - handleWidth / 2,
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
handlePosition = Math.max(
|
|
214
|
+
handleWidth / 2,
|
|
215
|
+
Math.min(handlePosition, sliderWidth - handleWidth / 2),
|
|
216
|
+
);
|
|
193
217
|
|
|
194
218
|
this.handle.style.transform = `translate(-50%, -50%) translateX(${handlePosition}px)`;
|
|
195
219
|
this.handle.position = handlePosition;
|
|
@@ -200,8 +224,7 @@ export default class Slider {
|
|
|
200
224
|
_triggerCallbacks() {
|
|
201
225
|
if (this.isObject) {
|
|
202
226
|
this.obj[this.prop] = parseFloat(this.valueInput.value);
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
227
|
+
} else {
|
|
205
228
|
if (this.callback) {
|
|
206
229
|
this.callback(parseFloat(this.valueInput.value));
|
|
207
230
|
}
|
|
@@ -215,7 +238,7 @@ export default class Slider {
|
|
|
215
238
|
}
|
|
216
239
|
|
|
217
240
|
_mapLinear(x, a1, a2, b1, b2) {
|
|
218
|
-
return b1 + (x - a1) * (b2 - b1) / (a2 - a1);
|
|
241
|
+
return b1 + ((x - a1) * (b2 - b1)) / (a2 - a1);
|
|
219
242
|
}
|
|
220
243
|
|
|
221
244
|
_quantize(x, step) {
|
|
@@ -229,4 +252,9 @@ export default class Slider {
|
|
|
229
252
|
_quantizeFloor(x, step) {
|
|
230
253
|
return step * Math.floor(x / step);
|
|
231
254
|
}
|
|
232
|
-
|
|
255
|
+
|
|
256
|
+
onChange(callback) {
|
|
257
|
+
this.callback = callback;
|
|
258
|
+
return this;
|
|
259
|
+
}
|
|
260
|
+
}
|
package/src/components/Toggle.js
CHANGED
|
@@ -1,80 +1,77 @@
|
|
|
1
1
|
export default class Toggle {
|
|
2
|
-
constructor(parent,
|
|
2
|
+
constructor(parent, arg1, arg2, arg3) {
|
|
3
3
|
this.parent = parent;
|
|
4
|
+
this.callback = null;
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
let params = {};
|
|
7
|
+
let value = null;
|
|
8
|
+
let isObject = false;
|
|
9
|
+
let obj, prop;
|
|
10
|
+
|
|
11
|
+
if (arg1 && typeof arg1 === 'object' && typeof arg2 === 'string') {
|
|
12
|
+
obj = arg1;
|
|
13
|
+
prop = arg2;
|
|
14
|
+
isObject = true;
|
|
15
|
+
params = arg3 || {};
|
|
16
|
+
} else if (arg1 && typeof arg1 === 'object') {
|
|
17
|
+
isObject = false;
|
|
18
|
+
params = arg1;
|
|
19
|
+
value = typeof params.value === 'boolean' ? params.value : null;
|
|
20
|
+
} else {
|
|
21
|
+
throw Error(`[GUI] toggle() invalid parameters.`);
|
|
7
22
|
}
|
|
8
23
|
|
|
9
24
|
let label = typeof params.label == 'string' ? params.label || ' ' : ' ';
|
|
10
|
-
let isObject = false;
|
|
11
25
|
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
26
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
}
|
|
27
|
+
if (isObject && label == ' ') {
|
|
28
|
+
label = prop;
|
|
29
|
+
}
|
|
35
30
|
|
|
31
|
+
if (isObject) {
|
|
36
32
|
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
33
|
}
|
|
44
34
|
|
|
45
|
-
const tooltip =
|
|
35
|
+
const tooltip =
|
|
36
|
+
typeof params.tooltip === 'string'
|
|
37
|
+
? params.tooltip
|
|
38
|
+
: params.tooltip === true
|
|
39
|
+
? label
|
|
40
|
+
: null;
|
|
46
41
|
|
|
47
42
|
const container = document.createElement('div');
|
|
48
43
|
container.textContent = label;
|
|
49
44
|
container.className = 'p-gui__toggle';
|
|
50
|
-
if (
|
|
45
|
+
if (tooltip) {
|
|
51
46
|
container.setAttribute('title', tooltip);
|
|
52
47
|
}
|
|
48
|
+
this.parent.wrapper.append(container);
|
|
53
49
|
|
|
54
50
|
container.addEventListener('click', (ev) => {
|
|
55
51
|
const checkbox = ev.target.childNodes[1];
|
|
56
|
-
|
|
52
|
+
|
|
57
53
|
let value = true;
|
|
58
|
-
|
|
54
|
+
|
|
59
55
|
if (checkbox.classList.contains('p-gui__toggle-checkbox--active')) {
|
|
60
56
|
value = false;
|
|
61
57
|
}
|
|
62
|
-
|
|
58
|
+
|
|
63
59
|
checkbox.classList.toggle('p-gui__toggle-checkbox--active');
|
|
64
60
|
|
|
65
|
-
if (
|
|
61
|
+
if (isObject) {
|
|
66
62
|
obj[prop] = value;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (typeof callback == 'function') {
|
|
71
|
-
callback(value);
|
|
63
|
+
} else {
|
|
64
|
+
if (typeof this.callback == 'function') {
|
|
65
|
+
this.callback(value);
|
|
72
66
|
}
|
|
73
67
|
}
|
|
74
68
|
|
|
75
69
|
if (this.parent.onUpdate) {
|
|
76
70
|
this.parent.onUpdate();
|
|
77
|
-
} else if (
|
|
71
|
+
} else if (
|
|
72
|
+
this.parent.isFolder &&
|
|
73
|
+
this.parent.firstParent.onUpdate
|
|
74
|
+
) {
|
|
78
75
|
this.parent.firstParent.onUpdate();
|
|
79
76
|
}
|
|
80
77
|
});
|
|
@@ -91,27 +88,34 @@ export default class Toggle {
|
|
|
91
88
|
checkbox.className = 'p-gui__toggle-checkbox' + activeClass;
|
|
92
89
|
container.append(checkbox);
|
|
93
90
|
|
|
94
|
-
if (
|
|
95
|
-
Object.defineProperty(
|
|
96
|
-
set: val => {
|
|
91
|
+
if (isObject) {
|
|
92
|
+
Object.defineProperty(obj, prop, {
|
|
93
|
+
set: (val) => {
|
|
97
94
|
this.parent.propReferences[propReferenceIndex] = val;
|
|
98
95
|
|
|
99
96
|
if (val) {
|
|
100
|
-
checkbox.classList.add(
|
|
97
|
+
checkbox.classList.add(
|
|
98
|
+
'p-gui__toggle-checkbox--active',
|
|
99
|
+
);
|
|
101
100
|
} else {
|
|
102
|
-
checkbox.classList.remove(
|
|
101
|
+
checkbox.classList.remove(
|
|
102
|
+
'p-gui__toggle-checkbox--active',
|
|
103
|
+
);
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
if (typeof callback == 'function') {
|
|
106
|
-
callback(val);
|
|
106
|
+
if (typeof this.callback == 'function') {
|
|
107
|
+
this.callback(val);
|
|
107
108
|
}
|
|
108
109
|
},
|
|
109
|
-
get: () => {
|
|
110
|
+
get: () => {
|
|
110
111
|
return this.parent.propReferences[propReferenceIndex];
|
|
111
|
-
}
|
|
112
|
+
},
|
|
112
113
|
});
|
|
113
114
|
}
|
|
115
|
+
}
|
|
114
116
|
|
|
115
|
-
|
|
117
|
+
onChange(callback) {
|
|
118
|
+
this.callback = callback;
|
|
119
|
+
return this;
|
|
116
120
|
}
|
|
117
|
-
}
|
|
121
|
+
}
|