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
package/package.json
CHANGED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export default class Slider {
|
|
2
|
+
constructor(parent, params = {}, callback) {
|
|
3
|
+
this.parent = parent;
|
|
4
|
+
|
|
5
|
+
let label = '';
|
|
6
|
+
if (typeof params != 'string') {
|
|
7
|
+
if (typeof params == 'object' && params?.hasOwnProperty('label')) {
|
|
8
|
+
label = params.label == '' ? ' ' : params.label;
|
|
9
|
+
} else {
|
|
10
|
+
label = ' ';
|
|
11
|
+
}
|
|
12
|
+
} else {
|
|
13
|
+
label = params == '' ? ' ' : params;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
|
|
17
|
+
|
|
18
|
+
const el = document.createElement('div');
|
|
19
|
+
el.className = 'p-gui__button';
|
|
20
|
+
el.textContent = label;
|
|
21
|
+
if ( tooltip ) {
|
|
22
|
+
el.setAttribute('title', tooltip);
|
|
23
|
+
}
|
|
24
|
+
el.addEventListener('click', () => {
|
|
25
|
+
if (callback) {
|
|
26
|
+
callback();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (this.parent.onUpdate) {
|
|
30
|
+
this.parent.onUpdate();
|
|
31
|
+
} else if (this.parent.isFolder && this.parent.firstParent.onUpdate) {
|
|
32
|
+
this.parent.firstParent.onUpdate();
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (typeof params.color == 'string') {
|
|
37
|
+
el.style.setProperty('--color-accent', params.color);
|
|
38
|
+
el.style.setProperty('--color-accent-hover', params.hoverColor || params.color);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.parent.wrapper.append(el);
|
|
42
|
+
return el;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export default class Color {
|
|
2
|
+
constructor(parent, params = {}, callback) {
|
|
3
|
+
this.parent = parent;
|
|
4
|
+
|
|
5
|
+
if (typeof params != 'object') {
|
|
6
|
+
throw Error(`[GUI] color() first parameter must be an object. Received: ${typeof params}.`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let label = typeof params.label == 'string' ? params.label || ' ' : ' ';
|
|
10
|
+
|
|
11
|
+
let isObject = false;
|
|
12
|
+
let propReferenceIndex = null;
|
|
13
|
+
let obj = params.obj;
|
|
14
|
+
let prop = params.prop;
|
|
15
|
+
let value;
|
|
16
|
+
const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
|
|
17
|
+
|
|
18
|
+
if (typeof params.value == 'string') {
|
|
19
|
+
if (params.value.length != 7 || params.value[0] != '#') {
|
|
20
|
+
console.error(`[GUI] color() 'value' parameter must be an hexadecimal string in the format "#ffffff". Received: "${params.value}".`)
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
value = params.value;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (!value) value = '#000000';
|
|
27
|
+
|
|
28
|
+
// callback mode
|
|
29
|
+
if ( params.value !== undefined ) {
|
|
30
|
+
if (prop != undefined || obj != undefined) {
|
|
31
|
+
console.warn(`[GUI] color() "obj" and "prop" parameters are ignored when a "value" parameter is used.`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// object-binding
|
|
36
|
+
else if (prop != undefined && obj != undefined) {
|
|
37
|
+
if (typeof prop != 'string') {
|
|
38
|
+
throw Error(`[GUI] color() "prop" parameter must be an string. Received: ${typeof prop}.`);
|
|
39
|
+
}
|
|
40
|
+
if (typeof obj != 'object') {
|
|
41
|
+
throw Error(`[GUI] color() "obj" parameter must be an object. Received: ${typeof obj}.`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (label == ' ') {
|
|
45
|
+
label = prop;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
propReferenceIndex = this.parent.propReferences.push(obj[prop]) - 1;
|
|
49
|
+
isObject = true;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
if ((prop != undefined && obj == undefined) || (prop == undefined && obj == undefined)) {
|
|
53
|
+
console.warn(`[GUI] color() "obj" and "prop" parameters must be used together.`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const container = document.createElement('div');
|
|
58
|
+
container.className = 'p-gui__color';
|
|
59
|
+
container.textContent = label;
|
|
60
|
+
if ( tooltip ) {
|
|
61
|
+
container.setAttribute('title', tooltip);
|
|
62
|
+
}
|
|
63
|
+
this.parent.wrapper.append(container);
|
|
64
|
+
|
|
65
|
+
const colorpicker = document.createElement('input');
|
|
66
|
+
colorpicker.className = 'p-gui__color-picker';
|
|
67
|
+
colorpicker.setAttribute('type', 'color');
|
|
68
|
+
colorpicker.value = value;
|
|
69
|
+
container.append(colorpicker);
|
|
70
|
+
|
|
71
|
+
if (typeof callback == 'function') {
|
|
72
|
+
colorpicker.addEventListener('input', () => {
|
|
73
|
+
if ( isObject ) {
|
|
74
|
+
obj[prop] = colorpicker.value;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
else if (typeof callback == 'function') {
|
|
78
|
+
callback(colorpicker.value);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (this.parent.onUpdate) {
|
|
82
|
+
this.parent.onUpdate();
|
|
83
|
+
} else if (this.parent.isFolder && this.parent.firstParent.onUpdate) {
|
|
84
|
+
this.parent.firstParent.onUpdate();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if ( isObject ) {
|
|
90
|
+
Object.defineProperty( obj, prop, {
|
|
91
|
+
set: val => {
|
|
92
|
+
this.parent.propReferences[propReferenceIndex] = val;
|
|
93
|
+
|
|
94
|
+
colorpicker.value = val;
|
|
95
|
+
|
|
96
|
+
if (typeof callback == 'function') {
|
|
97
|
+
callback(val);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
get: () => {
|
|
101
|
+
return this.parent.propReferences[propReferenceIndex];
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return container;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export default class Image {
|
|
2
|
+
constructor(parent, params = {}, callback) {
|
|
3
|
+
this.parent = parent;
|
|
4
|
+
|
|
5
|
+
if (typeof params != 'object') {
|
|
6
|
+
throw Error(`[GUI] image() first parameter must be an object. Received: ${typeof params}.`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let path;
|
|
10
|
+
if (typeof params.path == 'string') {
|
|
11
|
+
path = params.path;
|
|
12
|
+
} else {
|
|
13
|
+
if (typeof params.path == undefined) {
|
|
14
|
+
throw Error(`[GUI] image() path must be provided.`);
|
|
15
|
+
} else {
|
|
16
|
+
throw Error(`[GUI] image() path must be a string.`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
let filename = path.replace(/^.*[\\\/]/, '');
|
|
20
|
+
let label;
|
|
21
|
+
if (params.label == undefined) {
|
|
22
|
+
label = filename;
|
|
23
|
+
} else {
|
|
24
|
+
label = typeof params.label == 'string' ? params.label || ' ' : ' ';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
|
|
28
|
+
|
|
29
|
+
const selected = params.selected === true;
|
|
30
|
+
const selectionBorder = params.selectionBorder !== false;
|
|
31
|
+
|
|
32
|
+
// width & height options
|
|
33
|
+
let inline_styles = '';
|
|
34
|
+
if (params.width) {
|
|
35
|
+
if (typeof params.width == 'number') {
|
|
36
|
+
params.width += 'px';
|
|
37
|
+
}
|
|
38
|
+
inline_styles += `flex: 0 0 calc(${params.width} - 5px); `;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (params.height) {
|
|
42
|
+
if (typeof params.height == 'number') {
|
|
43
|
+
params.height += 'px';
|
|
44
|
+
}
|
|
45
|
+
inline_styles += `height: ${params.height}; `;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Image button
|
|
49
|
+
const image = document.createElement('div');
|
|
50
|
+
image.className = 'p-gui__image';
|
|
51
|
+
image.style = 'background-image: url(' + path + '); ' + inline_styles;
|
|
52
|
+
if ( tooltip ) {
|
|
53
|
+
image.setAttribute('title', tooltip);
|
|
54
|
+
}
|
|
55
|
+
this.parent.imageContainer.append(image);
|
|
56
|
+
|
|
57
|
+
if (selected && selectionBorder) {
|
|
58
|
+
image.classList.add('p-gui__image--selected');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Text inside image
|
|
62
|
+
const text = document.createElement('div');
|
|
63
|
+
text.className = 'p-gui__image-text';
|
|
64
|
+
text.textContent = label;
|
|
65
|
+
image.append(text);
|
|
66
|
+
|
|
67
|
+
image.addEventListener('click', () => {
|
|
68
|
+
let selected_items = image.parentElement.querySelectorAll('.p-gui__image--selected');
|
|
69
|
+
for (let i = 0; i < selected_items.length; i++) {
|
|
70
|
+
selected_items[i].classList.remove('p-gui__image--selected');
|
|
71
|
+
}
|
|
72
|
+
if (selectionBorder) {
|
|
73
|
+
image.classList.add('p-gui__image--selected');
|
|
74
|
+
}
|
|
75
|
+
if (typeof callback == 'function') {
|
|
76
|
+
callback({ path, text: label });
|
|
77
|
+
}
|
|
78
|
+
if (this.parent.onUpdate) {
|
|
79
|
+
this.parent.onUpdate();
|
|
80
|
+
} else if (this.parent.isFolder && this.parent.firstParent.onUpdate) {
|
|
81
|
+
this.parent.firstParent.onUpdate();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return image;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
export default class List {
|
|
2
|
+
constructor(parent, params = {}, callback) {
|
|
3
|
+
this.parent = parent;
|
|
4
|
+
|
|
5
|
+
if (typeof params != 'object') {
|
|
6
|
+
throw Error(`[GUI] list() 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 values = Array.isArray(params.values) ? params.values : null;
|
|
15
|
+
let value;
|
|
16
|
+
let objectValues = typeof values[0] == 'string' ? false : true;
|
|
17
|
+
const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
|
|
18
|
+
|
|
19
|
+
callback = typeof callback == 'function' ? callback : null;
|
|
20
|
+
|
|
21
|
+
// callback mode
|
|
22
|
+
if ( params.value !== undefined ||
|
|
23
|
+
(params.value === undefined && obj === undefined && prop === undefined)) {
|
|
24
|
+
if (prop != undefined || obj != undefined) {
|
|
25
|
+
console.warn(`[GUI] list() "obj" and "prop" parameters are ignored when a "value" parameter is used.`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
value = (() => {
|
|
29
|
+
if (!values) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
if (typeof params.value == 'string') {
|
|
33
|
+
return values.indexOf(params.value);
|
|
34
|
+
}
|
|
35
|
+
if (typeof params.value == 'number') {
|
|
36
|
+
return params.value;
|
|
37
|
+
}
|
|
38
|
+
})();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// object-binding mode
|
|
42
|
+
else if (prop != undefined && obj != undefined) {
|
|
43
|
+
if (typeof prop != 'string') {
|
|
44
|
+
throw Error(`[GUI] list() "prop" parameter must be an string. Received: ${typeof prop}.`);
|
|
45
|
+
}
|
|
46
|
+
if (typeof obj != 'object') {
|
|
47
|
+
throw Error(`[GUI] list() "obj" parameter must be an object. Received: ${typeof obj}.`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
value = (() => {
|
|
51
|
+
if (!values) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
if (typeof obj[prop] == 'string') {
|
|
55
|
+
if ( !objectValues ) { // values is an array of strings
|
|
56
|
+
return values.indexOf(obj[prop]);
|
|
57
|
+
}
|
|
58
|
+
else { // values is an array of objects
|
|
59
|
+
return values.find(item => item.value === obj[prop]).value;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (typeof obj[prop] == 'number') {
|
|
63
|
+
if ( !objectValues ) { // values is an array of strings
|
|
64
|
+
return obj[prop];
|
|
65
|
+
}
|
|
66
|
+
else { // values is an array of objects
|
|
67
|
+
return values.find(item => item.value === obj[prop]).value;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
})();
|
|
71
|
+
|
|
72
|
+
propReferenceIndex = this.parent.propReferences.push(obj[prop]) - 1;
|
|
73
|
+
isObject = true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
else {
|
|
77
|
+
if ((prop != undefined && obj == undefined) || (prop == undefined && obj == undefined)) {
|
|
78
|
+
console.warn(`[GUI] list() "obj" and "prop" parameters must be used together.`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let container = document.createElement('div');
|
|
83
|
+
container.className = 'p-gui__list';
|
|
84
|
+
container.textContent = label;
|
|
85
|
+
if (tooltip) {
|
|
86
|
+
container.setAttribute('title', tooltip);
|
|
87
|
+
}
|
|
88
|
+
this.parent.wrapper.append(container);
|
|
89
|
+
|
|
90
|
+
let select = document.createElement('select');
|
|
91
|
+
container.append(select);
|
|
92
|
+
select.className = 'p-gui__list-dropdown';
|
|
93
|
+
select.addEventListener('change', (ev) => {
|
|
94
|
+
if ( isObject ) {
|
|
95
|
+
obj[prop] = ev.target.value;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
else if (callback) {
|
|
99
|
+
callback(ev.target.value);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (this.parent.onUpdate) {
|
|
103
|
+
this.parent.onUpdate();
|
|
104
|
+
} else if (this.parent.isFolder && this.parent.firstParent.onUpdate) {
|
|
105
|
+
this.parent.firstParent.onUpdate();
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
if (values)
|
|
110
|
+
{
|
|
111
|
+
values.forEach((item, index) =>
|
|
112
|
+
{
|
|
113
|
+
const optionName = objectValues ? item.label : item;
|
|
114
|
+
const optionValue = objectValues ? item.value : item;
|
|
115
|
+
let option = document.createElement('option');
|
|
116
|
+
option.setAttribute('value', optionValue);
|
|
117
|
+
option.textContent = optionName;
|
|
118
|
+
select.append(option);
|
|
119
|
+
|
|
120
|
+
if (!objectValues && value == index || objectValues && value == optionValue) {
|
|
121
|
+
option.setAttribute('selected', '');
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if ( isObject ) {
|
|
127
|
+
Object.defineProperty( obj, prop, {
|
|
128
|
+
set: val => {
|
|
129
|
+
let newIndex, newValue, newObj;
|
|
130
|
+
if (objectValues) {
|
|
131
|
+
newObj = values.find(item => {
|
|
132
|
+
return item.value == val;
|
|
133
|
+
});
|
|
134
|
+
newValue = newObj?.value || values[0].value;
|
|
135
|
+
newIndex = values.indexOf(newObj);
|
|
136
|
+
} else {
|
|
137
|
+
if (typeof val == 'string') {
|
|
138
|
+
newIndex = values.indexOf(val);
|
|
139
|
+
newValue = val;
|
|
140
|
+
}
|
|
141
|
+
if (typeof val == 'number') {
|
|
142
|
+
newIndex = val;
|
|
143
|
+
newValue = values[val];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
this.parent.propReferences[propReferenceIndex] = objectValues ? newValue : val;
|
|
148
|
+
|
|
149
|
+
const previousSelection = select.querySelector('[selected]');
|
|
150
|
+
if ( previousSelection ) {
|
|
151
|
+
previousSelection.removeAttribute('selected')
|
|
152
|
+
}
|
|
153
|
+
select.querySelectorAll('option')[newIndex].setAttribute('selected', '');
|
|
154
|
+
|
|
155
|
+
if (typeof callback == 'function') {
|
|
156
|
+
if (objectValues) {
|
|
157
|
+
callback(newObj, newIndex);
|
|
158
|
+
} else {
|
|
159
|
+
callback(newValue, newIndex);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
get: () => {
|
|
164
|
+
return this.parent.propReferences[propReferenceIndex];
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return container;
|
|
170
|
+
}
|
|
171
|
+
}
|
package/src/components/Slider.js
CHANGED
|
@@ -10,7 +10,7 @@ export default class Slider {
|
|
|
10
10
|
let label = typeof params.label == 'string' ? params.label || ' ' : ' ';
|
|
11
11
|
this.isObject = false;
|
|
12
12
|
let propReferenceIndex = null;
|
|
13
|
-
this.obj = params.obj;
|
|
13
|
+
this.obj = params.obj;
|
|
14
14
|
this.prop = params.prop;
|
|
15
15
|
let value = typeof params.value == 'number' ? params.value : null;
|
|
16
16
|
this.min = params.min ?? 0;
|
|
@@ -20,7 +20,7 @@ export default class Slider {
|
|
|
20
20
|
this.callback = typeof callback == 'function' ? callback : null;
|
|
21
21
|
|
|
22
22
|
// callback mode
|
|
23
|
-
if (
|
|
23
|
+
if (value !== null) {
|
|
24
24
|
if (this.prop != undefined || this.obj != undefined) {
|
|
25
25
|
console.warn(`[GUI] slider() "obj" and "prop" parameters are ignored when a "value" parameter is used.`);
|
|
26
26
|
}
|
|
@@ -50,8 +50,6 @@ export default class Slider {
|
|
|
50
50
|
}
|
|
51
51
|
const tooltip = (typeof params.tooltip === 'string') ? params.tooltip : (params.tooltip === true ? label : null);
|
|
52
52
|
|
|
53
|
-
this.imageContainer = null;
|
|
54
|
-
|
|
55
53
|
const container = document.createElement('div');
|
|
56
54
|
container.className = 'p-gui__slider';
|
|
57
55
|
|
|
@@ -59,11 +57,13 @@ export default class Slider {
|
|
|
59
57
|
container.setAttribute('title', tooltip);
|
|
60
58
|
}
|
|
61
59
|
|
|
60
|
+
this.parent.wrapper.append(container);
|
|
61
|
+
|
|
62
62
|
const slider_name = document.createElement('div');
|
|
63
63
|
slider_name.className = 'p-gui__slider-name';
|
|
64
64
|
slider_name.textContent = label;
|
|
65
65
|
container.append(slider_name);
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
this.ctrlDiv = document.createElement('div');
|
|
68
68
|
this.ctrlDiv.className = 'p-gui__slider-ctrl';
|
|
69
69
|
this.ctrlDiv.setAttribute('type', 'range');
|
|
@@ -102,7 +102,7 @@ export default class Slider {
|
|
|
102
102
|
this._updateHandlePositionFromValue();
|
|
103
103
|
this._triggerCallbacks();
|
|
104
104
|
})
|
|
105
|
-
|
|
105
|
+
|
|
106
106
|
this.ctrlDiv.addEventListener('pointerdown', (evt) => {
|
|
107
107
|
this.ctrlDiv.pointerDown = true;
|
|
108
108
|
this.ctrlDiv.prevPosition = evt.clientX;
|
|
@@ -114,15 +114,15 @@ export default class Slider {
|
|
|
114
114
|
});
|
|
115
115
|
|
|
116
116
|
window.addEventListener('pointermove', (evt) => {
|
|
117
|
-
if (this.ctrlDiv.pointerDown) {
|
|
117
|
+
if (this.ctrlDiv.pointerDown) {
|
|
118
118
|
this.ctrlDiv.pointerDelta = evt.clientX - this.ctrlDiv.prevPosition;
|
|
119
119
|
this._updateHandlePositionFromPointer(evt);
|
|
120
120
|
}
|
|
121
121
|
});
|
|
122
122
|
|
|
123
|
-
if (
|
|
124
|
-
Object.defineProperty(
|
|
125
|
-
set: val => {
|
|
123
|
+
if (this.isObject) {
|
|
124
|
+
Object.defineProperty(this.obj, this.prop, {
|
|
125
|
+
set: val => {
|
|
126
126
|
this.propReferences[propReferenceIndex] = val;
|
|
127
127
|
this.valueInput.value = val;
|
|
128
128
|
|
|
@@ -130,9 +130,9 @@ export default class Slider {
|
|
|
130
130
|
|
|
131
131
|
if (this.callback) {
|
|
132
132
|
this.callback(parseFloat(this.valueInput.value));
|
|
133
|
-
}
|
|
133
|
+
}
|
|
134
134
|
},
|
|
135
|
-
get: () => {
|
|
135
|
+
get: () => {
|
|
136
136
|
return this.propReferences[propReferenceIndex];
|
|
137
137
|
}
|
|
138
138
|
});
|
|
@@ -147,7 +147,7 @@ export default class Slider {
|
|
|
147
147
|
const pointerDelta = evt.clientX - this.ctrlDiv.prevPosition;
|
|
148
148
|
const currentValue = parseFloat(this.valueInput.value);
|
|
149
149
|
let handlePosition;
|
|
150
|
-
|
|
150
|
+
|
|
151
151
|
if (firstDown) {
|
|
152
152
|
handlePosition = evt.offsetX;
|
|
153
153
|
} else {
|
|
@@ -155,19 +155,19 @@ export default class Slider {
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
handlePosition = Math.max(handleWidth / 2, Math.min(handlePosition, sliderWidth - handleWidth / 2));
|
|
158
|
-
|
|
158
|
+
|
|
159
159
|
let newValue = this.min + (this.max - this.min) * (handlePosition - handleWidth / 2) / (sliderWidth - handleWidth);
|
|
160
|
-
if (
|
|
160
|
+
if (newValue > currentValue) {
|
|
161
161
|
newValue = this._quantizeFloor(newValue, this.step);
|
|
162
162
|
} else {
|
|
163
163
|
newValue = this._quantizeCeil(newValue, this.step);
|
|
164
164
|
}
|
|
165
|
-
|
|
165
|
+
|
|
166
166
|
// toFixed(9) avoids weird javascript infinite decimals
|
|
167
167
|
newValue = parseFloat(newValue.toFixed(9));
|
|
168
168
|
const nextValue = parseFloat((currentValue + this.step).toFixed(9));
|
|
169
169
|
const prevValue = parseFloat((currentValue - this.step).toFixed(9));
|
|
170
|
-
|
|
170
|
+
|
|
171
171
|
if (newValue >= nextValue || newValue <= prevValue) {
|
|
172
172
|
newValue = newValue.toFixed(this.decimals);
|
|
173
173
|
|
|
@@ -179,7 +179,7 @@ export default class Slider {
|
|
|
179
179
|
this.handle.position = handlePosition;
|
|
180
180
|
|
|
181
181
|
this.filling.style.width = this.handle.position + 'px';
|
|
182
|
-
|
|
182
|
+
|
|
183
183
|
this._triggerCallbacks();
|
|
184
184
|
}
|
|
185
185
|
}
|
|
@@ -188,17 +188,17 @@ export default class Slider {
|
|
|
188
188
|
const sliderWidth = this.ctrlDiv.offsetWidth;
|
|
189
189
|
const handleWidth = this.handle.offsetWidth;
|
|
190
190
|
let handlePosition = this._mapLinear(this.valueInput.value, this.min, this.max, handleWidth / 2, sliderWidth - handleWidth / 2);
|
|
191
|
-
|
|
191
|
+
|
|
192
192
|
handlePosition = Math.max(handleWidth / 2, Math.min(handlePosition, sliderWidth - handleWidth / 2));
|
|
193
|
-
|
|
193
|
+
|
|
194
194
|
this.handle.style.transform = `translate(-50%, -50%) translateX(${handlePosition}px)`;
|
|
195
195
|
this.handle.position = handlePosition;
|
|
196
196
|
|
|
197
197
|
this.filling.style.width = this.handle.position + 'px';
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
_triggerCallbacks() {
|
|
201
|
-
if (
|
|
200
|
+
_triggerCallbacks() {
|
|
201
|
+
if (this.isObject) {
|
|
202
202
|
this.obj[this.prop] = parseFloat(this.valueInput.value);
|
|
203
203
|
}
|
|
204
204
|
else {
|
|
@@ -213,9 +213,9 @@ export default class Slider {
|
|
|
213
213
|
this.parent.firstParent.onUpdate();
|
|
214
214
|
}
|
|
215
215
|
}
|
|
216
|
-
|
|
217
|
-
_mapLinear(
|
|
218
|
-
return b1 + (
|
|
216
|
+
|
|
217
|
+
_mapLinear(x, a1, a2, b1, b2) {
|
|
218
|
+
return b1 + (x - a1) * (b2 - b1) / (a2 - a1);
|
|
219
219
|
}
|
|
220
220
|
|
|
221
221
|
_quantize(x, step) {
|