@mulsense/xnew 0.6.1 → 0.6.3
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/dist/xnew.d.ts +38 -31
- package/dist/xnew.js +325 -349
- package/dist/xnew.mjs +325 -349
- package/package.json +1 -1
package/dist/xnew.mjs
CHANGED
|
@@ -207,6 +207,21 @@ class Timer {
|
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
+
function addEvent(target, type, execute, options) {
|
|
211
|
+
let initalized = false;
|
|
212
|
+
const id = setTimeout(() => {
|
|
213
|
+
initalized = true;
|
|
214
|
+
target.addEventListener(type, execute, options);
|
|
215
|
+
}, 0);
|
|
216
|
+
return () => {
|
|
217
|
+
if (initalized === false) {
|
|
218
|
+
clearTimeout(id);
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
target.removeEventListener(type, execute);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
}
|
|
210
225
|
class Eventor {
|
|
211
226
|
constructor() {
|
|
212
227
|
this.map = new MapMap();
|
|
@@ -214,53 +229,62 @@ class Eventor {
|
|
|
214
229
|
add(element, type, listener, options) {
|
|
215
230
|
const props = { element, type, listener, options };
|
|
216
231
|
let finalize;
|
|
217
|
-
if (props.type ===
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
finalize = this.click(props);
|
|
231
|
-
}
|
|
232
|
-
else if (props.type === 'click.outside') {
|
|
233
|
-
finalize = this.click_outside(props);
|
|
234
|
-
}
|
|
235
|
-
else if (['pointerdown', 'pointermove', 'pointerup', 'pointerover', 'pointerout'].includes(props.type)) {
|
|
236
|
-
finalize = this.pointer(props);
|
|
237
|
-
}
|
|
238
|
-
else if (['pointerdown.outside', 'pointermove.outside', 'pointerup.outside'].includes(props.type)) {
|
|
239
|
-
finalize = this.pointer_outside(props);
|
|
240
|
-
}
|
|
241
|
-
else if (['mousedown', 'mousemove', 'mouseup', 'mouseover', 'mouseout'].includes(props.type)) {
|
|
242
|
-
finalize = this.mouse(props);
|
|
243
|
-
}
|
|
244
|
-
else if (['touchstart', 'touchmove', 'touchend', 'touchcancel'].includes(props.type)) {
|
|
245
|
-
finalize = this.touch(props);
|
|
246
|
-
}
|
|
247
|
-
else if (['dragstart', 'dragmove', 'dragend'].includes(props.type)) {
|
|
248
|
-
finalize = this.drag(props);
|
|
249
|
-
}
|
|
250
|
-
else if (['gesturestart', 'gesturemove', 'gestureend'].includes(props.type)) {
|
|
251
|
-
finalize = this.gesture(props);
|
|
252
|
-
}
|
|
253
|
-
else if (['keydown', 'keyup'].includes(props.type)) {
|
|
254
|
-
finalize = this.key(props);
|
|
255
|
-
}
|
|
256
|
-
else if (['keydown.arrow', 'keyup.arrow'].includes(props.type)) {
|
|
257
|
-
finalize = this.key_arrow(props);
|
|
232
|
+
if (props.type.indexOf('window.') === 0) {
|
|
233
|
+
if (['window.keydown', 'window.keyup'].includes(props.type)) {
|
|
234
|
+
finalize = this.window_key(props);
|
|
235
|
+
}
|
|
236
|
+
else if (['window.keydown.arrow', 'window.keyup.arrow'].includes(props.type)) {
|
|
237
|
+
finalize = this.window_key_arrow(props);
|
|
238
|
+
}
|
|
239
|
+
else if (['window.keydown.wasd', 'window.keyup.wasd'].includes(props.type)) {
|
|
240
|
+
finalize = this.window_key_wasd(props);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
finalize = this.window_basic(props);
|
|
244
|
+
}
|
|
258
245
|
}
|
|
259
|
-
else if (
|
|
260
|
-
|
|
246
|
+
else if (props.type.indexOf('document.') === 0) {
|
|
247
|
+
{
|
|
248
|
+
finalize = this.document_basic(props);
|
|
249
|
+
}
|
|
261
250
|
}
|
|
262
251
|
else {
|
|
263
|
-
|
|
252
|
+
if (props.type === 'resize') {
|
|
253
|
+
finalize = this.element_resize(props);
|
|
254
|
+
}
|
|
255
|
+
else if (props.type === 'change') {
|
|
256
|
+
finalize = this.element_change(props);
|
|
257
|
+
}
|
|
258
|
+
else if (props.type === 'input') {
|
|
259
|
+
finalize = this.element_input(props);
|
|
260
|
+
}
|
|
261
|
+
else if (props.type === 'wheel') {
|
|
262
|
+
finalize = this.element_wheel(props);
|
|
263
|
+
}
|
|
264
|
+
else if (props.type === 'click') {
|
|
265
|
+
finalize = this.element_click(props);
|
|
266
|
+
}
|
|
267
|
+
else if (props.type === 'click.outside') {
|
|
268
|
+
finalize = this.element_click_outside(props);
|
|
269
|
+
}
|
|
270
|
+
else if (['pointerdown', 'pointermove', 'pointerup', 'pointerover', 'pointerout'].includes(props.type)) {
|
|
271
|
+
finalize = this.element_pointer(props);
|
|
272
|
+
}
|
|
273
|
+
else if (['pointerdown.outside', 'pointermove.outside', 'pointerup.outside'].includes(props.type)) {
|
|
274
|
+
finalize = this.element_pointer_outside(props);
|
|
275
|
+
}
|
|
276
|
+
else if (['mousedown', 'mousemove', 'mouseup', 'mouseover', 'mouseout'].includes(props.type)) {
|
|
277
|
+
finalize = this.element_mouse(props);
|
|
278
|
+
}
|
|
279
|
+
else if (['touchstart', 'touchmove', 'touchend', 'touchcancel'].includes(props.type)) {
|
|
280
|
+
finalize = this.element_touch(props);
|
|
281
|
+
}
|
|
282
|
+
else if (['dragstart', 'dragmove', 'dragend'].includes(props.type)) {
|
|
283
|
+
finalize = this.element_drag(props);
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
finalize = this.element_basic(props);
|
|
287
|
+
}
|
|
264
288
|
}
|
|
265
289
|
this.map.set(props.type, props.listener, finalize);
|
|
266
290
|
}
|
|
@@ -271,16 +295,12 @@ class Eventor {
|
|
|
271
295
|
this.map.delete(type, listener);
|
|
272
296
|
}
|
|
273
297
|
}
|
|
274
|
-
|
|
275
|
-
|
|
298
|
+
element_basic(props) {
|
|
299
|
+
return addEvent(props.element, props.type, (event) => {
|
|
276
300
|
props.listener({ event });
|
|
277
|
-
};
|
|
278
|
-
props.element.addEventListener(props.type, execute, props.options);
|
|
279
|
-
return () => {
|
|
280
|
-
props.element.removeEventListener(props.type, execute);
|
|
281
|
-
};
|
|
301
|
+
}, props.options);
|
|
282
302
|
}
|
|
283
|
-
|
|
303
|
+
element_resize(props) {
|
|
284
304
|
const observer = new ResizeObserver((entries) => {
|
|
285
305
|
for (const entry of entries) {
|
|
286
306
|
props.listener({});
|
|
@@ -292,8 +312,8 @@ class Eventor {
|
|
|
292
312
|
observer.unobserve(props.element);
|
|
293
313
|
};
|
|
294
314
|
}
|
|
295
|
-
|
|
296
|
-
|
|
315
|
+
element_change(props) {
|
|
316
|
+
return addEvent(props.element, props.type, (event) => {
|
|
297
317
|
let value = null;
|
|
298
318
|
if (event.target.type === 'checkbox') {
|
|
299
319
|
value = event.target.checked;
|
|
@@ -305,14 +325,10 @@ class Eventor {
|
|
|
305
325
|
value = event.target.value;
|
|
306
326
|
}
|
|
307
327
|
props.listener({ event, value });
|
|
308
|
-
};
|
|
309
|
-
props.element.addEventListener(props.type, execute, props.options);
|
|
310
|
-
return () => {
|
|
311
|
-
props.element.removeEventListener(props.type, execute);
|
|
312
|
-
};
|
|
328
|
+
}, props.options);
|
|
313
329
|
}
|
|
314
|
-
|
|
315
|
-
|
|
330
|
+
element_input(props) {
|
|
331
|
+
return addEvent(props.element, props.type, (event) => {
|
|
316
332
|
let value = null;
|
|
317
333
|
if (event.target.type === 'checkbox') {
|
|
318
334
|
value = event.target.checked;
|
|
@@ -324,88 +340,56 @@ class Eventor {
|
|
|
324
340
|
value = event.target.value;
|
|
325
341
|
}
|
|
326
342
|
props.listener({ event, value });
|
|
327
|
-
};
|
|
328
|
-
props.element.addEventListener(props.type, execute, props.options);
|
|
329
|
-
return () => {
|
|
330
|
-
props.element.removeEventListener(props.type, execute);
|
|
331
|
-
};
|
|
343
|
+
}, props.options);
|
|
332
344
|
}
|
|
333
|
-
|
|
334
|
-
|
|
345
|
+
element_click(props) {
|
|
346
|
+
return addEvent(props.element, props.type, (event) => {
|
|
335
347
|
props.listener({ event, position: pointer(props.element, event).position });
|
|
336
|
-
};
|
|
337
|
-
props.element.addEventListener(props.type, execute, props.options);
|
|
338
|
-
return () => {
|
|
339
|
-
props.element.removeEventListener(props.type, execute);
|
|
340
|
-
};
|
|
348
|
+
}, props.options);
|
|
341
349
|
}
|
|
342
|
-
|
|
343
|
-
|
|
350
|
+
element_click_outside(props) {
|
|
351
|
+
return addEvent(document, props.type.split('.')[0], (event) => {
|
|
344
352
|
if (props.element.contains(event.target) === false) {
|
|
345
353
|
props.listener({ event, position: pointer(props.element, event).position });
|
|
346
354
|
}
|
|
347
|
-
};
|
|
348
|
-
document.addEventListener(props.type.split('.')[0], execute, props.options);
|
|
349
|
-
return () => {
|
|
350
|
-
document.removeEventListener(props.type.split('.')[0], execute);
|
|
351
|
-
};
|
|
355
|
+
}, props.options);
|
|
352
356
|
}
|
|
353
|
-
|
|
354
|
-
|
|
357
|
+
element_pointer(props) {
|
|
358
|
+
return addEvent(props.element, props.type, (event) => {
|
|
355
359
|
props.listener({ event, position: pointer(props.element, event).position });
|
|
356
|
-
};
|
|
357
|
-
props.element.addEventListener(props.type, execute, props.options);
|
|
358
|
-
return () => {
|
|
359
|
-
props.element.removeEventListener(props.type, execute);
|
|
360
|
-
};
|
|
360
|
+
}, props.options);
|
|
361
361
|
}
|
|
362
|
-
|
|
363
|
-
|
|
362
|
+
element_mouse(props) {
|
|
363
|
+
return addEvent(props.element, props.type, (event) => {
|
|
364
364
|
props.listener({ event, position: pointer(props.element, event).position });
|
|
365
|
-
};
|
|
366
|
-
props.element.addEventListener(props.type, execute, props.options);
|
|
367
|
-
return () => {
|
|
368
|
-
props.element.removeEventListener(props.type, execute);
|
|
369
|
-
};
|
|
365
|
+
}, props.options);
|
|
370
366
|
}
|
|
371
|
-
|
|
372
|
-
|
|
367
|
+
element_touch(props) {
|
|
368
|
+
return addEvent(props.element, props.type, (event) => {
|
|
373
369
|
props.listener({ event, position: pointer(props.element, event).position });
|
|
374
|
-
};
|
|
375
|
-
props.element.addEventListener(props.type, execute, props.options);
|
|
376
|
-
return () => {
|
|
377
|
-
props.element.removeEventListener(props.type, execute);
|
|
378
|
-
};
|
|
370
|
+
}, props.options);
|
|
379
371
|
}
|
|
380
|
-
|
|
381
|
-
|
|
372
|
+
element_pointer_outside(props) {
|
|
373
|
+
return addEvent(document, props.type.split('.')[0], (event) => {
|
|
382
374
|
if (props.element.contains(event.target) === false) {
|
|
383
375
|
props.listener({ event, position: pointer(props.element, event).position });
|
|
384
376
|
}
|
|
385
|
-
};
|
|
386
|
-
document.addEventListener(props.type.split('.')[0], execute, props.options);
|
|
387
|
-
return () => {
|
|
388
|
-
document.removeEventListener(props.type.split('.')[0], execute);
|
|
389
|
-
};
|
|
377
|
+
}, props.options);
|
|
390
378
|
}
|
|
391
|
-
|
|
392
|
-
|
|
379
|
+
element_wheel(props) {
|
|
380
|
+
return addEvent(props.element, props.type, (event) => {
|
|
393
381
|
props.listener({ event, delta: { x: event.wheelDeltaX, y: event.wheelDeltaY } });
|
|
394
|
-
};
|
|
395
|
-
props.element.addEventListener(props.type, execute, props.options);
|
|
396
|
-
return () => {
|
|
397
|
-
props.element.removeEventListener(props.type, execute);
|
|
398
|
-
};
|
|
382
|
+
}, props.options);
|
|
399
383
|
}
|
|
400
|
-
|
|
384
|
+
element_drag(props) {
|
|
401
385
|
let pointermove = null;
|
|
402
386
|
let pointerup = null;
|
|
403
387
|
let pointercancel = null;
|
|
404
|
-
const pointerdown = (event) => {
|
|
388
|
+
const pointerdown = addEvent(props.element, 'pointerdown', (event) => {
|
|
405
389
|
const id = event.pointerId;
|
|
406
390
|
const position = pointer(props.element, event).position;
|
|
407
391
|
let previous = position;
|
|
408
|
-
pointermove = (event) => {
|
|
392
|
+
pointermove = addEvent(window, 'pointermove', (event) => {
|
|
409
393
|
if (event.pointerId === id) {
|
|
410
394
|
const position = pointer(props.element, event).position;
|
|
411
395
|
const delta = { x: position.x - previous.x, y: position.y - previous.y };
|
|
@@ -414,8 +398,8 @@ class Eventor {
|
|
|
414
398
|
}
|
|
415
399
|
previous = position;
|
|
416
400
|
}
|
|
417
|
-
};
|
|
418
|
-
pointerup = (event) => {
|
|
401
|
+
}, props.options);
|
|
402
|
+
pointerup = addEvent(window, 'pointerup', (event) => {
|
|
419
403
|
if (event.pointerId === id) {
|
|
420
404
|
const position = pointer(props.element, event).position;
|
|
421
405
|
if (props.type === 'dragend') {
|
|
@@ -423,8 +407,8 @@ class Eventor {
|
|
|
423
407
|
}
|
|
424
408
|
remove();
|
|
425
409
|
}
|
|
426
|
-
};
|
|
427
|
-
pointercancel = (event) => {
|
|
410
|
+
}, props.options);
|
|
411
|
+
pointercancel = addEvent(window, 'pointercancel', (event) => {
|
|
428
412
|
if (event.pointerId === id) {
|
|
429
413
|
const position = pointer(props.element, event).position;
|
|
430
414
|
if (props.type === 'dragend') {
|
|
@@ -432,168 +416,102 @@ class Eventor {
|
|
|
432
416
|
}
|
|
433
417
|
remove();
|
|
434
418
|
}
|
|
435
|
-
};
|
|
436
|
-
window.addEventListener('pointermove', pointermove);
|
|
437
|
-
window.addEventListener('pointerup', pointerup);
|
|
438
|
-
window.addEventListener('pointercancel', pointercancel);
|
|
419
|
+
}, props.options);
|
|
439
420
|
if (props.type === 'dragstart') {
|
|
440
421
|
props.listener({ event, position, delta: { x: 0, y: 0 } });
|
|
441
422
|
}
|
|
442
|
-
};
|
|
423
|
+
}, props.options);
|
|
443
424
|
function remove() {
|
|
444
|
-
|
|
445
|
-
window.removeEventListener('pointermove', pointermove);
|
|
446
|
-
if (pointerup)
|
|
447
|
-
window.removeEventListener('pointerup', pointerup);
|
|
448
|
-
if (pointercancel)
|
|
449
|
-
window.removeEventListener('pointercancel', pointercancel);
|
|
425
|
+
pointermove === null || pointermove === void 0 ? void 0 : pointermove();
|
|
450
426
|
pointermove = null;
|
|
427
|
+
pointerup === null || pointerup === void 0 ? void 0 : pointerup();
|
|
451
428
|
pointerup = null;
|
|
429
|
+
pointercancel === null || pointercancel === void 0 ? void 0 : pointercancel();
|
|
452
430
|
pointercancel = null;
|
|
453
431
|
}
|
|
454
|
-
props.element.addEventListener('pointerdown', pointerdown, props.options);
|
|
455
432
|
return () => {
|
|
456
|
-
|
|
433
|
+
pointerdown();
|
|
457
434
|
remove();
|
|
458
435
|
};
|
|
459
436
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
const dragstart = ({ event, position }) => {
|
|
466
|
-
map.set(event.pointerId, position);
|
|
467
|
-
isActive = map.size === 2 ? true : false;
|
|
468
|
-
if (isActive === true && props.type === 'gesturestart') {
|
|
469
|
-
props.listener({ event });
|
|
470
|
-
}
|
|
471
|
-
};
|
|
472
|
-
const dragmove = ({ event, position, delta }) => {
|
|
473
|
-
if (map.size >= 2 && isActive === true) {
|
|
474
|
-
const a = map.get(event.pointerId);
|
|
475
|
-
const b = getOthers(event.pointerId)[0];
|
|
476
|
-
let scale = 0.0;
|
|
477
|
-
{
|
|
478
|
-
const v = { x: a.x - b.x, y: a.y - b.y };
|
|
479
|
-
const s = v.x * v.x + v.y * v.y;
|
|
480
|
-
scale = 1 + (s > 0.0 ? (v.x * delta.x + v.y * delta.y) / s : 0);
|
|
481
|
-
}
|
|
482
|
-
// let rotate = 0.0;
|
|
483
|
-
// {
|
|
484
|
-
// const c = { x: a.x + delta.x, y: a.y + delta.y };
|
|
485
|
-
// const v1 = { x: a.x - b.x, y: a.y - b.y };
|
|
486
|
-
// const v2 = { x: c.x - b.x, y: c.y - b.y };
|
|
487
|
-
// const l1 = Math.sqrt(v1.x * v1.x + v1.y * v1.y);
|
|
488
|
-
// const l2 = Math.sqrt(v2.x * v2.x + v2.y * v2.y);
|
|
489
|
-
// if (l1 > 0.0 && l2 > 0.0) {
|
|
490
|
-
// const angle = Math.acos((v1.x * v2.x + v1.y * v2.y) / (l1 * l2));
|
|
491
|
-
// const sign = v1.x * v2.y - v1.y * v2.x;
|
|
492
|
-
// rotate = sign > 0.0 ? +angle : -angle;
|
|
493
|
-
// }
|
|
494
|
-
// }
|
|
495
|
-
if (props.type === 'gesturemove') {
|
|
496
|
-
props.listener({ event, scale });
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
map.set(event.pointerId, position);
|
|
500
|
-
};
|
|
501
|
-
const dragend = ({ event }) => {
|
|
502
|
-
map.delete(event.pointerId);
|
|
503
|
-
if (isActive === true && props.type === 'gestureend') {
|
|
504
|
-
props.listener({ event, scale: 1.0 });
|
|
505
|
-
}
|
|
506
|
-
isActive = false;
|
|
507
|
-
};
|
|
508
|
-
this.add(element, 'dragstart', dragstart, options);
|
|
509
|
-
this.add(element, 'dragmove', dragmove, options);
|
|
510
|
-
this.add(element, 'dragend', dragend, options);
|
|
511
|
-
function getOthers(id) {
|
|
512
|
-
const backup = map.get(id);
|
|
513
|
-
map.delete(id);
|
|
514
|
-
const others = [...map.values()];
|
|
515
|
-
map.set(id, backup);
|
|
516
|
-
return others;
|
|
517
|
-
}
|
|
518
|
-
return () => {
|
|
519
|
-
this.remove('dragstart', dragstart);
|
|
520
|
-
this.remove('dragmove', dragmove);
|
|
521
|
-
this.remove('dragend', dragend);
|
|
522
|
-
};
|
|
437
|
+
window_basic(props) {
|
|
438
|
+
const type = props.type.substring('window.'.length);
|
|
439
|
+
return addEvent(window, type, (event) => {
|
|
440
|
+
props.listener({ event });
|
|
441
|
+
}, props.options);
|
|
523
442
|
}
|
|
524
|
-
|
|
525
|
-
const
|
|
526
|
-
|
|
443
|
+
window_key(props) {
|
|
444
|
+
const type = props.type.substring(props.type.indexOf('.') + 1);
|
|
445
|
+
return addEvent(window, type, (event) => {
|
|
446
|
+
if (event.repeat)
|
|
527
447
|
return;
|
|
528
448
|
props.listener({ event, code: event.code });
|
|
529
|
-
};
|
|
530
|
-
window.addEventListener(props.type, execute, props.options);
|
|
531
|
-
return () => {
|
|
532
|
-
window.removeEventListener(props.type, execute);
|
|
533
|
-
};
|
|
449
|
+
}, props.options);
|
|
534
450
|
}
|
|
535
|
-
|
|
451
|
+
window_key_arrow(props) {
|
|
536
452
|
const keymap = {};
|
|
537
|
-
const keydown = (event) => {
|
|
453
|
+
const keydown = addEvent(window, 'keydown', (event) => {
|
|
538
454
|
if (event.repeat)
|
|
539
455
|
return;
|
|
540
456
|
keymap[event.code] = 1;
|
|
541
|
-
if (props.type === 'keydown.arrow' && ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) {
|
|
457
|
+
if (props.type === 'window.keydown.arrow' && ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) {
|
|
542
458
|
const vector = {
|
|
543
459
|
x: (keymap['ArrowLeft'] ? -1 : 0) + (keymap['ArrowRight'] ? +1 : 0),
|
|
544
460
|
y: (keymap['ArrowUp'] ? -1 : 0) + (keymap['ArrowDown'] ? +1 : 0)
|
|
545
461
|
};
|
|
546
462
|
props.listener({ event, code: event.code, vector });
|
|
547
463
|
}
|
|
548
|
-
};
|
|
549
|
-
const keyup = (event) => {
|
|
464
|
+
}, props.options);
|
|
465
|
+
const keyup = addEvent(window, 'keyup', (event) => {
|
|
550
466
|
keymap[event.code] = 0;
|
|
551
|
-
if (props.type === 'keyup.arrow' && ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) {
|
|
467
|
+
if (props.type === 'window.keyup.arrow' && ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) {
|
|
552
468
|
const vector = {
|
|
553
469
|
x: (keymap['ArrowLeft'] ? -1 : 0) + (keymap['ArrowRight'] ? +1 : 0),
|
|
554
470
|
y: (keymap['ArrowUp'] ? -1 : 0) + (keymap['ArrowDown'] ? +1 : 0)
|
|
555
471
|
};
|
|
556
472
|
props.listener({ event, code: event.code, vector });
|
|
557
473
|
}
|
|
558
|
-
};
|
|
559
|
-
window.addEventListener('keydown', keydown, props.options);
|
|
560
|
-
window.addEventListener('keyup', keyup, props.options);
|
|
474
|
+
}, props.options);
|
|
561
475
|
return () => {
|
|
562
|
-
|
|
563
|
-
|
|
476
|
+
keydown();
|
|
477
|
+
keyup();
|
|
564
478
|
};
|
|
565
479
|
}
|
|
566
|
-
|
|
480
|
+
window_key_wasd(props) {
|
|
567
481
|
const keymap = {};
|
|
568
|
-
const
|
|
482
|
+
const finalize1 = addEvent(window, 'keydown', (event) => {
|
|
569
483
|
if (event.repeat)
|
|
570
484
|
return;
|
|
571
485
|
keymap[event.code] = 1;
|
|
572
|
-
if (props.type === 'keydown.wasd' && ['KeyW', 'KeyA', 'KeyS', 'KeyD'].includes(event.code)) {
|
|
486
|
+
if (props.type === 'window.keydown.wasd' && ['KeyW', 'KeyA', 'KeyS', 'KeyD'].includes(event.code)) {
|
|
573
487
|
const vector = {
|
|
574
488
|
x: (keymap['KeyA'] ? -1 : 0) + (keymap['KeyD'] ? +1 : 0),
|
|
575
489
|
y: (keymap['KeyW'] ? -1 : 0) + (keymap['KeyS'] ? +1 : 0)
|
|
576
490
|
};
|
|
577
491
|
props.listener({ event, code: event.code, vector });
|
|
578
492
|
}
|
|
579
|
-
};
|
|
580
|
-
const
|
|
493
|
+
}, props.options);
|
|
494
|
+
const finalize2 = addEvent(window, 'keyup', (event) => {
|
|
581
495
|
keymap[event.code] = 0;
|
|
582
|
-
if (props.type === 'keyup.wasd' && ['KeyW', 'KeyA', 'KeyS', 'KeyD'].includes(event.code)) {
|
|
496
|
+
if (props.type === 'window.keyup.wasd' && ['KeyW', 'KeyA', 'KeyS', 'KeyD'].includes(event.code)) {
|
|
583
497
|
const vector = {
|
|
584
498
|
x: (keymap['KeyA'] ? -1 : 0) + (keymap['KeyD'] ? +1 : 0),
|
|
585
499
|
y: (keymap['KeyW'] ? -1 : 0) + (keymap['KeyS'] ? +1 : 0)
|
|
586
500
|
};
|
|
587
501
|
props.listener({ event, code: event.code, vector });
|
|
588
502
|
}
|
|
589
|
-
};
|
|
590
|
-
window.addEventListener('keydown', keydown, props.options);
|
|
591
|
-
window.addEventListener('keyup', keyup, props.options);
|
|
503
|
+
}, props.options);
|
|
592
504
|
return () => {
|
|
593
|
-
|
|
594
|
-
|
|
505
|
+
finalize1();
|
|
506
|
+
finalize2();
|
|
595
507
|
};
|
|
596
508
|
}
|
|
509
|
+
document_basic(props) {
|
|
510
|
+
const type = props.type.substring('document.'.length);
|
|
511
|
+
return addEvent(document, type, (event) => {
|
|
512
|
+
props.listener({ event });
|
|
513
|
+
}, props.options);
|
|
514
|
+
}
|
|
597
515
|
}
|
|
598
516
|
function pointer(element, event) {
|
|
599
517
|
const rect = element.getBoundingClientRect();
|
|
@@ -713,7 +631,7 @@ class Unit {
|
|
|
713
631
|
baseComponent = (unit) => { };
|
|
714
632
|
}
|
|
715
633
|
const baseContext = (_a = parent === null || parent === void 0 ? void 0 : parent._.currentContext) !== null && _a !== void 0 ? _a : { stack: null };
|
|
716
|
-
this._ = { parent, target, baseElement, baseContext, baseComponent, props
|
|
634
|
+
this._ = { parent, target, baseElement, baseContext, baseComponent, props };
|
|
717
635
|
parent === null || parent === void 0 ? void 0 : parent._.children.push(this);
|
|
718
636
|
Unit.initialize(this, null);
|
|
719
637
|
}
|
|
@@ -735,8 +653,10 @@ class Unit {
|
|
|
735
653
|
}
|
|
736
654
|
}
|
|
737
655
|
reboot() {
|
|
738
|
-
|
|
739
|
-
|
|
656
|
+
let anchor = null;
|
|
657
|
+
if (this._.nestElements[0] && this._.nestElements[0].owned === true) {
|
|
658
|
+
anchor = this._.nestElements[0].element.nextElementSibling;
|
|
659
|
+
}
|
|
740
660
|
Unit.stop(this);
|
|
741
661
|
Unit.finalize(this);
|
|
742
662
|
Unit.initialize(this, anchor);
|
|
@@ -754,7 +674,7 @@ class Unit {
|
|
|
754
674
|
protected: false,
|
|
755
675
|
ancestors: unit._.parent ? [unit._.parent, ...unit._.parent._.ancestors] : [],
|
|
756
676
|
children: [],
|
|
757
|
-
|
|
677
|
+
nestElements: [],
|
|
758
678
|
promises: [],
|
|
759
679
|
components: [],
|
|
760
680
|
listeners: new MapMap(),
|
|
@@ -779,10 +699,12 @@ class Unit {
|
|
|
779
699
|
[...unit._.systems.finalize].reverse().forEach(({ execute }) => execute());
|
|
780
700
|
unit.off();
|
|
781
701
|
unit._.components.forEach((component) => Unit.component2units.delete(component, unit));
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
702
|
+
for (const { element, owned } of unit._.nestElements.reverse()) {
|
|
703
|
+
if (owned === true) {
|
|
704
|
+
element.remove();
|
|
705
|
+
}
|
|
785
706
|
}
|
|
707
|
+
unit._.currentElement = unit._.baseElement;
|
|
786
708
|
// reset defines
|
|
787
709
|
Object.keys(unit._.defines).forEach((key) => {
|
|
788
710
|
delete unit[key];
|
|
@@ -791,28 +713,35 @@ class Unit {
|
|
|
791
713
|
unit._.state = 'finalized';
|
|
792
714
|
}
|
|
793
715
|
}
|
|
794
|
-
static nest(unit,
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
716
|
+
static nest(unit, target, textContent) {
|
|
717
|
+
if (target instanceof HTMLElement || target instanceof SVGElement) {
|
|
718
|
+
unit._.nestElements.push({ element: target, owned: false });
|
|
719
|
+
unit._.currentElement = target;
|
|
720
|
+
return target;
|
|
721
|
+
}
|
|
722
|
+
else {
|
|
723
|
+
const match = target.match(/<((\w+)[^>]*?)\/?>/);
|
|
724
|
+
if (match !== null) {
|
|
725
|
+
let element;
|
|
726
|
+
if (unit._.anchor !== null) {
|
|
727
|
+
unit._.anchor.insertAdjacentHTML('beforebegin', `<${match[1]}></${match[2]}>`);
|
|
728
|
+
element = unit._.anchor.previousElementSibling;
|
|
729
|
+
unit._.anchor = null;
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
unit._.currentElement.insertAdjacentHTML('beforeend', `<${match[1]}></${match[2]}>`);
|
|
733
|
+
element = unit._.currentElement.children[unit._.currentElement.children.length - 1];
|
|
734
|
+
}
|
|
735
|
+
unit._.currentElement = element;
|
|
736
|
+
if (textContent !== undefined) {
|
|
737
|
+
element.textContent = textContent.toString();
|
|
738
|
+
}
|
|
739
|
+
unit._.nestElements.push({ element, owned: true });
|
|
740
|
+
return element;
|
|
802
741
|
}
|
|
803
742
|
else {
|
|
804
|
-
|
|
805
|
-
element = unit._.currentElement.children[unit._.currentElement.children.length - 1];
|
|
743
|
+
throw new Error(`xnew.nest: invalid html string [${target}]`);
|
|
806
744
|
}
|
|
807
|
-
unit._.currentElement = element;
|
|
808
|
-
if (textContent !== undefined) {
|
|
809
|
-
element.textContent = textContent.toString();
|
|
810
|
-
}
|
|
811
|
-
unit._.elements.push(element);
|
|
812
|
-
return element;
|
|
813
|
-
}
|
|
814
|
-
else {
|
|
815
|
-
throw new Error(`xnew.nest: invalid html string [${tag}]`);
|
|
816
745
|
}
|
|
817
746
|
}
|
|
818
747
|
static extend(unit, component, props) {
|
|
@@ -823,7 +752,7 @@ class Unit {
|
|
|
823
752
|
else {
|
|
824
753
|
const backupComponent = unit._.currentComponent;
|
|
825
754
|
unit._.currentComponent = component;
|
|
826
|
-
const defines = (_a = component(unit, props)) !== null && _a !== void 0 ? _a : {};
|
|
755
|
+
const defines = (_a = component(unit, props !== null && props !== void 0 ? props : {})) !== null && _a !== void 0 ? _a : {};
|
|
827
756
|
unit._.currentComponent = backupComponent;
|
|
828
757
|
Unit.component2units.add(component, unit);
|
|
829
758
|
unit._.components.push(component);
|
|
@@ -1023,22 +952,22 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
1023
952
|
}, {
|
|
1024
953
|
/**
|
|
1025
954
|
* Creates a nested HTML/SVG element within the current component
|
|
1026
|
-
* @param
|
|
955
|
+
* @param target - HTML or SVG tag string (e.g., '<div class="my-class">', '<span style="color:red">', '<svg viewBox="0 0 24 24">')
|
|
1027
956
|
* @returns The created HTML/SVG element
|
|
1028
957
|
* @throws Error if called after component initialization
|
|
1029
958
|
* @example
|
|
1030
959
|
* const div = xnew.nest('<div>')
|
|
1031
960
|
* div.textContent = 'Hello'
|
|
1032
961
|
*/
|
|
1033
|
-
nest(
|
|
962
|
+
nest(target) {
|
|
1034
963
|
try {
|
|
1035
964
|
if (Unit.currentUnit._.state !== 'invoked') {
|
|
1036
965
|
throw new Error('xnew.nest can not be called after initialized.');
|
|
1037
966
|
}
|
|
1038
|
-
return Unit.nest(Unit.currentUnit,
|
|
967
|
+
return Unit.nest(Unit.currentUnit, target);
|
|
1039
968
|
}
|
|
1040
969
|
catch (error) {
|
|
1041
|
-
console.error('xnew.nest(
|
|
970
|
+
console.error('xnew.nest(target: HTMLElement | SVGElement | string): ', error);
|
|
1042
971
|
throw error;
|
|
1043
972
|
}
|
|
1044
973
|
},
|
|
@@ -1058,7 +987,8 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
1058
987
|
}
|
|
1059
988
|
const defines = Unit.extend(Unit.currentUnit, component, props);
|
|
1060
989
|
if (typeof component === 'function') {
|
|
1061
|
-
|
|
990
|
+
Unit.context(Unit.currentUnit, component, Unit.currentUnit);
|
|
991
|
+
Unit.context(Unit.currentUnit._.parent, component, Unit.currentUnit);
|
|
1062
992
|
}
|
|
1063
993
|
return defines;
|
|
1064
994
|
}
|
|
@@ -1267,48 +1197,39 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
1267
1197
|
},
|
|
1268
1198
|
});
|
|
1269
1199
|
|
|
1270
|
-
function OpenAndClose(unit, { open =
|
|
1200
|
+
function OpenAndClose(unit, { open = true, transition = { duration: 200, easing: 'ease' } }) {
|
|
1271
1201
|
let state = open ? 1.0 : 0.0;
|
|
1272
|
-
let
|
|
1202
|
+
let sign = open ? +1 : -1;
|
|
1273
1203
|
let timer = xnew$1.timeout(() => xnew$1.emit('-transition', { state }));
|
|
1274
1204
|
return {
|
|
1275
|
-
toggle(
|
|
1276
|
-
|
|
1277
|
-
unit.open(duration, easing);
|
|
1278
|
-
}
|
|
1279
|
-
else {
|
|
1280
|
-
unit.close(duration, easing);
|
|
1281
|
-
}
|
|
1205
|
+
toggle() {
|
|
1206
|
+
sign < 0 ? unit.open() : unit.close();
|
|
1282
1207
|
},
|
|
1283
|
-
open(
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
});
|
|
1296
|
-
}
|
|
1208
|
+
open() {
|
|
1209
|
+
var _a, _b;
|
|
1210
|
+
sign = +1;
|
|
1211
|
+
const d = 1 - state;
|
|
1212
|
+
const duration = ((_a = transition === null || transition === void 0 ? void 0 : transition.duration) !== null && _a !== void 0 ? _a : 200) * d;
|
|
1213
|
+
const easing = (_b = transition === null || transition === void 0 ? void 0 : transition.easing) !== null && _b !== void 0 ? _b : 'ease';
|
|
1214
|
+
timer === null || timer === void 0 ? void 0 : timer.clear();
|
|
1215
|
+
timer = xnew$1.transition((x) => {
|
|
1216
|
+
state = 1.0 - (x < 1.0 ? (1 - x) * d : 0.0);
|
|
1217
|
+
xnew$1.emit('-transition', { state });
|
|
1218
|
+
}, duration, easing)
|
|
1219
|
+
.timeout(() => xnew$1.emit('-opened', { state }));
|
|
1297
1220
|
},
|
|
1298
|
-
close(
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
});
|
|
1311
|
-
}
|
|
1221
|
+
close() {
|
|
1222
|
+
var _a, _b;
|
|
1223
|
+
sign = -1;
|
|
1224
|
+
const d = state;
|
|
1225
|
+
const duration = ((_a = transition === null || transition === void 0 ? void 0 : transition.duration) !== null && _a !== void 0 ? _a : 200) * d;
|
|
1226
|
+
const easing = (_b = transition === null || transition === void 0 ? void 0 : transition.easing) !== null && _b !== void 0 ? _b : 'ease';
|
|
1227
|
+
timer === null || timer === void 0 ? void 0 : timer.clear();
|
|
1228
|
+
timer = xnew$1.transition((x) => {
|
|
1229
|
+
state = x < 1.0 ? (1 - x) * d : 0.0;
|
|
1230
|
+
xnew$1.emit('-transition', { state });
|
|
1231
|
+
}, duration, easing)
|
|
1232
|
+
.timeout(() => xnew$1.emit('-closed', { state }));
|
|
1312
1233
|
},
|
|
1313
1234
|
};
|
|
1314
1235
|
}
|
|
@@ -1321,17 +1242,14 @@ function Accordion(unit) {
|
|
|
1321
1242
|
outer.style.opacity = state.toString();
|
|
1322
1243
|
});
|
|
1323
1244
|
}
|
|
1324
|
-
function
|
|
1245
|
+
function Popup(unit) {
|
|
1325
1246
|
const system = xnew$1.context(OpenAndClose);
|
|
1326
1247
|
system.on('-closed', () => unit.finalize());
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
xnew$1.nest('<div style="position: absolute; inset: 0; margin: auto; width: max-content; height: max-content;">');
|
|
1331
|
-
unit.on('click', ({ event }) => event.stopPropagation());
|
|
1332
|
-
outer.style.background = background;
|
|
1248
|
+
system.open();
|
|
1249
|
+
xnew$1.nest('<div style="position: fixed; inset: 0; z-index: 1000; opacity: 0;">');
|
|
1250
|
+
unit.on('click', ({ event }) => event.target === unit.element && system.close());
|
|
1333
1251
|
system.on('-transition', ({ state }) => {
|
|
1334
|
-
|
|
1252
|
+
unit.element.style.opacity = state.toString();
|
|
1335
1253
|
});
|
|
1336
1254
|
}
|
|
1337
1255
|
|
|
@@ -1383,7 +1301,7 @@ function AnalogStick(unit, { stroke = 'currentColor', strokeOpacity = 0.8, strok
|
|
|
1383
1301
|
target.element.style.left = `${vector.x * size / 4}px`;
|
|
1384
1302
|
target.element.style.top = `${vector.y * size / 4}px`;
|
|
1385
1303
|
const nexttype = { dragstart: '-down', dragmove: '-move' }[type];
|
|
1386
|
-
xnew$1.emit(nexttype, {
|
|
1304
|
+
xnew$1.emit(nexttype, { vector });
|
|
1387
1305
|
});
|
|
1388
1306
|
unit.on('dragend', () => {
|
|
1389
1307
|
const size = unit.element.clientWidth;
|
|
@@ -1391,7 +1309,7 @@ function AnalogStick(unit, { stroke = 'currentColor', strokeOpacity = 0.8, strok
|
|
|
1391
1309
|
target.element.style.filter = '';
|
|
1392
1310
|
target.element.style.left = `${vector.x * size / 4}px`;
|
|
1393
1311
|
target.element.style.top = `${vector.y * size / 4}px`;
|
|
1394
|
-
xnew$1.emit('-up', {
|
|
1312
|
+
xnew$1.emit('-up', { vector });
|
|
1395
1313
|
});
|
|
1396
1314
|
}
|
|
1397
1315
|
function DPad(unit, { diagonal = true, stroke = 'currentColor', strokeOpacity = 0.8, strokeWidth = 1, strokeLinejoin = 'round', fill = '#FFF', fillOpacity = 0.8 } = {}) {
|
|
@@ -1456,54 +1374,42 @@ function DPad(unit, { diagonal = true, stroke = 'currentColor', strokeOpacity =
|
|
|
1456
1374
|
});
|
|
1457
1375
|
}
|
|
1458
1376
|
|
|
1459
|
-
|
|
1377
|
+
const currentColorA = 'color-mix(in srgb, currentColor 70%, transparent)';
|
|
1378
|
+
const currentColorB = 'color-mix(in srgb, currentColor 10%, transparent)';
|
|
1379
|
+
function Panel(unit, { name, open = false, params }) {
|
|
1460
1380
|
const object = params !== null && params !== void 0 ? params : {};
|
|
1461
1381
|
xnew$1.extend(Group, { name, open });
|
|
1462
1382
|
return {
|
|
1463
1383
|
group({ name, open, params }, inner) {
|
|
1464
1384
|
const group = xnew$1((unit) => {
|
|
1465
|
-
xnew$1.extend(
|
|
1385
|
+
xnew$1.extend(Panel, { name, open, params: params !== null && params !== void 0 ? params : object });
|
|
1466
1386
|
inner(unit);
|
|
1467
1387
|
});
|
|
1468
|
-
group.on('-eventcapture', ({ event, key, value }) => {
|
|
1469
|
-
xnew$1.emit('-eventcapture', { event, key, value });
|
|
1470
|
-
});
|
|
1471
1388
|
return group;
|
|
1472
1389
|
},
|
|
1473
1390
|
button(key) {
|
|
1474
1391
|
const button = xnew$1(Button, { key });
|
|
1475
|
-
button.on('click', ({ event }) => {
|
|
1476
|
-
xnew$1.emit('-eventcapture', { event, key });
|
|
1477
|
-
});
|
|
1478
1392
|
return button;
|
|
1479
1393
|
},
|
|
1480
1394
|
select(key, { options = [] } = {}) {
|
|
1481
1395
|
var _a, _b;
|
|
1482
1396
|
object[key] = (_b = (_a = object[key]) !== null && _a !== void 0 ? _a : options[0]) !== null && _b !== void 0 ? _b : '';
|
|
1483
1397
|
const select = xnew$1(Select, { key, value: object[key], options });
|
|
1484
|
-
select.on('input', ({
|
|
1485
|
-
xnew$1.emit('-eventcapture', { event, key, value });
|
|
1486
|
-
});
|
|
1398
|
+
select.on('input', ({ value }) => object[key] = value);
|
|
1487
1399
|
return select;
|
|
1488
1400
|
},
|
|
1489
1401
|
range(key, options = {}) {
|
|
1490
|
-
var _a;
|
|
1491
|
-
object[key] = (_a = object[key]) !== null && _a !== void 0 ? _a : 0;
|
|
1402
|
+
var _a, _b;
|
|
1403
|
+
object[key] = (_b = (_a = object[key]) !== null && _a !== void 0 ? _a : options.min) !== null && _b !== void 0 ? _b : 0;
|
|
1492
1404
|
const number = xnew$1(Range, Object.assign({ key, value: object[key] }, options));
|
|
1493
|
-
number.on('input', ({
|
|
1494
|
-
object[key] = value;
|
|
1495
|
-
xnew$1.emit('-eventcapture', { event, key, value });
|
|
1496
|
-
});
|
|
1405
|
+
number.on('input', ({ value }) => object[key] = value);
|
|
1497
1406
|
return number;
|
|
1498
1407
|
},
|
|
1499
1408
|
checkbox(key) {
|
|
1500
1409
|
var _a;
|
|
1501
1410
|
object[key] = (_a = object[key]) !== null && _a !== void 0 ? _a : false;
|
|
1502
1411
|
const checkbox = xnew$1(Checkbox, { key, value: object[key] });
|
|
1503
|
-
checkbox.on('input', ({
|
|
1504
|
-
object[key] = value;
|
|
1505
|
-
xnew$1.emit('-eventcapture', { event, key, value });
|
|
1506
|
-
});
|
|
1412
|
+
checkbox.on('input', ({ value }) => object[key] = value);
|
|
1507
1413
|
return checkbox;
|
|
1508
1414
|
},
|
|
1509
1415
|
separator() {
|
|
@@ -1514,7 +1420,7 @@ function GUIPanel(unit, { name, open = false, params }) {
|
|
|
1514
1420
|
function Group(group, { name, open = false }) {
|
|
1515
1421
|
xnew$1.extend(OpenAndClose, { open });
|
|
1516
1422
|
if (name) {
|
|
1517
|
-
xnew$1('<div style="display: flex; align-items: center; cursor: pointer;">', (unit) => {
|
|
1423
|
+
xnew$1('<div style="height: 2rem; margin: 0.125rem 0; display: flex; align-items: center; cursor: pointer; user-select: none;">', (unit) => {
|
|
1518
1424
|
unit.on('click', () => group.toggle());
|
|
1519
1425
|
xnew$1('<svg viewBox="0 0 12 12" style="width: 1rem; height: 1rem; margin-right: 0.25rem;" fill="none" stroke="currentColor">', (unit) => {
|
|
1520
1426
|
xnew$1('<path d="M6 2 10 6 6 10" />');
|
|
@@ -1526,11 +1432,11 @@ function Group(group, { name, open = false }) {
|
|
|
1526
1432
|
xnew$1.extend(Accordion);
|
|
1527
1433
|
}
|
|
1528
1434
|
function Button(unit, { key = '' }) {
|
|
1529
|
-
xnew$1.nest('<button style="margin: 0.125rem;
|
|
1435
|
+
xnew$1.nest('<button style="margin: 0.125rem 0; height: 2rem; border: 1px solid; border-radius: 0.25rem; cursor: pointer;">');
|
|
1530
1436
|
unit.element.textContent = key;
|
|
1531
1437
|
unit.on('pointerover', () => {
|
|
1532
|
-
unit.element.style.background =
|
|
1533
|
-
unit.element.style.borderColor =
|
|
1438
|
+
unit.element.style.background = currentColorB;
|
|
1439
|
+
unit.element.style.borderColor = currentColorA;
|
|
1534
1440
|
});
|
|
1535
1441
|
unit.on('pointerout', () => {
|
|
1536
1442
|
unit.element.style.background = '';
|
|
@@ -1544,31 +1450,101 @@ function Button(unit, { key = '' }) {
|
|
|
1544
1450
|
});
|
|
1545
1451
|
}
|
|
1546
1452
|
function Separator(unit) {
|
|
1547
|
-
xnew$1.nest(
|
|
1453
|
+
xnew$1.nest(`<div style="margin: 0.5rem 0; border-top: 1px solid ${currentColorA};">`);
|
|
1548
1454
|
}
|
|
1549
1455
|
function Range(unit, { key = '', value, min = 0, max = 100, step = 1 }) {
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1456
|
+
value = value !== null && value !== void 0 ? value : min;
|
|
1457
|
+
xnew$1.nest(`<div style="position: relative; height: 2rem; margin: 0.125rem 0; cursor: pointer; user-select: none;">`);
|
|
1458
|
+
// fill bar
|
|
1459
|
+
const ratio = (value - min) / (max - min);
|
|
1460
|
+
const fill = xnew$1(`<div style="position: absolute; top: 0; left: 0; bottom: 0; width: ${ratio * 100}%; background: ${currentColorB}; border: 1px solid ${currentColorA}; border-radius: 0.25rem; transition: width 0.05s;">`);
|
|
1461
|
+
// overlay labels
|
|
1462
|
+
const status = xnew$1('<div style="position: absolute; inset: 0; padding: 0 0.5rem; display: flex; justify-content: space-between; align-items: center; pointer-events: none;">', (unit) => {
|
|
1463
|
+
xnew$1('<div>', key);
|
|
1464
|
+
xnew$1('<div key="status">', value);
|
|
1554
1465
|
});
|
|
1555
|
-
|
|
1466
|
+
// hidden native input for interaction
|
|
1467
|
+
xnew$1.nest(`<input type="range" name="${key}" min="${min}" max="${max}" step="${step}" value="${value}" style="position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; margin: 0;">`);
|
|
1556
1468
|
unit.on('input', ({ event }) => {
|
|
1557
|
-
|
|
1469
|
+
const v = Number(event.target.value);
|
|
1470
|
+
const r = (v - min) / (max - min);
|
|
1471
|
+
fill.element.style.width = `${r * 100}%`;
|
|
1472
|
+
status.element.querySelector('[key="status"]').textContent = String(v);
|
|
1558
1473
|
});
|
|
1559
1474
|
}
|
|
1560
1475
|
function Checkbox(unit, { key = '', value } = {}) {
|
|
1561
|
-
xnew$1.nest(`<
|
|
1476
|
+
xnew$1.nest(`<div style="position: relative; height: 2rem; margin: 0.125rem 0; padding: 0 0.5rem; display: flex; align-items: center; cursor: pointer; user-select: none;">`);
|
|
1562
1477
|
xnew$1('<div style="flex: 1;">', key);
|
|
1563
|
-
xnew$1
|
|
1478
|
+
const box = xnew$1(`<div style="width: 1.25rem; height: 1.25rem; border: 1px solid ${currentColorA}; border-radius: 0.25rem; display: flex; align-items: center; justify-content: center; transition: background 0.1s;">`, () => {
|
|
1479
|
+
xnew$1(`<svg viewBox="0 0 12 12" style="width: 1.25rem; height: 1.25rem; opacity: 0; transition: opacity 0.1s;" fill="none" stroke="${currentColorA}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">`, () => {
|
|
1480
|
+
xnew$1('<path d="M2 6 5 9 10 3" />');
|
|
1481
|
+
});
|
|
1482
|
+
});
|
|
1483
|
+
const check = box.element.querySelector('svg');
|
|
1484
|
+
const update = (checked) => {
|
|
1485
|
+
box.element.style.background = checked ? currentColorB : '';
|
|
1486
|
+
check.style.opacity = checked ? '1' : '0';
|
|
1487
|
+
};
|
|
1488
|
+
update(!!value);
|
|
1489
|
+
xnew$1.nest(`<input type="checkbox" name="${key}" ${value ? 'checked' : ''} style="position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; margin: 0;">`);
|
|
1490
|
+
unit.on('input', ({ event, value }) => {
|
|
1491
|
+
update(value);
|
|
1492
|
+
});
|
|
1564
1493
|
}
|
|
1565
|
-
function Select(
|
|
1566
|
-
|
|
1494
|
+
function Select(_, { key = '', value, options = [] } = {}) {
|
|
1495
|
+
var _a;
|
|
1496
|
+
const initial = (_a = value !== null && value !== void 0 ? value : options[0]) !== null && _a !== void 0 ? _a : '';
|
|
1497
|
+
xnew$1.nest(`<div style="position: relative; height: 2rem; margin: 0.125rem 0; padding: 0 0.5rem; display: flex; align-items: center;">`);
|
|
1567
1498
|
xnew$1('<div style="flex: 1;">', key);
|
|
1568
|
-
xnew$1
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1499
|
+
const native = xnew$1(`<select name="${key}" style="display: none;">`, () => {
|
|
1500
|
+
for (const option of options) {
|
|
1501
|
+
xnew$1(`<option value="${option}" ${option === initial ? 'selected' : ''}>`, option);
|
|
1502
|
+
}
|
|
1503
|
+
});
|
|
1504
|
+
const button = xnew$1(`<div style="height: 2rem; padding: 0 1.5rem 0 0.5rem; display: flex; align-items: center; border: 1px solid ${currentColorA}; border-radius: 0.25rem; cursor: pointer; user-select: none; min-width: 3rem; white-space: nowrap;">`, initial);
|
|
1505
|
+
xnew$1(`<svg viewBox="0 0 12 12" style="position: absolute; right: 1.0rem; width: 0.75rem; height: 0.75rem; pointer-events: none;" fill="none" stroke="${currentColorA}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">`, () => {
|
|
1506
|
+
xnew$1('<path d="M2 4 6 8 10 4" />');
|
|
1507
|
+
});
|
|
1508
|
+
button.on('click', () => {
|
|
1509
|
+
xnew$1((list) => {
|
|
1510
|
+
xnew$1.nest(`<div style="position: fixed; border: 1px solid ${currentColorA}; border-radius: 0.25rem; overflow: hidden; z-index: 1000;">`);
|
|
1511
|
+
const updatePosition = () => {
|
|
1512
|
+
const rect = button.element.getBoundingClientRect();
|
|
1513
|
+
list.element.style.right = (window.innerWidth - rect.right) + 'px';
|
|
1514
|
+
list.element.style.top = rect.bottom + 'px';
|
|
1515
|
+
list.element.style.minWidth = rect.width + 'px';
|
|
1516
|
+
};
|
|
1517
|
+
updatePosition();
|
|
1518
|
+
list.element.style.background = getEffectiveBg(button.element);
|
|
1519
|
+
window.addEventListener('scroll', updatePosition, true);
|
|
1520
|
+
list.on('finalize', () => window.removeEventListener('scroll', updatePosition, true));
|
|
1521
|
+
for (const option of options) {
|
|
1522
|
+
const item = xnew$1(`<div style="height: 2rem; padding: 0 0.5rem; display: flex; align-items: center; cursor: pointer; user-select: none;">`, option);
|
|
1523
|
+
item.on('pointerover', () => item.element.style.background = currentColorB);
|
|
1524
|
+
item.on('pointerout', () => item.element.style.background = '');
|
|
1525
|
+
item.on('click', () => {
|
|
1526
|
+
button.element.textContent = option;
|
|
1527
|
+
native.element.value = option;
|
|
1528
|
+
native.element.dispatchEvent(new Event('input', { bubbles: false }));
|
|
1529
|
+
list.finalize();
|
|
1530
|
+
});
|
|
1531
|
+
}
|
|
1532
|
+
list.on('click.outside', () => {
|
|
1533
|
+
list.finalize();
|
|
1534
|
+
});
|
|
1535
|
+
});
|
|
1536
|
+
});
|
|
1537
|
+
xnew$1.nest(native.element);
|
|
1538
|
+
}
|
|
1539
|
+
function getEffectiveBg(el) {
|
|
1540
|
+
let current = el.parentElement;
|
|
1541
|
+
while (current) {
|
|
1542
|
+
const bg = getComputedStyle(current).backgroundColor;
|
|
1543
|
+
if (bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent')
|
|
1544
|
+
return bg;
|
|
1545
|
+
current = current.parentElement;
|
|
1546
|
+
}
|
|
1547
|
+
return 'Canvas';
|
|
1572
1548
|
}
|
|
1573
1549
|
|
|
1574
1550
|
const context = new window.AudioContext();
|
|
@@ -1800,9 +1776,9 @@ const basics = {
|
|
|
1800
1776
|
OpenAndClose,
|
|
1801
1777
|
AnalogStick,
|
|
1802
1778
|
DPad,
|
|
1803
|
-
|
|
1779
|
+
Panel,
|
|
1804
1780
|
Accordion,
|
|
1805
|
-
|
|
1781
|
+
Popup,
|
|
1806
1782
|
};
|
|
1807
1783
|
const audio = {
|
|
1808
1784
|
load(path) {
|