@mulsense/xnew 0.3.7 → 0.4.1
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 -3
- package/dist/addons/xmatter.js +0 -3
- package/dist/addons/xmatter.mjs +0 -3
- package/dist/addons/xpixi.d.ts +5 -4
- package/dist/addons/xpixi.js +10 -10
- package/dist/addons/xpixi.mjs +10 -10
- package/dist/addons/xrapier2d.js +1 -4
- package/dist/addons/xrapier2d.mjs +1 -4
- package/dist/addons/xrapier3d.js +1 -4
- package/dist/addons/xrapier3d.mjs +1 -4
- package/dist/addons/xthree.d.ts +8 -1
- package/dist/addons/xthree.js +9 -7
- package/dist/addons/xthree.mjs +9 -7
- package/dist/xnew.d.ts +48 -25
- package/dist/xnew.js +661 -567
- package/dist/xnew.mjs +661 -567
- package/package.json +8 -6
package/dist/xnew.mjs
CHANGED
|
@@ -98,7 +98,7 @@ class MapMap extends Map {
|
|
|
98
98
|
//----------------------------------------------------------------------------------------------------
|
|
99
99
|
// ticker
|
|
100
100
|
//----------------------------------------------------------------------------------------------------
|
|
101
|
-
class
|
|
101
|
+
class AnimationTicker {
|
|
102
102
|
constructor(callback, fps = 60) {
|
|
103
103
|
const self = this;
|
|
104
104
|
this.id = null;
|
|
@@ -129,7 +129,7 @@ class Timer {
|
|
|
129
129
|
this.counter = 0;
|
|
130
130
|
this.offset = 0.0;
|
|
131
131
|
this.status = 0;
|
|
132
|
-
this.ticker = new
|
|
132
|
+
this.ticker = new AnimationTicker((time) => {
|
|
133
133
|
var _a, _b;
|
|
134
134
|
let p = Math.min(this.elapsed() / this.options.duration, 1.0);
|
|
135
135
|
if (this.options.easing === 'ease-out') {
|
|
@@ -200,10 +200,323 @@ class Timer {
|
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
203
|
+
const SYSTEM_EVENTS = ['start', 'update', 'render', 'stop', 'finalize'];
|
|
204
|
+
|
|
205
|
+
class EventManager {
|
|
206
|
+
constructor() {
|
|
207
|
+
this.map = new MapMap();
|
|
208
|
+
}
|
|
209
|
+
add(props) {
|
|
210
|
+
let finalize;
|
|
211
|
+
if (props.type === 'resize') {
|
|
212
|
+
finalize = this.resize(props);
|
|
213
|
+
}
|
|
214
|
+
else if (props.type === 'wheel') {
|
|
215
|
+
finalize = this.wheel(props);
|
|
216
|
+
}
|
|
217
|
+
else if (props.type === 'click') {
|
|
218
|
+
finalize = this.click(props);
|
|
219
|
+
}
|
|
220
|
+
else if (props.type === 'click.outside') {
|
|
221
|
+
finalize = this.click_outside(props);
|
|
222
|
+
}
|
|
223
|
+
else if (['pointerdown', 'pointermove', 'pointerup', 'pointerover', 'pointerout'].includes(props.type)) {
|
|
224
|
+
finalize = this.pointer(props);
|
|
225
|
+
}
|
|
226
|
+
else if (['pointerdown.outside', 'pointermove.outside', 'pointerup.outside'].includes(props.type)) {
|
|
227
|
+
finalize = this.pointer_outside(props);
|
|
228
|
+
}
|
|
229
|
+
else if (['mousedown', 'mousemove', 'mouseup', 'mouseover', 'mouseout'].includes(props.type)) {
|
|
230
|
+
finalize = this.mouse(props);
|
|
231
|
+
}
|
|
232
|
+
else if (['touchstart', 'touchmove', 'touchend', 'touchcancel'].includes(props.type)) {
|
|
233
|
+
finalize = this.touch(props);
|
|
234
|
+
}
|
|
235
|
+
else if (['dragstart', 'dragmove', 'dragend'].includes(props.type)) {
|
|
236
|
+
finalize = this.drag(props);
|
|
237
|
+
}
|
|
238
|
+
else if (['gesturestart', 'gesturemove', 'gestureend'].includes(props.type)) {
|
|
239
|
+
finalize = this.gesture(props);
|
|
240
|
+
}
|
|
241
|
+
else if (['keydown', 'keyup'].includes(props.type)) {
|
|
242
|
+
finalize = this.key(props);
|
|
243
|
+
}
|
|
244
|
+
else if (['keydown.arrow', 'keyup.arrow'].includes(props.type)) {
|
|
245
|
+
finalize = this.key_arrow(props);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
finalize = this.basic(props);
|
|
249
|
+
}
|
|
250
|
+
this.map.set(props.type, props.listener, finalize);
|
|
251
|
+
}
|
|
252
|
+
remove({ type, listener }) {
|
|
253
|
+
const finalize = this.map.get(type, listener);
|
|
254
|
+
if (finalize) {
|
|
255
|
+
finalize();
|
|
256
|
+
this.map.delete(type, listener);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
basic(props) {
|
|
260
|
+
const execute = (event) => {
|
|
261
|
+
props.listener({ event, type: event.type });
|
|
262
|
+
};
|
|
263
|
+
props.element.addEventListener(props.type, execute, props.options);
|
|
264
|
+
return () => {
|
|
265
|
+
props.element.removeEventListener(props.type, execute);
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
resize(props) {
|
|
269
|
+
const observer = new ResizeObserver((entries) => {
|
|
270
|
+
for (const entry of entries) {
|
|
271
|
+
props.listener({ type: 'resize' });
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
observer.observe(props.element);
|
|
276
|
+
return () => {
|
|
277
|
+
observer.unobserve(props.element);
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
click(props) {
|
|
281
|
+
const execute = (event) => {
|
|
282
|
+
props.listener({ event, type: props.type, position: pointer(props.element, event).position });
|
|
283
|
+
};
|
|
284
|
+
props.element.addEventListener(props.type, execute, props.options);
|
|
285
|
+
return () => {
|
|
286
|
+
props.element.removeEventListener(props.type, execute);
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
click_outside(props) {
|
|
290
|
+
const execute = (event) => {
|
|
291
|
+
if (props.element.contains(event.target) === false) {
|
|
292
|
+
props.listener({ event, type: props.type, position: pointer(props.element, event).position });
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
document.addEventListener(props.type.split('.')[0], execute, props.options);
|
|
296
|
+
return () => {
|
|
297
|
+
document.removeEventListener(props.type.split('.')[0], execute);
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
pointer(props) {
|
|
301
|
+
const execute = (event) => {
|
|
302
|
+
props.listener({ event, type: props.type, position: pointer(props.element, event).position });
|
|
303
|
+
};
|
|
304
|
+
props.element.addEventListener(props.type, execute, props.options);
|
|
305
|
+
return () => {
|
|
306
|
+
props.element.removeEventListener(props.type, execute);
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
mouse(props) {
|
|
310
|
+
const execute = (event) => {
|
|
311
|
+
props.listener({ event, type: props.type, position: pointer(props.element, event).position });
|
|
312
|
+
};
|
|
313
|
+
props.element.addEventListener(props.type, execute, props.options);
|
|
314
|
+
return () => {
|
|
315
|
+
props.element.removeEventListener(props.type, execute);
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
touch(props) {
|
|
319
|
+
const execute = (event) => {
|
|
320
|
+
props.listener({ event, type: props.type, position: pointer(props.element, event).position });
|
|
321
|
+
};
|
|
322
|
+
props.element.addEventListener(props.type, execute, props.options);
|
|
323
|
+
return () => {
|
|
324
|
+
props.element.removeEventListener(props.type, execute);
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
pointer_outside(props) {
|
|
328
|
+
const execute = (event) => {
|
|
329
|
+
if (props.element.contains(event.target) === false) {
|
|
330
|
+
props.listener({ event, type: props.type, position: pointer(props.element, event).position });
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
document.addEventListener(props.type.split('.')[0], execute, props.options);
|
|
334
|
+
return () => {
|
|
335
|
+
document.removeEventListener(props.type.split('.')[0], execute);
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
wheel(props) {
|
|
339
|
+
const execute = (event) => {
|
|
340
|
+
props.listener({ event, type: props.type, delta: { x: event.wheelDeltaX, y: event.wheelDeltaY } });
|
|
341
|
+
};
|
|
342
|
+
props.element.addEventListener(props.type, execute, props.options);
|
|
343
|
+
return () => {
|
|
344
|
+
props.element.removeEventListener(props.type, execute);
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
drag(props) {
|
|
348
|
+
let pointermove = null;
|
|
349
|
+
let pointerup = null;
|
|
350
|
+
let pointercancel = null;
|
|
351
|
+
const pointerdown = (event) => {
|
|
352
|
+
const id = event.pointerId;
|
|
353
|
+
const position = pointer(props.element, event).position;
|
|
354
|
+
let previous = position;
|
|
355
|
+
pointermove = (event) => {
|
|
356
|
+
if (event.pointerId === id) {
|
|
357
|
+
const position = pointer(props.element, event).position;
|
|
358
|
+
const delta = { x: position.x - previous.x, y: position.y - previous.y };
|
|
359
|
+
if (props.type === 'dragmove') {
|
|
360
|
+
props.listener({ event, type: props.type, position, delta });
|
|
361
|
+
}
|
|
362
|
+
previous = position;
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
pointerup = (event) => {
|
|
366
|
+
if (event.pointerId === id) {
|
|
367
|
+
const position = pointer(props.element, event).position;
|
|
368
|
+
if (props.type === 'dragend') {
|
|
369
|
+
props.listener({ event, type: props.type, position, delta: { x: 0, y: 0 } });
|
|
370
|
+
}
|
|
371
|
+
remove();
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
pointercancel = (event) => {
|
|
375
|
+
if (event.pointerId === id) {
|
|
376
|
+
const position = pointer(props.element, event).position;
|
|
377
|
+
if (props.type === 'dragend') {
|
|
378
|
+
props.listener({ event, type: props.type, position, delta: { x: 0, y: 0 } });
|
|
379
|
+
}
|
|
380
|
+
remove();
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
window.addEventListener('pointermove', pointermove);
|
|
384
|
+
window.addEventListener('pointerup', pointerup);
|
|
385
|
+
window.addEventListener('pointercancel', pointercancel);
|
|
386
|
+
if (props.type === 'dragstart') {
|
|
387
|
+
props.listener({ event, type: props.type, position, delta: { x: 0, y: 0 } });
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
function remove() {
|
|
391
|
+
if (pointermove)
|
|
392
|
+
window.removeEventListener('pointermove', pointermove);
|
|
393
|
+
if (pointerup)
|
|
394
|
+
window.removeEventListener('pointerup', pointerup);
|
|
395
|
+
if (pointercancel)
|
|
396
|
+
window.removeEventListener('pointercancel', pointercancel);
|
|
397
|
+
pointermove = null;
|
|
398
|
+
pointerup = null;
|
|
399
|
+
pointercancel = null;
|
|
400
|
+
}
|
|
401
|
+
props.element.addEventListener('pointerdown', pointerdown, props.options);
|
|
402
|
+
return () => {
|
|
403
|
+
props.element.removeEventListener('pointerdown', pointerdown);
|
|
404
|
+
remove();
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
gesture(props) {
|
|
408
|
+
let isActive = false;
|
|
409
|
+
const map = new Map();
|
|
410
|
+
const element = props.element;
|
|
411
|
+
const options = props.options;
|
|
412
|
+
const dragstart = ({ event, position }) => {
|
|
413
|
+
map.set(event.pointerId, position);
|
|
414
|
+
isActive = map.size === 2 ? true : false;
|
|
415
|
+
if (isActive === true && props.type === 'gesturestart') {
|
|
416
|
+
props.listener({ event, type: props.type });
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
const dragmove = ({ event, position, delta }) => {
|
|
420
|
+
if (map.size >= 2 && isActive === true) {
|
|
421
|
+
const a = map.get(event.pointerId);
|
|
422
|
+
const b = getOthers(event.pointerId)[0];
|
|
423
|
+
let scale = 0.0;
|
|
424
|
+
{
|
|
425
|
+
const v = { x: a.x - b.x, y: a.y - b.y };
|
|
426
|
+
const s = v.x * v.x + v.y * v.y;
|
|
427
|
+
scale = 1 + (s > 0.0 ? (v.x * delta.x + v.y * delta.y) / s : 0);
|
|
428
|
+
}
|
|
429
|
+
// let rotate = 0.0;
|
|
430
|
+
// {
|
|
431
|
+
// const c = { x: a.x + delta.x, y: a.y + delta.y };
|
|
432
|
+
// const v1 = { x: a.x - b.x, y: a.y - b.y };
|
|
433
|
+
// const v2 = { x: c.x - b.x, y: c.y - b.y };
|
|
434
|
+
// const l1 = Math.sqrt(v1.x * v1.x + v1.y * v1.y);
|
|
435
|
+
// const l2 = Math.sqrt(v2.x * v2.x + v2.y * v2.y);
|
|
436
|
+
// if (l1 > 0.0 && l2 > 0.0) {
|
|
437
|
+
// const angle = Math.acos((v1.x * v2.x + v1.y * v2.y) / (l1 * l2));
|
|
438
|
+
// const sign = v1.x * v2.y - v1.y * v2.x;
|
|
439
|
+
// rotate = sign > 0.0 ? +angle : -angle;
|
|
440
|
+
// }
|
|
441
|
+
// }
|
|
442
|
+
if (props.type === 'gesturemove') {
|
|
443
|
+
props.listener({ event, type: props.type, scale });
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
map.set(event.pointerId, position);
|
|
447
|
+
};
|
|
448
|
+
const dragend = ({ event }) => {
|
|
449
|
+
map.delete(event.pointerId);
|
|
450
|
+
if (isActive === true && props.type === 'gestureend') {
|
|
451
|
+
props.listener({ event, type: props.type, scale: 1.0 });
|
|
452
|
+
}
|
|
453
|
+
isActive = false;
|
|
454
|
+
};
|
|
455
|
+
this.add({ element, options, type: 'dragstart', listener: dragstart });
|
|
456
|
+
this.add({ element, options, type: 'dragmove', listener: dragmove });
|
|
457
|
+
this.add({ element, options, type: 'dragend', listener: dragend });
|
|
458
|
+
function getOthers(id) {
|
|
459
|
+
const backup = map.get(id);
|
|
460
|
+
map.delete(id);
|
|
461
|
+
const others = [...map.values()];
|
|
462
|
+
map.set(id, backup);
|
|
463
|
+
return others;
|
|
464
|
+
}
|
|
465
|
+
return () => {
|
|
466
|
+
this.remove({ type: 'dragstart', listener: dragstart });
|
|
467
|
+
this.remove({ type: 'dragmove', listener: dragmove });
|
|
468
|
+
this.remove({ type: 'dragend', listener: dragend });
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
key(props) {
|
|
472
|
+
const execute = (event) => {
|
|
473
|
+
if (props.type === 'keydown' && event.repeat)
|
|
474
|
+
return;
|
|
475
|
+
props.listener({ event, type: props.type, code: event.code });
|
|
476
|
+
};
|
|
477
|
+
window.addEventListener(props.type, execute, props.options);
|
|
478
|
+
return () => {
|
|
479
|
+
window.removeEventListener(props.type, execute);
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
key_arrow(props) {
|
|
483
|
+
const keymap = {};
|
|
484
|
+
const keydown = (event) => {
|
|
485
|
+
if (event.repeat)
|
|
486
|
+
return;
|
|
487
|
+
keymap[event.code] = 1;
|
|
488
|
+
if (props.type === 'keydown.arrow' && ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) {
|
|
489
|
+
const vector = {
|
|
490
|
+
x: (keymap['ArrowLeft'] ? -1 : 0) + (keymap['ArrowRight'] ? +1 : 0),
|
|
491
|
+
y: (keymap['ArrowUp'] ? -1 : 0) + (keymap['ArrowDown'] ? +1 : 0)
|
|
492
|
+
};
|
|
493
|
+
props.listener({ event, type: props.type, code: event.code, vector });
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
const keyup = (event) => {
|
|
497
|
+
keymap[event.code] = 0;
|
|
498
|
+
if (props.type === 'keyup.arrow' && ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) {
|
|
499
|
+
const vector = {
|
|
500
|
+
x: (keymap['ArrowLeft'] ? -1 : 0) + (keymap['ArrowRight'] ? +1 : 0),
|
|
501
|
+
y: (keymap['ArrowUp'] ? -1 : 0) + (keymap['ArrowDown'] ? +1 : 0)
|
|
502
|
+
};
|
|
503
|
+
props.listener({ event, type: props.type, code: event.code, vector });
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
window.addEventListener('keydown', keydown, props.options);
|
|
507
|
+
window.addEventListener('keyup', keyup, props.options);
|
|
508
|
+
return () => {
|
|
509
|
+
window.removeEventListener('keydown', keydown);
|
|
510
|
+
window.removeEventListener('keyup', keyup);
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
function pointer(element, event) {
|
|
515
|
+
const rect = element.getBoundingClientRect();
|
|
516
|
+
const position = { x: event.clientX - rect.left, y: event.clientY - rect.top };
|
|
517
|
+
return { position };
|
|
518
|
+
}
|
|
519
|
+
|
|
207
520
|
//----------------------------------------------------------------------------------------------------
|
|
208
521
|
// unit
|
|
209
522
|
//----------------------------------------------------------------------------------------------------
|
|
@@ -279,8 +592,8 @@ class Unit {
|
|
|
279
592
|
}
|
|
280
593
|
static initialize(unit, anchor) {
|
|
281
594
|
var _a, _b;
|
|
282
|
-
const backup = Unit.
|
|
283
|
-
Unit.
|
|
595
|
+
const backup = Unit.currentUnit;
|
|
596
|
+
Unit.currentUnit = unit;
|
|
284
597
|
unit._ = Object.assign(unit._, {
|
|
285
598
|
currentElement: unit._.baseElement,
|
|
286
599
|
currentContext: unit._.baseContext,
|
|
@@ -296,7 +609,8 @@ class Unit {
|
|
|
296
609
|
components: [],
|
|
297
610
|
listeners: new MapMap(),
|
|
298
611
|
defines: {},
|
|
299
|
-
systems: { start: [],
|
|
612
|
+
systems: { start: [], update: [], render: [], stop: [], finalize: [] },
|
|
613
|
+
eventManager: new EventManager(),
|
|
300
614
|
});
|
|
301
615
|
// nest html element
|
|
302
616
|
if (typeof unit._.target === 'string') {
|
|
@@ -306,13 +620,13 @@ class Unit {
|
|
|
306
620
|
Unit.extend(unit, unit._.baseComponent, unit._.props);
|
|
307
621
|
// whether the unit promise was resolved
|
|
308
622
|
Promise.all(unit._.promises.map(p => p.promise)).then(() => unit._.state = 'initialized');
|
|
309
|
-
Unit.
|
|
623
|
+
Unit.currentUnit = backup;
|
|
310
624
|
}
|
|
311
625
|
static finalize(unit) {
|
|
312
626
|
if (unit._.state !== 'finalized' && unit._.state !== 'finalizing') {
|
|
313
627
|
unit._.state = 'finalizing';
|
|
314
628
|
unit._.children.forEach((child) => child.finalize());
|
|
315
|
-
unit._.systems.finalize.forEach((
|
|
629
|
+
unit._.systems.finalize.forEach(({ execute }) => execute());
|
|
316
630
|
unit.off();
|
|
317
631
|
unit._.components.forEach((component) => Unit.component2units.delete(component, unit));
|
|
318
632
|
if (unit._.elements.length > 0) {
|
|
@@ -392,7 +706,7 @@ class Unit {
|
|
|
392
706
|
if (unit._.state === 'initialized' || unit._.state === 'stopped') {
|
|
393
707
|
unit._.state = 'started';
|
|
394
708
|
unit._.children.forEach((child) => Unit.start(child));
|
|
395
|
-
unit._.systems.start.forEach((
|
|
709
|
+
unit._.systems.start.forEach(({ execute }) => execute());
|
|
396
710
|
}
|
|
397
711
|
else if (unit._.state === 'started') {
|
|
398
712
|
unit._.children.forEach((child) => Unit.start(child));
|
|
@@ -402,31 +716,31 @@ class Unit {
|
|
|
402
716
|
if (unit._.state === 'started') {
|
|
403
717
|
unit._.state = 'stopped';
|
|
404
718
|
unit._.children.forEach((child) => Unit.stop(child));
|
|
405
|
-
unit._.systems.stop.forEach((
|
|
719
|
+
unit._.systems.stop.forEach(({ execute }) => execute());
|
|
406
720
|
}
|
|
407
721
|
}
|
|
408
722
|
static update(unit) {
|
|
409
|
-
if (unit._.state === 'started'
|
|
723
|
+
if (unit._.state === 'started') {
|
|
410
724
|
unit._.children.forEach((child) => Unit.update(child));
|
|
411
|
-
unit._.systems.update.forEach((
|
|
725
|
+
unit._.systems.update.forEach(({ execute }) => execute());
|
|
412
726
|
}
|
|
413
727
|
}
|
|
414
|
-
static
|
|
415
|
-
if (unit._.state === 'started') {
|
|
416
|
-
unit._.children.forEach((child) => Unit.
|
|
417
|
-
unit._.systems.
|
|
728
|
+
static render(unit) {
|
|
729
|
+
if (unit._.state === 'started' || unit._.state === 'started' || unit._.state === 'stopped') {
|
|
730
|
+
unit._.children.forEach((child) => Unit.render(child));
|
|
731
|
+
unit._.systems.render.forEach(({ execute }) => execute());
|
|
418
732
|
}
|
|
419
733
|
}
|
|
420
734
|
static reset() {
|
|
421
|
-
var _a
|
|
422
|
-
(_a = Unit.
|
|
423
|
-
Unit.
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
Unit.
|
|
427
|
-
Unit.
|
|
428
|
-
Unit.update(Unit.root);
|
|
735
|
+
var _a;
|
|
736
|
+
(_a = Unit.rootUnit) === null || _a === void 0 ? void 0 : _a.finalize();
|
|
737
|
+
Unit.currentUnit = Unit.rootUnit = new Unit(null, null);
|
|
738
|
+
const ticker = new AnimationTicker(() => {
|
|
739
|
+
Unit.start(Unit.rootUnit);
|
|
740
|
+
Unit.update(Unit.rootUnit);
|
|
741
|
+
Unit.render(Unit.rootUnit);
|
|
429
742
|
});
|
|
743
|
+
Unit.rootUnit.on('finalize', () => ticker.clear());
|
|
430
744
|
}
|
|
431
745
|
static wrap(unit, listener) {
|
|
432
746
|
const snapshot = Unit.snapshot(unit);
|
|
@@ -436,25 +750,27 @@ class Unit {
|
|
|
436
750
|
if (snapshot.unit._.state === 'finalized') {
|
|
437
751
|
return;
|
|
438
752
|
}
|
|
439
|
-
const
|
|
753
|
+
const currentUnit = Unit.currentUnit;
|
|
440
754
|
const backup = Unit.snapshot(snapshot.unit);
|
|
441
755
|
try {
|
|
442
|
-
Unit.
|
|
756
|
+
Unit.currentUnit = snapshot.unit;
|
|
443
757
|
snapshot.unit._.currentContext = snapshot.context;
|
|
444
758
|
snapshot.unit._.currentElement = snapshot.element;
|
|
759
|
+
snapshot.unit._.currentComponent = snapshot.component;
|
|
445
760
|
return func(...args);
|
|
446
761
|
}
|
|
447
762
|
catch (error) {
|
|
448
763
|
throw error;
|
|
449
764
|
}
|
|
450
765
|
finally {
|
|
451
|
-
Unit.
|
|
766
|
+
Unit.currentUnit = currentUnit;
|
|
452
767
|
snapshot.unit._.currentContext = backup.context;
|
|
453
768
|
snapshot.unit._.currentElement = backup.element;
|
|
769
|
+
snapshot.unit._.currentComponent = backup.component;
|
|
454
770
|
}
|
|
455
771
|
}
|
|
456
772
|
static snapshot(unit) {
|
|
457
|
-
return { unit, context: unit._.currentContext, element: unit._.currentElement };
|
|
773
|
+
return { unit, context: unit._.currentContext, element: unit._.currentElement, component: unit._.currentComponent };
|
|
458
774
|
}
|
|
459
775
|
static context(unit, key, value) {
|
|
460
776
|
if (value !== undefined) {
|
|
@@ -472,43 +788,47 @@ class Unit {
|
|
|
472
788
|
return [...((_a = Unit.component2units.get(component)) !== null && _a !== void 0 ? _a : [])];
|
|
473
789
|
}
|
|
474
790
|
on(type, listener, options) {
|
|
475
|
-
type.trim().split(/\s+/)
|
|
476
|
-
|
|
477
|
-
this._.systems[type].push(listener);
|
|
478
|
-
}
|
|
479
|
-
if (this._.listeners.has(type, listener) === false) {
|
|
480
|
-
const execute = Unit.wrap(Unit.current, listener);
|
|
481
|
-
this._.listeners.set(type, listener, { element: this.element, execute });
|
|
482
|
-
Unit.type2units.add(type, this);
|
|
483
|
-
if (/^[A-Za-z]/.test(type)) {
|
|
484
|
-
this.element.addEventListener(type, execute, options);
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
});
|
|
791
|
+
const types = type.trim().split(/\s+/);
|
|
792
|
+
types.forEach((type) => Unit.on(this, type, listener, options));
|
|
488
793
|
}
|
|
489
794
|
off(type, listener) {
|
|
490
795
|
const types = typeof type === 'string' ? type.trim().split(/\s+/) : [...this._.listeners.keys()];
|
|
491
|
-
types.forEach((type) =>
|
|
492
|
-
|
|
493
|
-
|
|
796
|
+
types.forEach((type) => Unit.off(this, type, listener));
|
|
797
|
+
}
|
|
798
|
+
static on(unit, type, listener, options) {
|
|
799
|
+
if (SYSTEM_EVENTS.includes(type)) {
|
|
800
|
+
const execute = Unit.wrap(Unit.currentUnit, listener);
|
|
801
|
+
unit._.systems[type].push({ listener, execute });
|
|
802
|
+
}
|
|
803
|
+
if (unit._.listeners.has(type, listener) === false) {
|
|
804
|
+
const execute = Unit.wrap(Unit.currentUnit, listener);
|
|
805
|
+
unit._.listeners.set(type, listener, { element: unit.element, component: unit._.currentComponent, execute });
|
|
806
|
+
Unit.type2units.add(type, unit);
|
|
807
|
+
if (/^[A-Za-z]/.test(type)) {
|
|
808
|
+
unit._.eventManager.add({ element: unit.element, type, listener: execute, options });
|
|
494
809
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
static off(unit, type, listener) {
|
|
813
|
+
if (SYSTEM_EVENTS.includes(type)) {
|
|
814
|
+
unit._.systems[type] = unit._.systems[type].filter(({ listener: lis }) => listener ? lis !== listener : false);
|
|
815
|
+
}
|
|
816
|
+
(listener ? [listener] : [...unit._.listeners.keys(type)]).forEach((listener) => {
|
|
817
|
+
const item = unit._.listeners.get(type, listener);
|
|
818
|
+
if (item === undefined)
|
|
819
|
+
return;
|
|
820
|
+
unit._.listeners.delete(type, listener);
|
|
821
|
+
if (/^[A-Za-z]/.test(type)) {
|
|
822
|
+
unit._.eventManager.remove({ type, listener: item.execute });
|
|
506
823
|
}
|
|
507
824
|
});
|
|
825
|
+
if (unit._.listeners.has(type) === false) {
|
|
826
|
+
Unit.type2units.delete(type, unit);
|
|
827
|
+
}
|
|
508
828
|
}
|
|
509
829
|
static emit(type, ...args) {
|
|
510
830
|
var _a, _b;
|
|
511
|
-
const current = Unit.
|
|
831
|
+
const current = Unit.currentUnit;
|
|
512
832
|
if (type[0] === '+') {
|
|
513
833
|
(_a = Unit.type2units.get(type)) === null || _a === void 0 ? void 0 : _a.forEach((unit) => {
|
|
514
834
|
var _a;
|
|
@@ -523,6 +843,7 @@ class Unit {
|
|
|
523
843
|
}
|
|
524
844
|
}
|
|
525
845
|
}
|
|
846
|
+
Unit.currentComponent = () => { };
|
|
526
847
|
Unit.component2units = new MapSet();
|
|
527
848
|
//----------------------------------------------------------------------------------------------------
|
|
528
849
|
// event
|
|
@@ -537,15 +858,15 @@ class UnitPromise {
|
|
|
537
858
|
this.component = component;
|
|
538
859
|
}
|
|
539
860
|
then(callback) {
|
|
540
|
-
this.promise = this.promise.then(Unit.wrap(Unit.
|
|
861
|
+
this.promise = this.promise.then(Unit.wrap(Unit.currentUnit, callback));
|
|
541
862
|
return this;
|
|
542
863
|
}
|
|
543
864
|
catch(callback) {
|
|
544
|
-
this.promise = this.promise.catch(Unit.wrap(Unit.
|
|
865
|
+
this.promise = this.promise.catch(Unit.wrap(Unit.currentUnit, callback));
|
|
545
866
|
return this;
|
|
546
867
|
}
|
|
547
868
|
finally(callback) {
|
|
548
|
-
this.promise = this.promise.finally(Unit.wrap(Unit.
|
|
869
|
+
this.promise = this.promise.finally(Unit.wrap(Unit.currentUnit, callback));
|
|
549
870
|
return this;
|
|
550
871
|
}
|
|
551
872
|
}
|
|
@@ -555,7 +876,7 @@ class UnitPromise {
|
|
|
555
876
|
class UnitTimer {
|
|
556
877
|
constructor(options) {
|
|
557
878
|
this.stack = [];
|
|
558
|
-
this.unit = new Unit(Unit.
|
|
879
|
+
this.unit = new Unit(Unit.currentUnit, UnitTimer.Component, Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
|
|
559
880
|
}
|
|
560
881
|
clear() {
|
|
561
882
|
this.stack = [];
|
|
@@ -575,19 +896,19 @@ class UnitTimer {
|
|
|
575
896
|
}
|
|
576
897
|
static execute(timer, options) {
|
|
577
898
|
if (timer.unit._.state === 'finalized') {
|
|
578
|
-
timer.unit = new Unit(Unit.
|
|
899
|
+
timer.unit = new Unit(Unit.currentUnit, UnitTimer.Component, Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
|
|
579
900
|
}
|
|
580
901
|
else if (timer.stack.length === 0) {
|
|
581
|
-
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.
|
|
902
|
+
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
|
|
582
903
|
timer.unit.on('finalize', () => { UnitTimer.next(timer); });
|
|
583
904
|
}
|
|
584
905
|
else {
|
|
585
|
-
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.
|
|
906
|
+
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
|
|
586
907
|
}
|
|
587
908
|
}
|
|
588
909
|
static next(timer) {
|
|
589
910
|
if (timer.stack.length > 0) {
|
|
590
|
-
timer.unit = new Unit(Unit.
|
|
911
|
+
timer.unit = new Unit(Unit.currentUnit, UnitTimer.Component, timer.stack.shift());
|
|
591
912
|
timer.unit.on('finalize', () => { UnitTimer.next(timer); });
|
|
592
913
|
}
|
|
593
914
|
}
|
|
@@ -614,10 +935,10 @@ class UnitTimer {
|
|
|
614
935
|
}
|
|
615
936
|
|
|
616
937
|
const xnew$1 = Object.assign(function (...args) {
|
|
617
|
-
if (Unit.
|
|
938
|
+
if (Unit.rootUnit === undefined) {
|
|
618
939
|
Unit.reset();
|
|
619
940
|
}
|
|
620
|
-
return new Unit(Unit.
|
|
941
|
+
return new Unit(Unit.currentUnit, ...args);
|
|
621
942
|
}, {
|
|
622
943
|
/**
|
|
623
944
|
* Creates a nested HTML/SVG element within the current component
|
|
@@ -630,7 +951,7 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
630
951
|
*/
|
|
631
952
|
nest(tag) {
|
|
632
953
|
try {
|
|
633
|
-
return Unit.nest(Unit.
|
|
954
|
+
return Unit.nest(Unit.currentUnit, tag);
|
|
634
955
|
}
|
|
635
956
|
catch (error) {
|
|
636
957
|
console.error('xnew.nest(tag: string): ', error);
|
|
@@ -648,7 +969,7 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
648
969
|
*/
|
|
649
970
|
extend(component, props) {
|
|
650
971
|
try {
|
|
651
|
-
return Unit.extend(Unit.
|
|
972
|
+
return Unit.extend(Unit.currentUnit, component, props);
|
|
652
973
|
}
|
|
653
974
|
catch (error) {
|
|
654
975
|
console.error('xnew.extend(component: Function, props?: Object): ', error);
|
|
@@ -669,7 +990,7 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
669
990
|
*/
|
|
670
991
|
context(key, value = undefined) {
|
|
671
992
|
try {
|
|
672
|
-
return Unit.context(Unit.
|
|
993
|
+
return Unit.context(Unit.currentUnit, key, value);
|
|
673
994
|
}
|
|
674
995
|
catch (error) {
|
|
675
996
|
console.error('xnew.context(key: string, value?: any): ', error);
|
|
@@ -685,9 +1006,9 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
685
1006
|
*/
|
|
686
1007
|
promise(promise) {
|
|
687
1008
|
try {
|
|
688
|
-
const component = Unit.
|
|
689
|
-
Unit.
|
|
690
|
-
return Unit.
|
|
1009
|
+
const component = Unit.currentUnit._.currentComponent;
|
|
1010
|
+
Unit.currentUnit._.promises.push(new UnitPromise(promise, component));
|
|
1011
|
+
return Unit.currentUnit._.promises[Unit.currentUnit._.promises.length - 1];
|
|
691
1012
|
}
|
|
692
1013
|
catch (error) {
|
|
693
1014
|
console.error('xnew.promise(promise: Promise<any>): ', error);
|
|
@@ -703,8 +1024,8 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
703
1024
|
*/
|
|
704
1025
|
then(callback) {
|
|
705
1026
|
try {
|
|
706
|
-
const component = Unit.
|
|
707
|
-
const promises = Unit.
|
|
1027
|
+
const component = Unit.currentUnit._.currentComponent;
|
|
1028
|
+
const promises = Unit.currentUnit._.promises;
|
|
708
1029
|
return new UnitPromise(Promise.all(promises.map(p => p.promise)), null)
|
|
709
1030
|
.then((results) => {
|
|
710
1031
|
callback(results.filter((_result, index) => promises[index].component !== null && promises[index].component === component));
|
|
@@ -724,7 +1045,7 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
724
1045
|
*/
|
|
725
1046
|
catch(callback) {
|
|
726
1047
|
try {
|
|
727
|
-
const promises = Unit.
|
|
1048
|
+
const promises = Unit.currentUnit._.promises;
|
|
728
1049
|
return new UnitPromise(Promise.all(promises.map(p => p.promise)), null)
|
|
729
1050
|
.catch(callback);
|
|
730
1051
|
}
|
|
@@ -742,7 +1063,7 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
742
1063
|
*/
|
|
743
1064
|
finally(callback) {
|
|
744
1065
|
try {
|
|
745
|
-
const promises = Unit.
|
|
1066
|
+
const promises = Unit.currentUnit._.promises;
|
|
746
1067
|
return new UnitPromise(Promise.all(promises.map(p => p.promise)), null)
|
|
747
1068
|
.finally(callback);
|
|
748
1069
|
}
|
|
@@ -761,7 +1082,7 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
761
1082
|
* }), 1000)
|
|
762
1083
|
*/
|
|
763
1084
|
scope(callback) {
|
|
764
|
-
const snapshot = Unit.snapshot(Unit.
|
|
1085
|
+
const snapshot = Unit.snapshot(Unit.currentUnit);
|
|
765
1086
|
return (...args) => Unit.scope(snapshot, callback, ...args);
|
|
766
1087
|
},
|
|
767
1088
|
/**
|
|
@@ -832,7 +1153,7 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
832
1153
|
return new UnitTimer({ transition, duration, easing, iterations: 1 });
|
|
833
1154
|
},
|
|
834
1155
|
protect() {
|
|
835
|
-
Unit.
|
|
1156
|
+
Unit.currentUnit._.protected = true;
|
|
836
1157
|
}
|
|
837
1158
|
});
|
|
838
1159
|
|
|
@@ -867,12 +1188,12 @@ function AccordionFrame(frame, { open = false, duration = 200, easing = 'ease' }
|
|
|
867
1188
|
}
|
|
868
1189
|
};
|
|
869
1190
|
}
|
|
870
|
-
function AccordionHeader(
|
|
1191
|
+
function AccordionHeader(unit, {} = {}) {
|
|
871
1192
|
const internal = xnew$1.context('xnew.accordionframe');
|
|
872
1193
|
xnew$1.nest('<button style="display: flex; align-items: center; margin: 0; padding: 0; width: 100%; text-align: left; border: none; font: inherit; color: inherit; background: none; cursor: pointer;">');
|
|
873
|
-
|
|
1194
|
+
unit.on('click', () => internal.frame.toggle());
|
|
874
1195
|
}
|
|
875
|
-
function AccordionBullet(
|
|
1196
|
+
function AccordionBullet(unit, { type = 'arrow' } = {}) {
|
|
876
1197
|
const internal = xnew$1.context('xnew.accordionframe');
|
|
877
1198
|
xnew$1.nest('<div style="display:inline-block; position: relative; width: 0.55em; margin: 0 0.3em;">');
|
|
878
1199
|
if (type === 'arrow') {
|
|
@@ -893,12 +1214,12 @@ function AccordionBullet(bullet, { type = 'arrow' } = {}) {
|
|
|
893
1214
|
});
|
|
894
1215
|
}
|
|
895
1216
|
}
|
|
896
|
-
function AccordionContent(
|
|
1217
|
+
function AccordionContent(unit, {} = {}) {
|
|
897
1218
|
const internal = xnew$1.context('xnew.accordionframe');
|
|
898
1219
|
xnew$1.nest(`<div style="display: ${internal.open ? 'block' : 'none'};">`);
|
|
899
1220
|
xnew$1.nest('<div style="padding: 0; display: flex; flex-direction: column; box-sizing: border-box;">');
|
|
900
1221
|
internal.on('-transition', ({ rate }) => {
|
|
901
|
-
|
|
1222
|
+
unit.transition({ element: unit.element, rate });
|
|
902
1223
|
});
|
|
903
1224
|
return {
|
|
904
1225
|
transition({ element, rate }) {
|
|
@@ -917,209 +1238,12 @@ function AccordionContent(content, {} = {}) {
|
|
|
917
1238
|
};
|
|
918
1239
|
}
|
|
919
1240
|
|
|
920
|
-
function
|
|
921
|
-
const observer = new ResizeObserver(xnew$1.scope((entries) => {
|
|
922
|
-
for (const entry of entries) {
|
|
923
|
-
xnew$1.emit('-resize');
|
|
924
|
-
break;
|
|
925
|
-
}
|
|
926
|
-
}));
|
|
927
|
-
if (resize.element) {
|
|
928
|
-
observer.observe(resize.element);
|
|
929
|
-
}
|
|
930
|
-
resize.on('finalize', () => {
|
|
931
|
-
if (resize.element) {
|
|
932
|
-
observer.unobserve(resize.element);
|
|
933
|
-
}
|
|
934
|
-
});
|
|
935
|
-
}
|
|
936
|
-
function DirectEvent(unit) {
|
|
937
|
-
const state = {};
|
|
938
|
-
const keydown = xnew$1.scope((event) => {
|
|
939
|
-
if (event.repeat)
|
|
940
|
-
return;
|
|
941
|
-
state[event.code] = 1;
|
|
942
|
-
xnew$1.emit('-keydown', { event, type: '-keydown', code: event.code });
|
|
943
|
-
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) {
|
|
944
|
-
xnew$1.emit('-keydown.arrow', { event, type: '-keydown.arrow', code: event.code, vector: getVector() });
|
|
945
|
-
}
|
|
946
|
-
});
|
|
947
|
-
const keyup = xnew$1.scope((event) => {
|
|
948
|
-
state[event.code] = 0;
|
|
949
|
-
xnew$1.emit('-keyup', { event, type: '-keyup', code: event.code });
|
|
950
|
-
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) {
|
|
951
|
-
xnew$1.emit('-keyup.arrow', { event, type: '-keyup.arrow', code: event.code, vector: getVector() });
|
|
952
|
-
}
|
|
953
|
-
});
|
|
954
|
-
window.addEventListener('keydown', keydown);
|
|
955
|
-
window.addEventListener('keyup', keyup);
|
|
956
|
-
unit.on('finalize', () => {
|
|
957
|
-
window.removeEventListener('keydown', keydown);
|
|
958
|
-
window.removeEventListener('keyup', keyup);
|
|
959
|
-
});
|
|
960
|
-
function getVector() {
|
|
961
|
-
return {
|
|
962
|
-
x: (state['ArrowLeft'] ? -1 : 0) + (state['ArrowRight'] ? +1 : 0),
|
|
963
|
-
y: (state['ArrowUp'] ? -1 : 0) + (state['ArrowDown'] ? +1 : 0)
|
|
964
|
-
};
|
|
965
|
-
}
|
|
966
|
-
const internal = xnew$1();
|
|
967
|
-
internal.on('pointerdown', (event) => xnew$1.emit('-pointerdown', { event, position: getPosition(unit.element, event) }));
|
|
968
|
-
internal.on('pointermove', (event) => xnew$1.emit('-pointermove', { event, position: getPosition(unit.element, event) }));
|
|
969
|
-
internal.on('pointerup', (event) => xnew$1.emit('-pointerup', { event, position: getPosition(unit.element, event) }));
|
|
970
|
-
internal.on('wheel', (event) => xnew$1.emit('-wheel', { event, delta: { x: event.wheelDeltaX, y: event.wheelDeltaY } }));
|
|
971
|
-
internal.on('click', (event) => xnew$1.emit('-click', { event, position: getPosition(unit.element, event) }));
|
|
972
|
-
internal.on('pointerover', (event) => xnew$1.emit('-pointerover', { event, position: getPosition(unit.element, event) }));
|
|
973
|
-
internal.on('pointerout', (event) => xnew$1.emit('-pointerout', { event, position: getPosition(unit.element, event) }));
|
|
974
|
-
const pointerdownoutside = xnew$1.scope((event) => {
|
|
975
|
-
if (unit.element.contains(event.target) === false) {
|
|
976
|
-
xnew$1.emit('-pointerdown.outside', { event, position: getPosition(unit.element, event) });
|
|
977
|
-
}
|
|
978
|
-
});
|
|
979
|
-
const pointerupoutside = xnew$1.scope((event) => {
|
|
980
|
-
if (unit.element.contains(event.target) === false) {
|
|
981
|
-
xnew$1.emit('-pointerup.outside', { event, position: getPosition(unit.element, event) });
|
|
982
|
-
}
|
|
983
|
-
});
|
|
984
|
-
const clickoutside = xnew$1.scope((event) => {
|
|
985
|
-
if (unit.element.contains(event.target) === false) {
|
|
986
|
-
xnew$1.emit('-click.outside', { event, position: getPosition(unit.element, event) });
|
|
987
|
-
}
|
|
988
|
-
});
|
|
989
|
-
document.addEventListener('pointerdown', pointerdownoutside);
|
|
990
|
-
document.addEventListener('pointerup', pointerupoutside);
|
|
991
|
-
document.addEventListener('click', clickoutside);
|
|
992
|
-
unit.on('finalize', () => {
|
|
993
|
-
document.removeEventListener('pointerdown', pointerdownoutside);
|
|
994
|
-
document.removeEventListener('pointerup', pointerupoutside);
|
|
995
|
-
document.removeEventListener('click', clickoutside);
|
|
996
|
-
});
|
|
997
|
-
const drag = xnew$1(DragEvent);
|
|
998
|
-
drag.on('-dragstart', (...args) => xnew$1.emit('-dragstart', ...args));
|
|
999
|
-
drag.on('-dragmove', (...args) => xnew$1.emit('-dragmove', ...args));
|
|
1000
|
-
drag.on('-dragend', (...args) => xnew$1.emit('-dragend', ...args));
|
|
1001
|
-
drag.on('-dragcancel', (...args) => xnew$1.emit('-dragcancel', ...args));
|
|
1002
|
-
const gesture = xnew$1(GestureEvent);
|
|
1003
|
-
gesture.on('-gesturestart', (...args) => xnew$1.emit('-gesturestart', ...args));
|
|
1004
|
-
gesture.on('-gesturemove', (...args) => xnew$1.emit('-gesturemove', ...args));
|
|
1005
|
-
gesture.on('-gestureend', (...args) => xnew$1.emit('-gestureend', ...args));
|
|
1006
|
-
gesture.on('-gesturecancel', (...args) => xnew$1.emit('-gesturecancel', ...args));
|
|
1007
|
-
}
|
|
1008
|
-
function DragEvent(unit) {
|
|
1009
|
-
const pointerdown = xnew$1.scope((event) => {
|
|
1010
|
-
const id = event.pointerId;
|
|
1011
|
-
const position = getPosition(unit.element, event);
|
|
1012
|
-
let previous = position;
|
|
1013
|
-
let connect = true;
|
|
1014
|
-
const pointermove = xnew$1.scope((event) => {
|
|
1015
|
-
if (event.pointerId === id) {
|
|
1016
|
-
const position = getPosition(unit.element, event);
|
|
1017
|
-
const delta = { x: position.x - previous.x, y: position.y - previous.y };
|
|
1018
|
-
xnew$1.emit('-dragmove', { event, position, delta });
|
|
1019
|
-
previous = position;
|
|
1020
|
-
}
|
|
1021
|
-
});
|
|
1022
|
-
const pointerup = xnew$1.scope((event) => {
|
|
1023
|
-
if (event.pointerId === id) {
|
|
1024
|
-
const position = getPosition(unit.element, event);
|
|
1025
|
-
xnew$1.emit('-dragend', { event, position, });
|
|
1026
|
-
remove();
|
|
1027
|
-
}
|
|
1028
|
-
});
|
|
1029
|
-
const pointercancel = xnew$1.scope((event) => {
|
|
1030
|
-
if (event.pointerId === id) {
|
|
1031
|
-
const position = getPosition(unit.element, event);
|
|
1032
|
-
xnew$1.emit('-dragcancel', { event, position, });
|
|
1033
|
-
remove();
|
|
1034
|
-
}
|
|
1035
|
-
});
|
|
1036
|
-
window.addEventListener('pointermove', pointermove);
|
|
1037
|
-
window.addEventListener('pointerup', pointerup);
|
|
1038
|
-
window.addEventListener('pointercancel', pointercancel);
|
|
1039
|
-
function remove() {
|
|
1040
|
-
if (connect === true) {
|
|
1041
|
-
window.removeEventListener('pointermove', pointermove);
|
|
1042
|
-
window.removeEventListener('pointerup', pointerup);
|
|
1043
|
-
window.removeEventListener('pointercancel', pointercancel);
|
|
1044
|
-
connect = false;
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
xnew$1((unit) => unit.on('-finalize', remove));
|
|
1048
|
-
xnew$1.emit('-dragstart', { event, position });
|
|
1049
|
-
});
|
|
1050
|
-
unit.on('pointerdown', pointerdown);
|
|
1051
|
-
}
|
|
1052
|
-
function GestureEvent(unit) {
|
|
1053
|
-
const drag = xnew$1(DragEvent);
|
|
1054
|
-
let isActive = false;
|
|
1055
|
-
const map = new Map();
|
|
1056
|
-
drag.on('-dragstart', ({ event, position }) => {
|
|
1057
|
-
map.set(event.pointerId, Object.assign({}, position));
|
|
1058
|
-
isActive = map.size === 2 ? true : false;
|
|
1059
|
-
if (isActive === true) {
|
|
1060
|
-
xnew$1.emit('-gesturestart', {});
|
|
1061
|
-
}
|
|
1062
|
-
});
|
|
1063
|
-
drag.on('-dragmove', ({ event, position, delta }) => {
|
|
1064
|
-
if (map.size >= 2 && isActive === true) {
|
|
1065
|
-
const a = map.get(event.pointerId);
|
|
1066
|
-
const b = getOthers(event.pointerId)[0];
|
|
1067
|
-
let scale = 0.0;
|
|
1068
|
-
{
|
|
1069
|
-
const v = { x: a.x - b.x, y: a.y - b.y };
|
|
1070
|
-
const s = v.x * v.x + v.y * v.y;
|
|
1071
|
-
scale = 1 + (s > 0.0 ? (v.x * delta.x + v.y * delta.y) / s : 0);
|
|
1072
|
-
}
|
|
1073
|
-
// let rotate = 0.0;
|
|
1074
|
-
// {
|
|
1075
|
-
// const c = { x: a.x + delta.x, y: a.y + delta.y };
|
|
1076
|
-
// const v1 = { x: a.x - b.x, y: a.y - b.y };
|
|
1077
|
-
// const v2 = { x: c.x - b.x, y: c.y - b.y };
|
|
1078
|
-
// const l1 = Math.sqrt(v1.x * v1.x + v1.y * v1.y);
|
|
1079
|
-
// const l2 = Math.sqrt(v2.x * v2.x + v2.y * v2.y);
|
|
1080
|
-
// if (l1 > 0.0 && l2 > 0.0) {
|
|
1081
|
-
// const angle = Math.acos((v1.x * v2.x + v1.y * v2.y) / (l1 * l2));
|
|
1082
|
-
// const sign = v1.x * v2.y - v1.y * v2.x;
|
|
1083
|
-
// rotate = sign > 0.0 ? +angle : -angle;
|
|
1084
|
-
// }
|
|
1085
|
-
// }
|
|
1086
|
-
xnew$1.emit('-gesturemove', { event, position, delta, scale });
|
|
1087
|
-
}
|
|
1088
|
-
map.set(event.pointerId, position);
|
|
1089
|
-
});
|
|
1090
|
-
drag.on('-dragend', ({ event }) => {
|
|
1091
|
-
if (isActive === true) {
|
|
1092
|
-
xnew$1.emit('-gestureend', {});
|
|
1093
|
-
}
|
|
1094
|
-
isActive = false;
|
|
1095
|
-
map.delete(event.pointerId);
|
|
1096
|
-
});
|
|
1097
|
-
drag.on('-dragcancel', ({ event }) => {
|
|
1098
|
-
if (isActive === true) {
|
|
1099
|
-
xnew$1.emit('-gesturecancel', { event });
|
|
1100
|
-
}
|
|
1101
|
-
isActive = false;
|
|
1102
|
-
map.delete(event.pointerId);
|
|
1103
|
-
});
|
|
1104
|
-
function getOthers(id) {
|
|
1105
|
-
const backup = map.get(id);
|
|
1106
|
-
map.delete(id);
|
|
1107
|
-
const others = [...map.values()];
|
|
1108
|
-
map.set(id, backup);
|
|
1109
|
-
return others;
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
function getPosition(element, event) {
|
|
1113
|
-
const rect = element.getBoundingClientRect();
|
|
1114
|
-
return { x: event.clientX - rect.left, y: event.clientY - rect.top };
|
|
1115
|
-
}
|
|
1116
|
-
|
|
1117
|
-
function Screen(screen, { width = 640, height = 480, fit = 'contain' } = {}) {
|
|
1241
|
+
function Screen(unit, { width = 640, height = 480, fit = 'contain' } = {}) {
|
|
1118
1242
|
const size = { width, height };
|
|
1119
1243
|
const wrapper = xnew$1.nest('<div style="position: relative; width: 100%; height: 100%; overflow: hidden;">');
|
|
1244
|
+
unit.on('resize', resize);
|
|
1120
1245
|
const absolute = xnew$1.nest('<div style="position: absolute; margin: auto; container-type: size; overflow: hidden;">');
|
|
1121
1246
|
const canvas = xnew$1(`<canvas width="${width}" height="${height}" style="width: 100%; height: 100%; vertical-align: bottom; user-select: none; user-drag: none; pointer-events: auto;">`);
|
|
1122
|
-
xnew$1(wrapper, ResizeEvent).on('-resize', resize);
|
|
1123
1247
|
resize();
|
|
1124
1248
|
function resize() {
|
|
1125
1249
|
const aspect = size.width / size.height;
|
|
@@ -1260,15 +1384,14 @@ function DragFrame(frame, { x = 0, y = 0 } = {}) {
|
|
|
1260
1384
|
const absolute = xnew$1.nest(`<div style="position: absolute; top: ${y}px; left: ${x}px;">`);
|
|
1261
1385
|
xnew$1.context('xnew.dragframe', { frame, absolute });
|
|
1262
1386
|
}
|
|
1263
|
-
function DragTarget(
|
|
1387
|
+
function DragTarget(unit, {} = {}) {
|
|
1264
1388
|
const { frame, absolute } = xnew$1.context('xnew.dragframe');
|
|
1265
|
-
xnew$1.
|
|
1266
|
-
const direct = xnew$1(absolute.parentElement, DirectEvent);
|
|
1389
|
+
const target = xnew$1(absolute.parentElement);
|
|
1267
1390
|
const current = { x: 0, y: 0 };
|
|
1268
1391
|
const offset = { x: 0, y: 0 };
|
|
1269
1392
|
let dragged = false;
|
|
1270
|
-
|
|
1271
|
-
if (
|
|
1393
|
+
target.on('dragstart', ({ event, position }) => {
|
|
1394
|
+
if (unit.element.contains(event.target) === false)
|
|
1272
1395
|
return;
|
|
1273
1396
|
dragged = true;
|
|
1274
1397
|
offset.x = position.x - parseFloat(absolute.style.left || '0');
|
|
@@ -1276,7 +1399,7 @@ function DragTarget(target, {} = {}) {
|
|
|
1276
1399
|
current.x = position.x - offset.x;
|
|
1277
1400
|
current.y = position.y - offset.y;
|
|
1278
1401
|
});
|
|
1279
|
-
|
|
1402
|
+
target.on('dragmove', ({ event, delta }) => {
|
|
1280
1403
|
if (dragged !== true)
|
|
1281
1404
|
return;
|
|
1282
1405
|
current.x += delta.x;
|
|
@@ -1284,9 +1407,10 @@ function DragTarget(target, {} = {}) {
|
|
|
1284
1407
|
absolute.style.left = `${current.x}px`;
|
|
1285
1408
|
absolute.style.top = `${current.y}px`;
|
|
1286
1409
|
});
|
|
1287
|
-
|
|
1410
|
+
target.on('dragend', ({ event }) => {
|
|
1288
1411
|
dragged = false;
|
|
1289
1412
|
});
|
|
1413
|
+
xnew$1.nest('<div>');
|
|
1290
1414
|
}
|
|
1291
1415
|
|
|
1292
1416
|
//----------------------------------------------------------------------------------------------------
|
|
@@ -1295,7 +1419,7 @@ function DragTarget(target, {} = {}) {
|
|
|
1295
1419
|
function SVGTemplate(self, { stroke = 'currentColor', strokeOpacity = 0.8, strokeWidth = 2, strokeLinejoin = 'round', fill = null, fillOpacity = 0.8 }) {
|
|
1296
1420
|
xnew$1.nest(`<svg
|
|
1297
1421
|
viewBox="0 0 100 100"
|
|
1298
|
-
style="position: absolute; width: 100%; height: 100%;
|
|
1422
|
+
style="position: absolute; width: 100%; height: 100%; select: none;
|
|
1299
1423
|
stroke: ${stroke}; stroke-opacity: ${strokeOpacity}; stroke-width: ${strokeWidth}; stroke-linejoin: ${strokeLinejoin};
|
|
1300
1424
|
${fill ? `fill: ${fill}; fill-opacity: ${fillOpacity};` : ''}
|
|
1301
1425
|
">`);
|
|
@@ -1305,7 +1429,7 @@ function AnalogStick(unit, { stroke = 'currentColor', strokeOpacity = 0.8, strok
|
|
|
1305
1429
|
const internal = xnew$1((unit) => {
|
|
1306
1430
|
let newsize = Math.min(outer.clientWidth, outer.clientHeight);
|
|
1307
1431
|
const inner = xnew$1.nest(`<div style="position: absolute; width: ${newsize}px; height: ${newsize}px; margin: auto; inset: 0; cursor: pointer; pointer-select: none; pointer-events: auto; overflow: hidden;">`);
|
|
1308
|
-
xnew$1(outer
|
|
1432
|
+
xnew$1(outer).on('resize', () => {
|
|
1309
1433
|
newsize = Math.min(outer.clientWidth, outer.clientHeight);
|
|
1310
1434
|
inner.style.width = `${newsize}px`;
|
|
1311
1435
|
inner.style.height = `${newsize}px`;
|
|
@@ -1321,22 +1445,21 @@ function AnalogStick(unit, { stroke = 'currentColor', strokeOpacity = 0.8, strok
|
|
|
1321
1445
|
xnew$1.extend(SVGTemplate, { fill, fillOpacity, stroke, strokeOpacity, strokeWidth, strokeLinejoin });
|
|
1322
1446
|
xnew$1('<circle cx="50" cy="50" r="23">');
|
|
1323
1447
|
});
|
|
1324
|
-
|
|
1325
|
-
direct.on('-dragstart', ({ event, position }) => {
|
|
1448
|
+
unit.on('dragstart', ({ event, position }) => {
|
|
1326
1449
|
const vector = getVector(position);
|
|
1327
1450
|
target.element.style.filter = 'brightness(90%)';
|
|
1328
1451
|
target.element.style.left = vector.x * newsize / 4 + 'px';
|
|
1329
1452
|
target.element.style.top = vector.y * newsize / 4 + 'px';
|
|
1330
1453
|
xnew$1.emit('-down', { vector });
|
|
1331
1454
|
});
|
|
1332
|
-
|
|
1455
|
+
unit.on('dragmove', ({ event, position }) => {
|
|
1333
1456
|
const vector = getVector(position);
|
|
1334
1457
|
target.element.style.filter = 'brightness(90%)';
|
|
1335
1458
|
target.element.style.left = vector.x * newsize / 4 + 'px';
|
|
1336
1459
|
target.element.style.top = vector.y * newsize / 4 + 'px';
|
|
1337
1460
|
xnew$1.emit('-move', { vector });
|
|
1338
1461
|
});
|
|
1339
|
-
|
|
1462
|
+
unit.on('dragend', ({ event }) => {
|
|
1340
1463
|
const vector = { x: 0, y: 0 };
|
|
1341
1464
|
target.element.style.filter = '';
|
|
1342
1465
|
target.element.style.left = vector.x * newsize / 4 + 'px';
|
|
@@ -1360,7 +1483,7 @@ function DirectionalPad(unit, { diagonal = true, stroke = 'currentColor', stroke
|
|
|
1360
1483
|
const internal = xnew$1((unit) => {
|
|
1361
1484
|
let newsize = Math.min(outer.clientWidth, outer.clientHeight);
|
|
1362
1485
|
const inner = xnew$1.nest(`<div style="position: absolute; width: ${newsize}px; height: ${newsize}px; margin: auto; inset: 0; cursor: pointer; pointer-select: none; pointer-events: auto; overflow: hidden;">`);
|
|
1363
|
-
xnew$1(outer
|
|
1486
|
+
xnew$1(outer).on('resize', () => {
|
|
1364
1487
|
newsize = Math.min(outer.clientWidth, outer.clientHeight);
|
|
1365
1488
|
inner.style.width = `${newsize}px`;
|
|
1366
1489
|
inner.style.height = `${newsize}px`;
|
|
@@ -1388,8 +1511,7 @@ function DirectionalPad(unit, { diagonal = true, stroke = 'currentColor', stroke
|
|
|
1388
1511
|
xnew$1('<polygon points="11 50 20 42 20 58">');
|
|
1389
1512
|
xnew$1('<polygon points="89 50 80 42 80 58">');
|
|
1390
1513
|
});
|
|
1391
|
-
|
|
1392
|
-
direct.on('-dragstart', ({ event, position }) => {
|
|
1514
|
+
unit.on('dragstart', ({ event, position }) => {
|
|
1393
1515
|
const vector = getVector(position);
|
|
1394
1516
|
targets[0].element.style.filter = (vector.y < 0) ? 'brightness(90%)' : '';
|
|
1395
1517
|
targets[1].element.style.filter = (vector.y > 0) ? 'brightness(90%)' : '';
|
|
@@ -1397,7 +1519,7 @@ function DirectionalPad(unit, { diagonal = true, stroke = 'currentColor', stroke
|
|
|
1397
1519
|
targets[3].element.style.filter = (vector.x > 0) ? 'brightness(90%)' : '';
|
|
1398
1520
|
xnew$1.emit('-down', { vector });
|
|
1399
1521
|
});
|
|
1400
|
-
|
|
1522
|
+
unit.on('dragmove', ({ event, position }) => {
|
|
1401
1523
|
const vector = getVector(position);
|
|
1402
1524
|
targets[0].element.style.filter = (vector.y < 0) ? 'brightness(90%)' : '';
|
|
1403
1525
|
targets[1].element.style.filter = (vector.y > 0) ? 'brightness(90%)' : '';
|
|
@@ -1405,7 +1527,7 @@ function DirectionalPad(unit, { diagonal = true, stroke = 'currentColor', stroke
|
|
|
1405
1527
|
targets[3].element.style.filter = (vector.x > 0) ? 'brightness(90%)' : '';
|
|
1406
1528
|
xnew$1.emit('-move', { vector });
|
|
1407
1529
|
});
|
|
1408
|
-
|
|
1530
|
+
unit.on('dragend', ({ event }) => {
|
|
1409
1531
|
const vector = { x: 0, y: 0 };
|
|
1410
1532
|
targets[0].element.style.filter = '';
|
|
1411
1533
|
targets[1].element.style.filter = '';
|
|
@@ -1457,249 +1579,29 @@ function TextStream(unit, { text = '', speed = 50, fade = 300 } = {}) {
|
|
|
1457
1579
|
const index = Math.floor((new Date().getTime() - start) / speed);
|
|
1458
1580
|
// Display characters up to the current index (fade in)
|
|
1459
1581
|
for (let i = 0; i < chars.length; i++) {
|
|
1460
|
-
if (i <= index) {
|
|
1461
|
-
chars[i].element.style.opacity = '1';
|
|
1462
|
-
}
|
|
1463
|
-
}
|
|
1464
|
-
if (state === 0 && index >= text.length) {
|
|
1465
|
-
action();
|
|
1466
|
-
}
|
|
1467
|
-
});
|
|
1468
|
-
xnew$1.timeout(() => {
|
|
1469
|
-
xnew$1(document.body).on('click wheel', action);
|
|
1470
|
-
xnew$1(DirectEvent).on('-keydown', action);
|
|
1471
|
-
}, 100);
|
|
1472
|
-
function action() {
|
|
1473
|
-
if (state === 0) {
|
|
1474
|
-
state = 1;
|
|
1475
|
-
for (let i = 0; i < chars.length; i++) {
|
|
1476
|
-
chars[i].element.style.opacity = '1';
|
|
1477
|
-
}
|
|
1478
|
-
xnew$1.emit('-complete');
|
|
1479
|
-
}
|
|
1480
|
-
else if (state === 1) {
|
|
1481
|
-
state = 2;
|
|
1482
|
-
xnew$1.emit('-next');
|
|
1483
|
-
}
|
|
1484
|
-
}
|
|
1485
|
-
}
|
|
1486
|
-
|
|
1487
|
-
const context = window.AudioContext ? new window.AudioContext() : (null);
|
|
1488
|
-
const master = context ? context.createGain() : (null);
|
|
1489
|
-
if (context) {
|
|
1490
|
-
master.gain.value = 0.1;
|
|
1491
|
-
master.connect(context.destination);
|
|
1492
|
-
}
|
|
1493
|
-
class AudioFile {
|
|
1494
|
-
constructor(path) {
|
|
1495
|
-
this.promise = fetch(path)
|
|
1496
|
-
.then((response) => response.arrayBuffer())
|
|
1497
|
-
.then((response) => context.decodeAudioData(response))
|
|
1498
|
-
.then((response) => { this.buffer = response; })
|
|
1499
|
-
.catch(() => {
|
|
1500
|
-
console.warn(`"${path}" could not be loaded.`);
|
|
1501
|
-
});
|
|
1502
|
-
this.amp = context.createGain();
|
|
1503
|
-
this.amp.gain.value = 1.0;
|
|
1504
|
-
this.amp.connect(master);
|
|
1505
|
-
this.fade = context.createGain();
|
|
1506
|
-
this.fade.gain.value = 1.0;
|
|
1507
|
-
this.fade.connect(this.amp);
|
|
1508
|
-
this.source = null;
|
|
1509
|
-
this.played = null;
|
|
1510
|
-
}
|
|
1511
|
-
set volume(value) {
|
|
1512
|
-
this.amp.gain.value = value;
|
|
1513
|
-
}
|
|
1514
|
-
get volume() {
|
|
1515
|
-
return this.amp.gain.value;
|
|
1516
|
-
}
|
|
1517
|
-
play({ offset = 0, fade = 0, loop = false } = {}) {
|
|
1518
|
-
if (this.buffer !== undefined && this.played === null) {
|
|
1519
|
-
this.source = context.createBufferSource();
|
|
1520
|
-
this.source.buffer = this.buffer;
|
|
1521
|
-
this.source.loop = loop;
|
|
1522
|
-
this.source.connect(this.fade);
|
|
1523
|
-
this.played = context.currentTime;
|
|
1524
|
-
this.source.playbackRate.value = 1;
|
|
1525
|
-
this.source.start(context.currentTime, offset / 1000);
|
|
1526
|
-
// Apply fade-in effect if fade duration is specified
|
|
1527
|
-
if (fade > 0) {
|
|
1528
|
-
this.fade.gain.setValueAtTime(0, context.currentTime);
|
|
1529
|
-
this.fade.gain.linearRampToValueAtTime(1.0, context.currentTime + fade / 1000);
|
|
1530
|
-
}
|
|
1531
|
-
this.source.onended = () => {
|
|
1532
|
-
var _a;
|
|
1533
|
-
this.played = null;
|
|
1534
|
-
(_a = this.source) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
1535
|
-
this.source = null;
|
|
1536
|
-
};
|
|
1537
|
-
}
|
|
1538
|
-
}
|
|
1539
|
-
pause({ fade = 0 } = {}) {
|
|
1540
|
-
var _a, _b;
|
|
1541
|
-
if (this.buffer !== undefined && this.played !== null) {
|
|
1542
|
-
const elapsed = (context.currentTime - this.played) % this.buffer.duration * 1000;
|
|
1543
|
-
// Apply fade-out effect if fade duration is specified
|
|
1544
|
-
if (fade > 0) {
|
|
1545
|
-
this.fade.gain.setValueAtTime(1.0, context.currentTime);
|
|
1546
|
-
this.fade.gain.linearRampToValueAtTime(0, context.currentTime + fade / 1000);
|
|
1547
|
-
(_a = this.source) === null || _a === void 0 ? void 0 : _a.stop(context.currentTime + fade / 1000);
|
|
1548
|
-
}
|
|
1549
|
-
else {
|
|
1550
|
-
(_b = this.source) === null || _b === void 0 ? void 0 : _b.stop(context.currentTime);
|
|
1551
|
-
}
|
|
1552
|
-
this.played = null;
|
|
1553
|
-
return elapsed;
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
clear() {
|
|
1557
|
-
var _a;
|
|
1558
|
-
this.amp.disconnect();
|
|
1559
|
-
this.fade.disconnect();
|
|
1560
|
-
(_a = this.source) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
1561
|
-
}
|
|
1562
|
-
}
|
|
1563
|
-
const keymap = {
|
|
1564
|
-
'A0': 27.500, 'A#0': 29.135, 'B0': 30.868,
|
|
1565
|
-
'C1': 32.703, 'C#1': 34.648, 'D1': 36.708, 'D#1': 38.891, 'E1': 41.203, 'F1': 43.654, 'F#1': 46.249, 'G1': 48.999, 'G#1': 51.913, 'A1': 55.000, 'A#1': 58.270, 'B1': 61.735,
|
|
1566
|
-
'C2': 65.406, 'C#2': 69.296, 'D2': 73.416, 'D#2': 77.782, 'E2': 82.407, 'F2': 87.307, 'F#2': 92.499, 'G2': 97.999, 'G#2': 103.826, 'A2': 110.000, 'A#2': 116.541, 'B2': 123.471,
|
|
1567
|
-
'C3': 130.813, 'C#3': 138.591, 'D3': 146.832, 'D#3': 155.563, 'E3': 164.814, 'F3': 174.614, 'F#3': 184.997, 'G3': 195.998, 'G#3': 207.652, 'A3': 220.000, 'A#3': 233.082, 'B3': 246.942,
|
|
1568
|
-
'C4': 261.626, 'C#4': 277.183, 'D4': 293.665, 'D#4': 311.127, 'E4': 329.628, 'F4': 349.228, 'F#4': 369.994, 'G4': 391.995, 'G#4': 415.305, 'A4': 440.000, 'A#4': 466.164, 'B4': 493.883,
|
|
1569
|
-
'C5': 523.251, 'C#5': 554.365, 'D5': 587.330, 'D#5': 622.254, 'E5': 659.255, 'F5': 698.456, 'F#5': 739.989, 'G5': 783.991, 'G#5': 830.609, 'A5': 880.000, 'A#5': 932.328, 'B5': 987.767,
|
|
1570
|
-
'C6': 1046.502, 'C#6': 1108.731, 'D6': 1174.659, 'D#6': 1244.508, 'E6': 1318.510, 'F6': 1396.913, 'F#6': 1479.978, 'G6': 1567.982, 'G#6': 1661.219, 'A6': 1760.000, 'A#6': 1864.655, 'B6': 1975.533,
|
|
1571
|
-
'C7': 2093.005, 'C#7': 2217.461, 'D7': 2349.318, 'D#7': 2489.016, 'E7': 2637.020, 'F7': 2793.826, 'F#7': 2959.955, 'G7': 3135.963, 'G#7': 3322.438, 'A7': 3520.000, 'A#7': 3729.310, 'B7': 3951.066,
|
|
1572
|
-
'C8': 4186.009,
|
|
1573
|
-
};
|
|
1574
|
-
const notemap = {
|
|
1575
|
-
'1m': 4.000, '2n': 2.000, '4n': 1.000, '8n': 0.500, '16n': 0.250, '32n': 0.125,
|
|
1576
|
-
};
|
|
1577
|
-
class Synthesizer {
|
|
1578
|
-
constructor(props) { this.props = props; }
|
|
1579
|
-
press(frequency, duration, wait) {
|
|
1580
|
-
var _a;
|
|
1581
|
-
const props = this.props;
|
|
1582
|
-
const fv = typeof frequency === 'string' ? keymap[frequency] : frequency;
|
|
1583
|
-
const dv = typeof duration === 'string' ? (notemap[duration] * 60 / ((_a = props.bpm) !== null && _a !== void 0 ? _a : 120)) : (typeof duration === 'number' ? (duration / 1000) : 0);
|
|
1584
|
-
const start = context.currentTime + (wait !== null && wait !== void 0 ? wait : 0) / 1000;
|
|
1585
|
-
const nodes = {};
|
|
1586
|
-
nodes.oscillator = context.createOscillator();
|
|
1587
|
-
nodes.oscillator.type = props.oscillator.type;
|
|
1588
|
-
nodes.oscillator.frequency.value = fv;
|
|
1589
|
-
if (props.oscillator.LFO) {
|
|
1590
|
-
nodes.oscillatorLFO = context.createOscillator();
|
|
1591
|
-
nodes.oscillatorLFODepth = context.createGain();
|
|
1592
|
-
nodes.oscillatorLFODepth.gain.value = fv * (Math.pow(2.0, props.oscillator.LFO.amount / 12.0) - 1.0);
|
|
1593
|
-
nodes.oscillatorLFO.type = props.oscillator.LFO.type;
|
|
1594
|
-
nodes.oscillatorLFO.frequency.value = props.oscillator.LFO.rate;
|
|
1595
|
-
nodes.oscillatorLFO.start(start);
|
|
1596
|
-
nodes.oscillatorLFO.connect(nodes.oscillatorLFODepth);
|
|
1597
|
-
nodes.oscillatorLFODepth.connect(nodes.oscillator.frequency);
|
|
1598
|
-
}
|
|
1599
|
-
nodes.amp = context.createGain();
|
|
1600
|
-
nodes.amp.gain.value = 0.0;
|
|
1601
|
-
nodes.target = context.createGain();
|
|
1602
|
-
nodes.target.gain.value = 1.0;
|
|
1603
|
-
nodes.amp.connect(nodes.target);
|
|
1604
|
-
nodes.target.connect(master);
|
|
1605
|
-
if (props.filter) {
|
|
1606
|
-
nodes.filter = context.createBiquadFilter();
|
|
1607
|
-
nodes.filter.type = props.filter.type;
|
|
1608
|
-
nodes.filter.frequency.value = props.filter.cutoff;
|
|
1609
|
-
nodes.oscillator.connect(nodes.filter);
|
|
1610
|
-
nodes.filter.connect(nodes.amp);
|
|
1611
|
-
}
|
|
1612
|
-
else {
|
|
1613
|
-
nodes.oscillator.connect(nodes.amp);
|
|
1614
|
-
}
|
|
1615
|
-
if (props.reverb) {
|
|
1616
|
-
nodes.convolver = context.createConvolver();
|
|
1617
|
-
nodes.convolver.buffer = impulseResponse({ time: props.reverb.time });
|
|
1618
|
-
nodes.convolverDepth = context.createGain();
|
|
1619
|
-
nodes.convolverDepth.gain.value = 1.0;
|
|
1620
|
-
nodes.convolverDepth.gain.value *= props.reverb.mix;
|
|
1621
|
-
nodes.target.gain.value *= (1.0 - props.reverb.mix);
|
|
1622
|
-
nodes.amp.connect(nodes.convolver);
|
|
1623
|
-
nodes.convolver.connect(nodes.convolverDepth);
|
|
1624
|
-
nodes.convolverDepth.connect(master);
|
|
1625
|
-
}
|
|
1626
|
-
if (props.oscillator.envelope) {
|
|
1627
|
-
const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
|
|
1628
|
-
startEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
|
|
1629
|
-
}
|
|
1630
|
-
if (props.amp.envelope) {
|
|
1631
|
-
startEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
|
|
1632
|
-
}
|
|
1633
|
-
nodes.oscillator.start(start);
|
|
1634
|
-
if (dv > 0) {
|
|
1635
|
-
release();
|
|
1636
|
-
}
|
|
1637
|
-
else {
|
|
1638
|
-
return { release };
|
|
1639
|
-
}
|
|
1640
|
-
function release() {
|
|
1641
|
-
let stop = null;
|
|
1642
|
-
const end = dv > 0 ? dv : (context.currentTime - start);
|
|
1643
|
-
if (props.amp.envelope) {
|
|
1644
|
-
const ADSR = props.amp.envelope.ADSR;
|
|
1645
|
-
const adsr = [ADSR[0] / 1000, ADSR[1] / 1000, ADSR[2], ADSR[3] / 1000];
|
|
1646
|
-
const rate = adsr[0] === 0.0 ? 1.0 : Math.min(end / (adsr[0] + 0.001), 1.0);
|
|
1647
|
-
stop = start + Math.max((adsr[0] + adsr[1]) * rate, end) + adsr[3];
|
|
1648
|
-
}
|
|
1649
|
-
else {
|
|
1650
|
-
stop = start + end;
|
|
1651
|
-
}
|
|
1652
|
-
if (nodes.oscillatorLFO) {
|
|
1653
|
-
nodes.oscillatorLFO.stop(stop);
|
|
1654
|
-
}
|
|
1655
|
-
if (props.oscillator.envelope) {
|
|
1656
|
-
const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
|
|
1657
|
-
stopEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
|
|
1658
|
-
}
|
|
1659
|
-
if (props.amp.envelope) {
|
|
1660
|
-
stopEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
|
|
1661
|
-
}
|
|
1662
|
-
nodes.oscillator.stop(stop);
|
|
1663
|
-
setTimeout(() => {
|
|
1664
|
-
var _a, _b, _c, _d, _e;
|
|
1665
|
-
nodes.oscillator.disconnect();
|
|
1666
|
-
nodes.amp.disconnect();
|
|
1667
|
-
nodes.target.disconnect();
|
|
1668
|
-
(_a = nodes.oscillatorLFO) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
1669
|
-
(_b = nodes.oscillatorLFODepth) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
1670
|
-
(_c = nodes.filter) === null || _c === void 0 ? void 0 : _c.disconnect();
|
|
1671
|
-
(_d = nodes.convolver) === null || _d === void 0 ? void 0 : _d.disconnect();
|
|
1672
|
-
(_e = nodes.convolverDepth) === null || _e === void 0 ? void 0 : _e.disconnect();
|
|
1673
|
-
}, 2000);
|
|
1674
|
-
}
|
|
1675
|
-
function stopEnvelope(param, base, amount, ADSR) {
|
|
1676
|
-
const end = dv > 0 ? dv : (context.currentTime - start);
|
|
1677
|
-
const rate = ADSR[0] === 0.0 ? 1.0 : Math.min(end / (ADSR[0] / 1000), 1.0);
|
|
1678
|
-
if (rate < 1.0) {
|
|
1679
|
-
param.cancelScheduledValues(start);
|
|
1680
|
-
param.setValueAtTime(base, start);
|
|
1681
|
-
param.linearRampToValueAtTime(base + amount * rate, start + ADSR[0] / 1000 * rate);
|
|
1682
|
-
param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000 * rate);
|
|
1582
|
+
if (i <= index) {
|
|
1583
|
+
chars[i].element.style.opacity = '1';
|
|
1683
1584
|
}
|
|
1684
|
-
param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dv));
|
|
1685
|
-
param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, end) + ADSR[3] / 1000);
|
|
1686
1585
|
}
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
param.setValueAtTime(base, start);
|
|
1690
|
-
param.linearRampToValueAtTime(base + amount, start + ADSR[0] / 1000);
|
|
1691
|
-
param.linearRampToValueAtTime(base + amount * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000);
|
|
1586
|
+
if (state === 0 && index >= text.length) {
|
|
1587
|
+
action();
|
|
1692
1588
|
}
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1589
|
+
});
|
|
1590
|
+
xnew$1.timeout(() => {
|
|
1591
|
+
xnew$1(document.body).on('click wheel', action);
|
|
1592
|
+
unit.on('keydown', action);
|
|
1593
|
+
}, 100);
|
|
1594
|
+
function action() {
|
|
1595
|
+
if (state === 0) {
|
|
1596
|
+
state = 1;
|
|
1597
|
+
for (let i = 0; i < chars.length; i++) {
|
|
1598
|
+
chars[i].element.style.opacity = '1';
|
|
1701
1599
|
}
|
|
1702
|
-
|
|
1600
|
+
xnew$1.emit('-complete');
|
|
1601
|
+
}
|
|
1602
|
+
else if (state === 1) {
|
|
1603
|
+
state = 2;
|
|
1604
|
+
xnew$1.emit('-next');
|
|
1703
1605
|
}
|
|
1704
1606
|
}
|
|
1705
1607
|
}
|
|
@@ -3346,35 +3248,228 @@ const icons = {
|
|
|
3346
3248
|
XMark(unit, props) { icon('XMark', props); },
|
|
3347
3249
|
};
|
|
3348
3250
|
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3251
|
+
const context = window.AudioContext ? new window.AudioContext() : (null);
|
|
3252
|
+
const master = context ? context.createGain() : (null);
|
|
3253
|
+
if (context) {
|
|
3254
|
+
master.gain.value = 0.1;
|
|
3255
|
+
master.connect(context.destination);
|
|
3256
|
+
}
|
|
3257
|
+
class AudioFile {
|
|
3258
|
+
constructor(path) {
|
|
3259
|
+
this.promise = fetch(path)
|
|
3260
|
+
.then((response) => response.arrayBuffer())
|
|
3261
|
+
.then((response) => context.decodeAudioData(response))
|
|
3262
|
+
.then((response) => { this.buffer = response; })
|
|
3263
|
+
.catch(() => {
|
|
3264
|
+
console.warn(`"${path}" could not be loaded.`);
|
|
3265
|
+
});
|
|
3266
|
+
this.amp = context.createGain();
|
|
3267
|
+
this.amp.gain.value = 1.0;
|
|
3268
|
+
this.amp.connect(master);
|
|
3269
|
+
this.fade = context.createGain();
|
|
3270
|
+
this.fade.gain.value = 1.0;
|
|
3271
|
+
this.fade.connect(this.amp);
|
|
3272
|
+
this.source = null;
|
|
3273
|
+
this.played = null;
|
|
3274
|
+
}
|
|
3275
|
+
set volume(value) {
|
|
3276
|
+
this.amp.gain.value = value;
|
|
3277
|
+
}
|
|
3278
|
+
get volume() {
|
|
3279
|
+
return this.amp.gain.value;
|
|
3280
|
+
}
|
|
3281
|
+
play({ offset = 0, fade = 0, loop = false } = {}) {
|
|
3282
|
+
if (this.buffer !== undefined && this.played === null) {
|
|
3283
|
+
this.source = context.createBufferSource();
|
|
3284
|
+
this.source.buffer = this.buffer;
|
|
3285
|
+
this.source.loop = loop;
|
|
3286
|
+
this.source.connect(this.fade);
|
|
3287
|
+
this.played = context.currentTime;
|
|
3288
|
+
this.source.playbackRate.value = 1;
|
|
3289
|
+
this.source.start(context.currentTime, offset / 1000);
|
|
3290
|
+
// Apply fade-in effect if fade duration is specified
|
|
3291
|
+
if (fade > 0) {
|
|
3292
|
+
this.fade.gain.setValueAtTime(0, context.currentTime);
|
|
3293
|
+
this.fade.gain.linearRampToValueAtTime(1.0, context.currentTime + fade / 1000);
|
|
3364
3294
|
}
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3295
|
+
this.source.onended = () => {
|
|
3296
|
+
var _a;
|
|
3297
|
+
this.played = null;
|
|
3298
|
+
(_a = this.source) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
3299
|
+
this.source = null;
|
|
3300
|
+
};
|
|
3301
|
+
}
|
|
3302
|
+
}
|
|
3303
|
+
pause({ fade = 0 } = {}) {
|
|
3304
|
+
var _a, _b;
|
|
3305
|
+
if (this.buffer !== undefined && this.played !== null) {
|
|
3306
|
+
const elapsed = (context.currentTime - this.played) % this.buffer.duration * 1000;
|
|
3307
|
+
// Apply fade-out effect if fade duration is specified
|
|
3308
|
+
if (fade > 0) {
|
|
3309
|
+
this.fade.gain.setValueAtTime(1.0, context.currentTime);
|
|
3310
|
+
this.fade.gain.linearRampToValueAtTime(0, context.currentTime + fade / 1000);
|
|
3311
|
+
(_a = this.source) === null || _a === void 0 ? void 0 : _a.stop(context.currentTime + fade / 1000);
|
|
3312
|
+
}
|
|
3313
|
+
else {
|
|
3314
|
+
(_b = this.source) === null || _b === void 0 ? void 0 : _b.stop(context.currentTime);
|
|
3315
|
+
}
|
|
3316
|
+
this.played = null;
|
|
3317
|
+
return elapsed;
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3320
|
+
clear() {
|
|
3321
|
+
var _a;
|
|
3322
|
+
this.amp.disconnect();
|
|
3323
|
+
this.fade.disconnect();
|
|
3324
|
+
(_a = this.source) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
const keymap = {
|
|
3328
|
+
'A0': 27.500, 'A#0': 29.135, 'B0': 30.868,
|
|
3329
|
+
'C1': 32.703, 'C#1': 34.648, 'D1': 36.708, 'D#1': 38.891, 'E1': 41.203, 'F1': 43.654, 'F#1': 46.249, 'G1': 48.999, 'G#1': 51.913, 'A1': 55.000, 'A#1': 58.270, 'B1': 61.735,
|
|
3330
|
+
'C2': 65.406, 'C#2': 69.296, 'D2': 73.416, 'D#2': 77.782, 'E2': 82.407, 'F2': 87.307, 'F#2': 92.499, 'G2': 97.999, 'G#2': 103.826, 'A2': 110.000, 'A#2': 116.541, 'B2': 123.471,
|
|
3331
|
+
'C3': 130.813, 'C#3': 138.591, 'D3': 146.832, 'D#3': 155.563, 'E3': 164.814, 'F3': 174.614, 'F#3': 184.997, 'G3': 195.998, 'G#3': 207.652, 'A3': 220.000, 'A#3': 233.082, 'B3': 246.942,
|
|
3332
|
+
'C4': 261.626, 'C#4': 277.183, 'D4': 293.665, 'D#4': 311.127, 'E4': 329.628, 'F4': 349.228, 'F#4': 369.994, 'G4': 391.995, 'G#4': 415.305, 'A4': 440.000, 'A#4': 466.164, 'B4': 493.883,
|
|
3333
|
+
'C5': 523.251, 'C#5': 554.365, 'D5': 587.330, 'D#5': 622.254, 'E5': 659.255, 'F5': 698.456, 'F#5': 739.989, 'G5': 783.991, 'G#5': 830.609, 'A5': 880.000, 'A#5': 932.328, 'B5': 987.767,
|
|
3334
|
+
'C6': 1046.502, 'C#6': 1108.731, 'D6': 1174.659, 'D#6': 1244.508, 'E6': 1318.510, 'F6': 1396.913, 'F#6': 1479.978, 'G6': 1567.982, 'G#6': 1661.219, 'A6': 1760.000, 'A#6': 1864.655, 'B6': 1975.533,
|
|
3335
|
+
'C7': 2093.005, 'C#7': 2217.461, 'D7': 2349.318, 'D#7': 2489.016, 'E7': 2637.020, 'F7': 2793.826, 'F#7': 2959.955, 'G7': 3135.963, 'G#7': 3322.438, 'A7': 3520.000, 'A#7': 3729.310, 'B7': 3951.066,
|
|
3336
|
+
'C8': 4186.009,
|
|
3337
|
+
};
|
|
3338
|
+
const notemap = {
|
|
3339
|
+
'1m': 4.000, '2n': 2.000, '4n': 1.000, '8n': 0.500, '16n': 0.250, '32n': 0.125,
|
|
3340
|
+
};
|
|
3341
|
+
class Synthesizer {
|
|
3342
|
+
constructor(props) { this.props = props; }
|
|
3343
|
+
press(frequency, duration, wait) {
|
|
3344
|
+
var _a;
|
|
3345
|
+
const props = this.props;
|
|
3346
|
+
const fv = typeof frequency === 'string' ? keymap[frequency] : frequency;
|
|
3347
|
+
const dv = typeof duration === 'string' ? (notemap[duration] * 60 / ((_a = props.bpm) !== null && _a !== void 0 ? _a : 120)) : (typeof duration === 'number' ? (duration / 1000) : 0);
|
|
3348
|
+
const start = context.currentTime + (wait !== null && wait !== void 0 ? wait : 0) / 1000;
|
|
3349
|
+
const nodes = {};
|
|
3350
|
+
nodes.oscillator = context.createOscillator();
|
|
3351
|
+
nodes.oscillator.type = props.oscillator.type;
|
|
3352
|
+
nodes.oscillator.frequency.value = fv;
|
|
3353
|
+
if (props.oscillator.LFO) {
|
|
3354
|
+
nodes.oscillatorLFO = context.createOscillator();
|
|
3355
|
+
nodes.oscillatorLFODepth = context.createGain();
|
|
3356
|
+
nodes.oscillatorLFODepth.gain.value = fv * (Math.pow(2.0, props.oscillator.LFO.amount / 12.0) - 1.0);
|
|
3357
|
+
nodes.oscillatorLFO.type = props.oscillator.LFO.type;
|
|
3358
|
+
nodes.oscillatorLFO.frequency.value = props.oscillator.LFO.rate;
|
|
3359
|
+
nodes.oscillatorLFO.start(start);
|
|
3360
|
+
nodes.oscillatorLFO.connect(nodes.oscillatorLFODepth);
|
|
3361
|
+
nodes.oscillatorLFODepth.connect(nodes.oscillator.frequency);
|
|
3362
|
+
}
|
|
3363
|
+
nodes.amp = context.createGain();
|
|
3364
|
+
nodes.amp.gain.value = 0.0;
|
|
3365
|
+
nodes.target = context.createGain();
|
|
3366
|
+
nodes.target.gain.value = 1.0;
|
|
3367
|
+
nodes.amp.connect(nodes.target);
|
|
3368
|
+
nodes.target.connect(master);
|
|
3369
|
+
if (props.filter) {
|
|
3370
|
+
nodes.filter = context.createBiquadFilter();
|
|
3371
|
+
nodes.filter.type = props.filter.type;
|
|
3372
|
+
nodes.filter.frequency.value = props.filter.cutoff;
|
|
3373
|
+
nodes.oscillator.connect(nodes.filter);
|
|
3374
|
+
nodes.filter.connect(nodes.amp);
|
|
3375
|
+
}
|
|
3376
|
+
else {
|
|
3377
|
+
nodes.oscillator.connect(nodes.amp);
|
|
3378
|
+
}
|
|
3379
|
+
if (props.reverb) {
|
|
3380
|
+
nodes.convolver = context.createConvolver();
|
|
3381
|
+
nodes.convolver.buffer = impulseResponse({ time: props.reverb.time });
|
|
3382
|
+
nodes.convolverDepth = context.createGain();
|
|
3383
|
+
nodes.convolverDepth.gain.value = 1.0;
|
|
3384
|
+
nodes.convolverDepth.gain.value *= props.reverb.mix;
|
|
3385
|
+
nodes.target.gain.value *= (1.0 - props.reverb.mix);
|
|
3386
|
+
nodes.amp.connect(nodes.convolver);
|
|
3387
|
+
nodes.convolver.connect(nodes.convolverDepth);
|
|
3388
|
+
nodes.convolverDepth.connect(master);
|
|
3389
|
+
}
|
|
3390
|
+
if (props.oscillator.envelope) {
|
|
3391
|
+
const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
|
|
3392
|
+
startEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
|
|
3393
|
+
}
|
|
3394
|
+
if (props.amp.envelope) {
|
|
3395
|
+
startEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
|
|
3396
|
+
}
|
|
3397
|
+
nodes.oscillator.start(start);
|
|
3398
|
+
if (dv > 0) {
|
|
3399
|
+
release();
|
|
3400
|
+
}
|
|
3401
|
+
else {
|
|
3402
|
+
return { release };
|
|
3403
|
+
}
|
|
3404
|
+
function release() {
|
|
3405
|
+
let stop = null;
|
|
3406
|
+
const end = dv > 0 ? dv : (context.currentTime - start);
|
|
3407
|
+
if (props.amp.envelope) {
|
|
3408
|
+
const ADSR = props.amp.envelope.ADSR;
|
|
3409
|
+
const adsr = [ADSR[0] / 1000, ADSR[1] / 1000, ADSR[2], ADSR[3] / 1000];
|
|
3410
|
+
const rate = adsr[0] === 0.0 ? 1.0 : Math.min(end / (adsr[0] + 0.001), 1.0);
|
|
3411
|
+
stop = start + Math.max((adsr[0] + adsr[1]) * rate, end) + adsr[3];
|
|
3412
|
+
}
|
|
3413
|
+
else {
|
|
3414
|
+
stop = start + end;
|
|
3415
|
+
}
|
|
3416
|
+
if (nodes.oscillatorLFO) {
|
|
3417
|
+
nodes.oscillatorLFO.stop(stop);
|
|
3418
|
+
}
|
|
3419
|
+
if (props.oscillator.envelope) {
|
|
3420
|
+
const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
|
|
3421
|
+
stopEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
|
|
3422
|
+
}
|
|
3423
|
+
if (props.amp.envelope) {
|
|
3424
|
+
stopEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
|
|
3425
|
+
}
|
|
3426
|
+
nodes.oscillator.stop(stop);
|
|
3427
|
+
setTimeout(() => {
|
|
3428
|
+
var _a, _b, _c, _d, _e;
|
|
3429
|
+
nodes.oscillator.disconnect();
|
|
3430
|
+
nodes.amp.disconnect();
|
|
3431
|
+
nodes.target.disconnect();
|
|
3432
|
+
(_a = nodes.oscillatorLFO) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
3433
|
+
(_b = nodes.oscillatorLFODepth) === null || _b === void 0 ? void 0 : _b.disconnect();
|
|
3434
|
+
(_c = nodes.filter) === null || _c === void 0 ? void 0 : _c.disconnect();
|
|
3435
|
+
(_d = nodes.convolver) === null || _d === void 0 ? void 0 : _d.disconnect();
|
|
3436
|
+
(_e = nodes.convolverDepth) === null || _e === void 0 ? void 0 : _e.disconnect();
|
|
3437
|
+
}, 2000);
|
|
3438
|
+
}
|
|
3439
|
+
function stopEnvelope(param, base, amount, ADSR) {
|
|
3440
|
+
const end = dv > 0 ? dv : (context.currentTime - start);
|
|
3441
|
+
const rate = ADSR[0] === 0.0 ? 1.0 : Math.min(end / (ADSR[0] / 1000), 1.0);
|
|
3442
|
+
if (rate < 1.0) {
|
|
3443
|
+
param.cancelScheduledValues(start);
|
|
3444
|
+
param.setValueAtTime(base, start);
|
|
3445
|
+
param.linearRampToValueAtTime(base + amount * rate, start + ADSR[0] / 1000 * rate);
|
|
3446
|
+
param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000 * rate);
|
|
3447
|
+
}
|
|
3448
|
+
param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dv));
|
|
3449
|
+
param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, end) + ADSR[3] / 1000);
|
|
3450
|
+
}
|
|
3451
|
+
function startEnvelope(param, base, amount, ADSR) {
|
|
3452
|
+
param.value = base;
|
|
3453
|
+
param.setValueAtTime(base, start);
|
|
3454
|
+
param.linearRampToValueAtTime(base + amount, start + ADSR[0] / 1000);
|
|
3455
|
+
param.linearRampToValueAtTime(base + amount * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000);
|
|
3456
|
+
}
|
|
3457
|
+
function impulseResponse({ time, decay = 2.0 }) {
|
|
3458
|
+
const length = context.sampleRate * time / 1000;
|
|
3459
|
+
const impulse = context.createBuffer(2, length, context.sampleRate);
|
|
3460
|
+
const ch0 = impulse.getChannelData(0);
|
|
3461
|
+
const ch1 = impulse.getChannelData(1);
|
|
3462
|
+
for (let i = 0; i < length; i++) {
|
|
3463
|
+
ch0[i] = (2 * Math.random() - 1) * Math.pow(1 - i / length, decay);
|
|
3464
|
+
ch1[i] = (2 * Math.random() - 1) * Math.pow(1 - i / length, decay);
|
|
3465
|
+
}
|
|
3466
|
+
return impulse;
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3372
3469
|
}
|
|
3373
3470
|
|
|
3374
3471
|
const basics = {
|
|
3375
3472
|
Screen,
|
|
3376
|
-
DirectEvent,
|
|
3377
|
-
ResizeEvent,
|
|
3378
3473
|
ModalFrame,
|
|
3379
3474
|
ModalContent,
|
|
3380
3475
|
AccordionFrame,
|
|
@@ -3389,7 +3484,6 @@ const basics = {
|
|
|
3389
3484
|
DragTarget,
|
|
3390
3485
|
AnalogStick,
|
|
3391
3486
|
DirectionalPad,
|
|
3392
|
-
VolumeController
|
|
3393
3487
|
};
|
|
3394
3488
|
const audio = {
|
|
3395
3489
|
load(path) {
|