@mulsense/xnew 0.1.11 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/addons/xmatter.js +2 -2
- package/dist/addons/xmatter.mjs +2 -2
- package/dist/addons/xpixi.js +4 -4
- package/dist/addons/xpixi.mjs +4 -4
- package/dist/addons/xrapier2d.js +2 -2
- package/dist/addons/xrapier2d.mjs +2 -2
- package/dist/addons/xthree.js +2 -2
- package/dist/addons/xthree.mjs +2 -2
- package/dist/types/audio/audio.d.ts +1 -11
- package/dist/types/basics/Event.d.ts +1 -1
- package/dist/types/core/time.d.ts +11 -10
- package/dist/types/core/unit.d.ts +5 -28
- package/dist/types/core/xnew.d.ts +1 -14
- package/dist/xnew.d.ts +5 -34
- package/dist/xnew.js +201 -168
- package/dist/xnew.mjs +201 -168
- package/package.json +1 -1
package/dist/xnew.mjs
CHANGED
|
@@ -99,17 +99,16 @@ class MapMap extends Map {
|
|
|
99
99
|
// ticker
|
|
100
100
|
//----------------------------------------------------------------------------------------------------
|
|
101
101
|
class Ticker {
|
|
102
|
-
constructor(callback) {
|
|
102
|
+
constructor(callback, fps = 60) {
|
|
103
103
|
const self = this;
|
|
104
104
|
this.id = null;
|
|
105
105
|
let previous = 0;
|
|
106
106
|
ticker();
|
|
107
107
|
function ticker() {
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
previous = time;
|
|
108
|
+
const delta = Date.now() - previous;
|
|
109
|
+
if (delta > (1000 / fps) * 0.9) {
|
|
110
|
+
callback();
|
|
111
|
+
previous += delta;
|
|
113
112
|
}
|
|
114
113
|
self.id = requestAnimationFrame(ticker);
|
|
115
114
|
}
|
|
@@ -121,43 +120,35 @@ class Ticker {
|
|
|
121
120
|
}
|
|
122
121
|
}
|
|
123
122
|
}
|
|
124
|
-
//----------------------------------------------------------------------------------------------------
|
|
125
|
-
// timer
|
|
126
|
-
//----------------------------------------------------------------------------------------------------
|
|
127
123
|
class Timer {
|
|
128
|
-
constructor(
|
|
124
|
+
constructor(options) {
|
|
129
125
|
var _a;
|
|
130
|
-
this.
|
|
131
|
-
this.
|
|
132
|
-
this.duration = duration !== null && duration !== void 0 ? duration : 0;
|
|
133
|
-
this.loop = loop;
|
|
134
|
-
this.easing = easing;
|
|
126
|
+
this.options = options;
|
|
127
|
+
this.options.easing = (_a = this.options.easing) !== null && _a !== void 0 ? _a : 'linear';
|
|
135
128
|
this.id = null;
|
|
136
129
|
this.time = 0.0;
|
|
130
|
+
this.counter = 0;
|
|
137
131
|
this.offset = 0.0;
|
|
138
132
|
this.status = 0;
|
|
139
133
|
this.ticker = new Ticker((time) => {
|
|
140
|
-
var _a;
|
|
141
|
-
let p = Math.min(this.elapsed() / this.duration, 1.0);
|
|
142
|
-
if (easing === 'ease-out') {
|
|
134
|
+
var _a, _b;
|
|
135
|
+
let p = Math.min(this.elapsed() / this.options.duration, 1.0);
|
|
136
|
+
if (this.options.easing === 'ease-out') {
|
|
143
137
|
p = Math.pow((1.0 - Math.pow((1.0 - p), 2.0)), 0.5);
|
|
144
138
|
}
|
|
145
|
-
else if (easing === 'ease-in') {
|
|
139
|
+
else if (this.options.easing === 'ease-in') {
|
|
146
140
|
p = Math.pow((1.0 - Math.pow((1.0 - p), 0.5)), 2.0);
|
|
147
141
|
}
|
|
148
|
-
else if (easing === 'ease') {
|
|
149
|
-
p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
|
|
142
|
+
else if (this.options.easing === 'ease') {
|
|
143
|
+
p = (1.0 - Math.cos(p * Math.PI)) / 2.0; // todo
|
|
150
144
|
}
|
|
151
|
-
else if (easing === 'ease-in-out') {
|
|
145
|
+
else if (this.options.easing === 'ease-in-out') {
|
|
152
146
|
p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
|
|
153
147
|
}
|
|
154
|
-
(_a = this.transition) === null ||
|
|
148
|
+
(_b = (_a = this.options).transition) === null || _b === void 0 ? void 0 : _b.call(_a, p);
|
|
155
149
|
});
|
|
156
150
|
this.visibilitychange = () => document.hidden === false ? this._start() : this._stop();
|
|
157
151
|
document.addEventListener('visibilitychange', this.visibilitychange);
|
|
158
|
-
if (this.duration > 0.0) {
|
|
159
|
-
(_a = this.transition) === null || _a === void 0 ? void 0 : _a.call(this, 0.0);
|
|
160
|
-
}
|
|
161
152
|
this.start();
|
|
162
153
|
}
|
|
163
154
|
clear() {
|
|
@@ -182,14 +173,24 @@ class Timer {
|
|
|
182
173
|
_start() {
|
|
183
174
|
if (this.status === 1 && this.id === null) {
|
|
184
175
|
this.id = setTimeout(() => {
|
|
185
|
-
var _a, _b;
|
|
186
|
-
(_a = this.
|
|
187
|
-
(
|
|
176
|
+
var _a, _b, _c, _d;
|
|
177
|
+
(_b = (_a = this.options).transition) === null || _b === void 0 ? void 0 : _b.call(_a, 1.0);
|
|
178
|
+
(_d = (_c = this.options).timeout) === null || _d === void 0 ? void 0 : _d.call(_c, this.counter);
|
|
188
179
|
this.id = null;
|
|
189
180
|
this.time = 0.0;
|
|
181
|
+
this.counter++;
|
|
190
182
|
this.offset = 0.0;
|
|
191
|
-
this.
|
|
192
|
-
|
|
183
|
+
if (this.options.iterations === undefined) {
|
|
184
|
+
this.start();
|
|
185
|
+
}
|
|
186
|
+
else if (this.options.iterations > 1) {
|
|
187
|
+
this.options.iterations--;
|
|
188
|
+
this.start();
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
this.clear();
|
|
192
|
+
}
|
|
193
|
+
}, this.options.duration - this.offset);
|
|
193
194
|
this.time = Date.now();
|
|
194
195
|
}
|
|
195
196
|
}
|
|
@@ -206,7 +207,7 @@ class Timer {
|
|
|
206
207
|
//----------------------------------------------------------------------------------------------------
|
|
207
208
|
// utils
|
|
208
209
|
//----------------------------------------------------------------------------------------------------
|
|
209
|
-
const SYSTEM_EVENTS = ['start', 'update', 'stop', 'finalize'];
|
|
210
|
+
const SYSTEM_EVENTS = ['-start', '-update', '-stop', '-finalize'];
|
|
210
211
|
//----------------------------------------------------------------------------------------------------
|
|
211
212
|
// unit
|
|
212
213
|
//----------------------------------------------------------------------------------------------------
|
|
@@ -299,10 +300,9 @@ class Unit {
|
|
|
299
300
|
elements: [],
|
|
300
301
|
promises: [],
|
|
301
302
|
components: [],
|
|
302
|
-
|
|
303
|
-
listeners2: new MapMap(),
|
|
303
|
+
listeners: new MapMap(),
|
|
304
304
|
defines: {},
|
|
305
|
-
systems: { start: [], update: [], stop: [], finalize: [] },
|
|
305
|
+
systems: { '-start': [], '-update': [], '-stop': [], '-finalize': [] },
|
|
306
306
|
});
|
|
307
307
|
// nest html element
|
|
308
308
|
if (typeof unit._.target === 'string') {
|
|
@@ -318,9 +318,8 @@ class Unit {
|
|
|
318
318
|
if (unit._.state !== 'finalized') {
|
|
319
319
|
unit._.state = 'finalized';
|
|
320
320
|
unit._.children.forEach((child) => child.finalize());
|
|
321
|
-
unit._.systems
|
|
321
|
+
unit._.systems['-finalize'].forEach((listener) => Unit.scope(Unit.snapshot(unit), listener));
|
|
322
322
|
unit.off();
|
|
323
|
-
Unit.suboff(unit, null);
|
|
324
323
|
unit._.components.forEach((component) => Unit.component2units.delete(component, unit));
|
|
325
324
|
if (unit._.elements.length > 0) {
|
|
326
325
|
unit._.baseElement.removeChild(unit._.elements[0]);
|
|
@@ -389,7 +388,7 @@ class Unit {
|
|
|
389
388
|
if (unit._.state === 'initialized' || unit._.state === 'stopped') {
|
|
390
389
|
unit._.state = 'started';
|
|
391
390
|
unit._.children.forEach((child) => Unit.start(child));
|
|
392
|
-
unit._.systems
|
|
391
|
+
unit._.systems['-start'].forEach((listener) => Unit.scope(Unit.snapshot(unit), listener));
|
|
393
392
|
}
|
|
394
393
|
else if (unit._.state === 'started') {
|
|
395
394
|
unit._.children.forEach((child) => Unit.start(child));
|
|
@@ -399,13 +398,13 @@ class Unit {
|
|
|
399
398
|
if (unit._.state === 'started') {
|
|
400
399
|
unit._.state = 'stopped';
|
|
401
400
|
unit._.children.forEach((child) => Unit.stop(child));
|
|
402
|
-
unit._.systems
|
|
401
|
+
unit._.systems['-stop'].forEach((listener) => Unit.scope(Unit.snapshot(unit), listener));
|
|
403
402
|
}
|
|
404
403
|
}
|
|
405
404
|
static update(unit) {
|
|
406
405
|
if (unit._.state === 'started') {
|
|
407
406
|
unit._.children.forEach((child) => Unit.update(child));
|
|
408
|
-
unit._.systems
|
|
407
|
+
unit._.systems['-update'].forEach((listener) => Unit.scope(Unit.snapshot(unit), listener));
|
|
409
408
|
}
|
|
410
409
|
}
|
|
411
410
|
static reset() {
|
|
@@ -413,7 +412,7 @@ class Unit {
|
|
|
413
412
|
(_a = Unit.root) === null || _a === void 0 ? void 0 : _a.finalize();
|
|
414
413
|
Unit.current = Unit.root = new Unit(null, null);
|
|
415
414
|
(_b = Unit.ticker) === null || _b === void 0 ? void 0 : _b.clear();
|
|
416
|
-
Unit.ticker = new Ticker((
|
|
415
|
+
Unit.ticker = new Ticker(() => {
|
|
417
416
|
Unit.start(Unit.root);
|
|
418
417
|
Unit.update(Unit.root);
|
|
419
418
|
});
|
|
@@ -463,9 +462,9 @@ class Unit {
|
|
|
463
462
|
if (SYSTEM_EVENTS.includes(type)) {
|
|
464
463
|
this._.systems[type].push(listener);
|
|
465
464
|
}
|
|
466
|
-
if (this._.
|
|
465
|
+
if (this._.listeners.has(type, listener) === false) {
|
|
467
466
|
const execute = Unit.wrap(Unit.current, listener);
|
|
468
|
-
this._.
|
|
467
|
+
this._.listeners.set(type, listener, { element: this.element, execute });
|
|
469
468
|
Unit.type2units.add(type, this);
|
|
470
469
|
if (/^[A-Za-z]/.test(type)) {
|
|
471
470
|
this.element.addEventListener(type, execute, options);
|
|
@@ -474,21 +473,21 @@ class Unit {
|
|
|
474
473
|
});
|
|
475
474
|
}
|
|
476
475
|
off(type, listener) {
|
|
477
|
-
const types = typeof type === 'string' ? type.trim().split(/\s+/) : [...this._.
|
|
476
|
+
const types = typeof type === 'string' ? type.trim().split(/\s+/) : [...this._.listeners.keys()];
|
|
478
477
|
types.forEach((type) => {
|
|
479
478
|
if (SYSTEM_EVENTS.includes(type)) {
|
|
480
479
|
this._.systems[type] = this._.systems[type].filter((lis) => listener ? lis !== listener : false);
|
|
481
480
|
}
|
|
482
|
-
(listener ? [listener] : [...this._.
|
|
483
|
-
const item = this._.
|
|
481
|
+
(listener ? [listener] : [...this._.listeners.keys(type)]).forEach((listener) => {
|
|
482
|
+
const item = this._.listeners.get(type, listener);
|
|
484
483
|
if (item !== undefined) {
|
|
485
|
-
this._.
|
|
484
|
+
this._.listeners.delete(type, listener);
|
|
486
485
|
if (/^[A-Za-z]/.test(type)) {
|
|
487
486
|
item.element.removeEventListener(type, item.execute);
|
|
488
487
|
}
|
|
489
488
|
}
|
|
490
489
|
});
|
|
491
|
-
if (this._.
|
|
490
|
+
if (this._.listeners.has(type) === false) {
|
|
492
491
|
Unit.type2units.delete(type, this);
|
|
493
492
|
}
|
|
494
493
|
});
|
|
@@ -498,34 +497,13 @@ class Unit {
|
|
|
498
497
|
if (type[0] === '+') {
|
|
499
498
|
(_a = Unit.type2units.get(type)) === null || _a === void 0 ? void 0 : _a.forEach((unit) => {
|
|
500
499
|
var _a;
|
|
501
|
-
(_a = unit._.
|
|
500
|
+
(_a = unit._.listeners.get(type)) === null || _a === void 0 ? void 0 : _a.forEach((item) => item.execute(...args));
|
|
502
501
|
});
|
|
503
502
|
}
|
|
504
503
|
else if (type[0] === '-') {
|
|
505
|
-
(_b = this._.
|
|
504
|
+
(_b = this._.listeners.get(type)) === null || _b === void 0 ? void 0 : _b.forEach((item) => item.execute(...args));
|
|
506
505
|
}
|
|
507
506
|
}
|
|
508
|
-
static subon(unit, target, type, listener, options) {
|
|
509
|
-
type.trim().split(/\s+/).forEach((type) => {
|
|
510
|
-
if (unit._.listeners2.has(type, listener) === false) {
|
|
511
|
-
const execute = Unit.wrap(unit, listener);
|
|
512
|
-
unit._.listeners2.set(type, listener, { element: target, execute });
|
|
513
|
-
target.addEventListener(type, execute, options);
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
static suboff(unit, target, type, listener) {
|
|
518
|
-
const types = typeof type === 'string' ? type.trim().split(/\s+/) : [...unit._.listeners2.keys()];
|
|
519
|
-
types.forEach((type) => {
|
|
520
|
-
(listener ? [listener] : [...unit._.listeners2.keys(type)]).forEach((listener) => {
|
|
521
|
-
const item = unit._.listeners2.get(type, listener);
|
|
522
|
-
if (item !== undefined && (target === null || target === item.element)) {
|
|
523
|
-
unit._.listeners2.delete(type, listener);
|
|
524
|
-
item.element.removeEventListener(type, item.execute);
|
|
525
|
-
}
|
|
526
|
-
});
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
507
|
}
|
|
530
508
|
Unit.component2units = new MapSet();
|
|
531
509
|
//----------------------------------------------------------------------------------------------------
|
|
@@ -554,54 +532,57 @@ class UnitPromise {
|
|
|
554
532
|
// unit timer
|
|
555
533
|
//----------------------------------------------------------------------------------------------------
|
|
556
534
|
class UnitTimer {
|
|
557
|
-
constructor(
|
|
535
|
+
constructor(options) {
|
|
558
536
|
this.stack = [];
|
|
559
|
-
this.unit = new Unit(Unit.current, UnitTimer.Component, { snapshot: Unit.snapshot(Unit.current)
|
|
537
|
+
this.unit = new Unit(Unit.current, UnitTimer.Component, Object.assign({ snapshot: Unit.snapshot(Unit.current) }, options));
|
|
560
538
|
}
|
|
561
539
|
clear() {
|
|
562
540
|
this.stack = [];
|
|
563
541
|
this.unit.finalize();
|
|
564
542
|
}
|
|
565
543
|
timeout(timeout, duration = 0) {
|
|
566
|
-
UnitTimer.execute(this, { timeout, duration });
|
|
544
|
+
UnitTimer.execute(this, { timeout, duration, iterations: 1 });
|
|
567
545
|
return this;
|
|
568
546
|
}
|
|
569
547
|
transition(transition, duration = 0, easing = 'linear') {
|
|
570
|
-
UnitTimer.execute(this, { transition, duration, easing });
|
|
548
|
+
UnitTimer.execute(this, { transition, duration, easing, iterations: 1 });
|
|
571
549
|
return this;
|
|
572
550
|
}
|
|
573
|
-
static execute(timer,
|
|
551
|
+
static execute(timer, options) {
|
|
574
552
|
if (timer.unit._.state === 'finalized') {
|
|
575
|
-
timer.unit = new Unit(Unit.current, UnitTimer.Component, { snapshot: Unit.snapshot(Unit.current)
|
|
553
|
+
timer.unit = new Unit(Unit.current, UnitTimer.Component, Object.assign({ snapshot: Unit.snapshot(Unit.current) }, options));
|
|
576
554
|
}
|
|
577
555
|
else if (timer.stack.length === 0) {
|
|
578
|
-
timer.stack.push({ snapshot: Unit.snapshot(Unit.current)
|
|
579
|
-
timer.unit.on('finalize', () => { UnitTimer.next(timer); });
|
|
556
|
+
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.current) }, options));
|
|
557
|
+
timer.unit.on('-finalize', () => { UnitTimer.next(timer); });
|
|
580
558
|
}
|
|
581
559
|
else {
|
|
582
|
-
timer.stack.push({ snapshot: Unit.snapshot(Unit.current)
|
|
560
|
+
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.current) }, options));
|
|
583
561
|
}
|
|
584
562
|
}
|
|
585
563
|
static next(timer) {
|
|
586
564
|
if (timer.stack.length > 0) {
|
|
587
565
|
timer.unit = new Unit(Unit.current, UnitTimer.Component, timer.stack.shift());
|
|
588
|
-
timer.unit.on('finalize', () => { UnitTimer.next(timer); });
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
static Component(unit,
|
|
592
|
-
const timer = new Timer(
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
566
|
+
timer.unit.on('-finalize', () => { UnitTimer.next(timer); });
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
static Component(unit, options) {
|
|
570
|
+
const timer = new Timer({
|
|
571
|
+
transition: (x) => {
|
|
572
|
+
if (options.transition !== undefined)
|
|
573
|
+
Unit.scope(options.snapshot, options.transition, x);
|
|
574
|
+
},
|
|
575
|
+
timeout: (count) => {
|
|
576
|
+
if (options.transition !== undefined)
|
|
577
|
+
Unit.scope(options.snapshot, options.transition, 1.0);
|
|
578
|
+
if (options.timeout !== undefined)
|
|
579
|
+
Unit.scope(options.snapshot, options.timeout);
|
|
580
|
+
if (options.iterations !== undefined && count >= options.iterations - 1) {
|
|
581
|
+
unit.finalize();
|
|
582
|
+
}
|
|
583
|
+
}, duration: options.duration, iterations: options.iterations, easing: options.easing
|
|
584
|
+
});
|
|
585
|
+
unit.on('-finalize', () => timer.clear());
|
|
605
586
|
}
|
|
606
587
|
}
|
|
607
588
|
|
|
@@ -792,7 +773,7 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
792
773
|
* // Cancel if needed: timer.clear()
|
|
793
774
|
*/
|
|
794
775
|
timeout(timeout, duration = 0) {
|
|
795
|
-
return new UnitTimer({ timeout, duration });
|
|
776
|
+
return new UnitTimer({ timeout, duration, iterations: 1 });
|
|
796
777
|
},
|
|
797
778
|
/**
|
|
798
779
|
* Executes a callback repeatedly at specified intervals, managed by component lifecycle
|
|
@@ -803,8 +784,8 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
803
784
|
* const timer = xnew.interval(() => console.log('Tick'), 1000)
|
|
804
785
|
* // Stop when needed: timer.clear()
|
|
805
786
|
*/
|
|
806
|
-
interval(timeout, duration) {
|
|
807
|
-
return new UnitTimer({ timeout, duration,
|
|
787
|
+
interval(timeout, duration, iterations) {
|
|
788
|
+
return new UnitTimer({ timeout, duration, iterations });
|
|
808
789
|
},
|
|
809
790
|
/**
|
|
810
791
|
* Creates a transition animation with easing, executing callback with progress values
|
|
@@ -820,27 +801,8 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
820
801
|
* }, 300)
|
|
821
802
|
*/
|
|
822
803
|
transition(transition, duration = 0, easing = 'linear') {
|
|
823
|
-
return new UnitTimer({ transition, duration, easing });
|
|
824
|
-
}
|
|
825
|
-
/**
|
|
826
|
-
* Creates an event listener manager for a target element with automatic cleanup
|
|
827
|
-
* @param target - Element, Window, or Document to attach listeners to
|
|
828
|
-
* @returns Object with on() and off() methods for managing event listeners
|
|
829
|
-
* @example
|
|
830
|
-
* const mouse = xnew.listener(window)
|
|
831
|
-
* mouse.on('mousemove', (e) => console.log(e.clientX, e.clientY))
|
|
832
|
-
* // Automatically cleaned up when component finalizes
|
|
833
|
-
*/
|
|
834
|
-
listener(target) {
|
|
835
|
-
return {
|
|
836
|
-
on(type, listener, options) {
|
|
837
|
-
Unit.subon(Unit.current, target, type, listener, options);
|
|
838
|
-
},
|
|
839
|
-
off(type, listener) {
|
|
840
|
-
Unit.suboff(Unit.current, target, type, listener);
|
|
841
|
-
}
|
|
842
|
-
};
|
|
843
|
-
},
|
|
804
|
+
return new UnitTimer({ transition, duration, easing, iterations: 1 });
|
|
805
|
+
}
|
|
844
806
|
});
|
|
845
807
|
|
|
846
808
|
function AccordionFrame(frame, { open = false, duration = 200, easing = 'ease' } = {}) {
|
|
@@ -931,34 +893,40 @@ function ResizeEvent(resize) {
|
|
|
931
893
|
if (resize.element) {
|
|
932
894
|
observer.observe(resize.element);
|
|
933
895
|
}
|
|
934
|
-
resize.on('finalize', () => {
|
|
896
|
+
resize.on('-finalize', () => {
|
|
935
897
|
if (resize.element) {
|
|
936
898
|
observer.unobserve(resize.element);
|
|
937
899
|
}
|
|
938
900
|
});
|
|
939
901
|
}
|
|
940
|
-
function KeyboardEvent(
|
|
902
|
+
function KeyboardEvent(keyboard) {
|
|
941
903
|
const state = {};
|
|
942
|
-
|
|
904
|
+
window.addEventListener('keydown', keydown);
|
|
905
|
+
window.addEventListener('keyup', keyup);
|
|
906
|
+
function keydown(event) {
|
|
943
907
|
state[event.code] = 1;
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
908
|
+
keyboard.emit('-keydown', { event, type: '-keydown', code: event.code });
|
|
909
|
+
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) {
|
|
910
|
+
keyboard.emit('-keydown:arrow', { event, type: '-keydown:arrow', code: event.code, vector: getVector() });
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
function keyup(event) {
|
|
947
914
|
state[event.code] = 0;
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
}
|
|
953
|
-
xnew$1.listener(window).on('keyup', (event) => {
|
|
954
|
-
unit.emit('-arrowkeyup', { event, type: '-arrowkeyup', code: event.code, vector: getVector() });
|
|
955
|
-
});
|
|
915
|
+
keyboard.emit('-keyup', { event, type: '-keyup', code: event.code });
|
|
916
|
+
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown'].includes(event.code)) {
|
|
917
|
+
keyboard.emit('-keyup:arrow', { event, type: '-keyup:arrow', code: event.code, vector: getVector() });
|
|
918
|
+
}
|
|
919
|
+
}
|
|
956
920
|
function getVector() {
|
|
957
921
|
return {
|
|
958
922
|
x: (state['ArrowLeft'] ? -1 : 0) + (state['ArrowRight'] ? +1 : 0),
|
|
959
923
|
y: (state['ArrowUp'] ? -1 : 0) + (state['ArrowDown'] ? +1 : 0)
|
|
960
924
|
};
|
|
961
925
|
}
|
|
926
|
+
keyboard.on('-finalize', () => {
|
|
927
|
+
window.removeEventListener('keydown', keydown);
|
|
928
|
+
window.removeEventListener('keyup', keyup);
|
|
929
|
+
});
|
|
962
930
|
}
|
|
963
931
|
function PointerEvent(unit) {
|
|
964
932
|
const internal = xnew$1();
|
|
@@ -966,8 +934,32 @@ function PointerEvent(unit) {
|
|
|
966
934
|
internal.on('pointermove', (event) => unit.emit('-pointermove', { event, position: getPosition(unit.element, event) }));
|
|
967
935
|
internal.on('pointerup', (event) => unit.emit('-pointerup', { event, position: getPosition(unit.element, event) }));
|
|
968
936
|
internal.on('wheel', (event) => unit.emit('-wheel', { event, delta: { x: event.wheelDeltaX, y: event.wheelDeltaY } }));
|
|
969
|
-
internal.on('
|
|
970
|
-
internal.on('
|
|
937
|
+
internal.on('click', (event) => unit.emit('-click', { event, position: getPosition(unit.element, event) }));
|
|
938
|
+
internal.on('pointerover', (event) => unit.emit('-pointerover', { event, position: getPosition(unit.element, event) }));
|
|
939
|
+
internal.on('pointerout', (event) => unit.emit('-pointerout', { event, position: getPosition(unit.element, event) }));
|
|
940
|
+
document.addEventListener('pointerdown', pointerdownoutside);
|
|
941
|
+
document.addEventListener('pointerup', pointerupoutside);
|
|
942
|
+
document.addEventListener('click', clickoutside);
|
|
943
|
+
unit.on('-finalize', () => {
|
|
944
|
+
document.removeEventListener('pointerdown', pointerdownoutside);
|
|
945
|
+
document.removeEventListener('pointerup', pointerupoutside);
|
|
946
|
+
document.removeEventListener('click', clickoutside);
|
|
947
|
+
});
|
|
948
|
+
function pointerdownoutside(event) {
|
|
949
|
+
if (unit.element.contains(event.target) === false) {
|
|
950
|
+
unit.emit('-pointerdown:outside', { event, position: getPosition(unit.element, event) });
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
function pointerupoutside(event) {
|
|
954
|
+
if (unit.element.contains(event.target) === false) {
|
|
955
|
+
unit.emit('-pointerup:outside', { event, position: getPosition(unit.element, event) });
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
function clickoutside(event) {
|
|
959
|
+
if (unit.element.contains(event.target) === false) {
|
|
960
|
+
unit.emit('-click:outside', { event, position: getPosition(unit.element, event) });
|
|
961
|
+
}
|
|
962
|
+
}
|
|
971
963
|
const drag = xnew$1(DragEvent);
|
|
972
964
|
drag.on('-dragstart', (...args) => unit.emit('-dragstart', ...args));
|
|
973
965
|
drag.on('-dragmove', (...args) => unit.emit('-dragmove', ...args));
|
|
@@ -980,36 +972,50 @@ function PointerEvent(unit) {
|
|
|
980
972
|
gesture.on('-gesturecancel', (...args) => unit.emit('-gesturecancel', ...args));
|
|
981
973
|
}
|
|
982
974
|
function DragEvent(unit) {
|
|
983
|
-
|
|
975
|
+
unit.on('pointerdown', pointerdown);
|
|
976
|
+
function pointerdown(event) {
|
|
984
977
|
const id = event.pointerId;
|
|
985
978
|
const position = getPosition(unit.element, event);
|
|
986
979
|
let previous = position;
|
|
987
|
-
xnew$1(() => {
|
|
988
|
-
|
|
980
|
+
xnew$1((internal) => {
|
|
981
|
+
let connect = true;
|
|
982
|
+
window.addEventListener('pointermove', pointermove);
|
|
983
|
+
window.addEventListener('pointerup', pointerup);
|
|
984
|
+
window.addEventListener('pointercancel', pointercancel);
|
|
985
|
+
function pointermove(event) {
|
|
989
986
|
if (event.pointerId === id) {
|
|
990
987
|
const position = getPosition(unit.element, event);
|
|
991
988
|
const delta = { x: position.x - previous.x, y: position.y - previous.y };
|
|
992
989
|
unit.emit('-dragmove', { event, position, delta });
|
|
993
990
|
previous = position;
|
|
994
991
|
}
|
|
995
|
-
}
|
|
996
|
-
|
|
992
|
+
}
|
|
993
|
+
function pointerup(event) {
|
|
997
994
|
if (event.pointerId === id) {
|
|
998
995
|
const position = getPosition(unit.element, event);
|
|
999
996
|
unit.emit('-dragend', { event, position, });
|
|
1000
|
-
|
|
997
|
+
remove();
|
|
1001
998
|
}
|
|
1002
|
-
}
|
|
1003
|
-
|
|
999
|
+
}
|
|
1000
|
+
function pointercancel(event) {
|
|
1004
1001
|
if (event.pointerId === id) {
|
|
1005
1002
|
const position = getPosition(unit.element, event);
|
|
1006
1003
|
unit.emit('-dragcancel', { event, position, });
|
|
1007
|
-
|
|
1004
|
+
remove();
|
|
1008
1005
|
}
|
|
1009
|
-
}
|
|
1006
|
+
}
|
|
1007
|
+
function remove() {
|
|
1008
|
+
if (connect === true) {
|
|
1009
|
+
window.removeEventListener('pointermove', pointermove);
|
|
1010
|
+
window.removeEventListener('pointerup', pointerup);
|
|
1011
|
+
window.removeEventListener('pointercancel', pointercancel);
|
|
1012
|
+
connect = false;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
internal.on('-finalize', remove);
|
|
1010
1016
|
});
|
|
1011
1017
|
unit.emit('-dragstart', { event, position });
|
|
1012
|
-
}
|
|
1018
|
+
}
|
|
1013
1019
|
}
|
|
1014
1020
|
function GestureEvent(unit) {
|
|
1015
1021
|
const drag = xnew$1(DragEvent);
|
|
@@ -1415,7 +1421,7 @@ function initialize() {
|
|
|
1415
1421
|
}
|
|
1416
1422
|
const audio = {
|
|
1417
1423
|
load(path) {
|
|
1418
|
-
return
|
|
1424
|
+
return AudioFile.load(path);
|
|
1419
1425
|
},
|
|
1420
1426
|
synthesizer(props) {
|
|
1421
1427
|
return new Synthesizer(props);
|
|
@@ -1441,43 +1447,69 @@ class AudioFile {
|
|
|
1441
1447
|
.catch(() => {
|
|
1442
1448
|
console.warn(`"${path}" could not be loaded.`);
|
|
1443
1449
|
});
|
|
1450
|
+
this.amp = context.createGain();
|
|
1451
|
+
this.amp.gain.value = 1.0;
|
|
1452
|
+
this.amp.connect(master);
|
|
1453
|
+
this.fade = context.createGain();
|
|
1454
|
+
this.fade.gain.value = 1.0;
|
|
1455
|
+
this.fade.connect(this.amp);
|
|
1456
|
+
this.source = null;
|
|
1444
1457
|
this.start = null;
|
|
1445
1458
|
}
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
play(offset = 0, loop = false) {
|
|
1459
|
+
set volume(value) {
|
|
1460
|
+
this.amp.gain.value = value;
|
|
1461
|
+
}
|
|
1462
|
+
get volume() {
|
|
1463
|
+
return this.amp.gain.value;
|
|
1464
|
+
}
|
|
1465
|
+
play({ offset = 0, loop = false, fade = 0 } = {}) {
|
|
1453
1466
|
if (this.buffer !== undefined && this.start === null) {
|
|
1454
1467
|
this.source = context.createBufferSource();
|
|
1455
1468
|
this.source.buffer = this.buffer;
|
|
1456
1469
|
this.source.loop = loop;
|
|
1457
|
-
this.
|
|
1458
|
-
this.amp.gain.value = 1.0;
|
|
1459
|
-
this.source.connect(this.amp);
|
|
1460
|
-
this.amp.connect(master);
|
|
1470
|
+
this.source.connect(this.fade);
|
|
1461
1471
|
this.start = context.currentTime;
|
|
1462
1472
|
this.source.playbackRate.value = 1;
|
|
1463
1473
|
this.source.start(context.currentTime, offset / 1000);
|
|
1474
|
+
// Apply fade-in effect if fade duration is specified
|
|
1475
|
+
if (fade > 0) {
|
|
1476
|
+
this.fade.gain.setValueAtTime(0, context.currentTime);
|
|
1477
|
+
this.fade.gain.linearRampToValueAtTime(1.0, context.currentTime + fade / 1000);
|
|
1478
|
+
}
|
|
1464
1479
|
this.source.onended = () => {
|
|
1465
|
-
var _a
|
|
1480
|
+
var _a;
|
|
1466
1481
|
this.start = null;
|
|
1467
1482
|
(_a = this.source) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
1468
|
-
|
|
1483
|
+
this.source = null;
|
|
1469
1484
|
};
|
|
1470
1485
|
}
|
|
1471
1486
|
}
|
|
1472
|
-
pause() {
|
|
1473
|
-
var _a;
|
|
1487
|
+
pause({ fade = 0 } = {}) {
|
|
1488
|
+
var _a, _b;
|
|
1474
1489
|
if (this.buffer !== undefined && this.start !== null) {
|
|
1475
|
-
(_a = this.source) === null || _a === void 0 ? void 0 : _a.stop(context.currentTime);
|
|
1476
1490
|
const elapsed = (context.currentTime - this.start) % this.buffer.duration * 1000;
|
|
1491
|
+
// Apply fade-out effect if fade duration is specified
|
|
1492
|
+
if (fade > 0) {
|
|
1493
|
+
this.fade.gain.setValueAtTime(1.0, context.currentTime);
|
|
1494
|
+
this.fade.gain.linearRampToValueAtTime(0, context.currentTime + fade / 1000);
|
|
1495
|
+
(_a = this.source) === null || _a === void 0 ? void 0 : _a.stop(context.currentTime + fade / 1000);
|
|
1496
|
+
}
|
|
1497
|
+
else {
|
|
1498
|
+
(_b = this.source) === null || _b === void 0 ? void 0 : _b.stop(context.currentTime);
|
|
1499
|
+
}
|
|
1477
1500
|
this.start = null;
|
|
1478
1501
|
return elapsed;
|
|
1479
1502
|
}
|
|
1480
1503
|
}
|
|
1504
|
+
static load(path) {
|
|
1505
|
+
const music = new AudioFile(path);
|
|
1506
|
+
return xnew$1.promise(music.promise).then(() => music);
|
|
1507
|
+
}
|
|
1508
|
+
static clear(file) {
|
|
1509
|
+
var _a;
|
|
1510
|
+
file.amp.disconnect();
|
|
1511
|
+
(_a = file.source) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
1512
|
+
}
|
|
1481
1513
|
}
|
|
1482
1514
|
const keymap = {
|
|
1483
1515
|
'A0': 27.500, 'A#0': 29.135, 'B0': 30.868,
|
|
@@ -1562,7 +1594,7 @@ class Synthesizer {
|
|
|
1562
1594
|
if (props.amp.envelope) {
|
|
1563
1595
|
const ADSR = props.amp.envelope.ADSR;
|
|
1564
1596
|
const adsr = [ADSR[0] / 1000, ADSR[1] / 1000, ADSR[2], ADSR[3] / 1000];
|
|
1565
|
-
const rate = adsr[0] === 0.0 ? 1.0 : Math.min(end / adsr[0], 1.0);
|
|
1597
|
+
const rate = adsr[0] === 0.0 ? 1.0 : Math.min(end / (adsr[0] + 0.001), 1.0);
|
|
1566
1598
|
stop = start + Math.max((adsr[0] + adsr[1]) * rate, end) + adsr[3];
|
|
1567
1599
|
}
|
|
1568
1600
|
else {
|
|
@@ -1592,7 +1624,8 @@ class Synthesizer {
|
|
|
1592
1624
|
}, 2000);
|
|
1593
1625
|
}
|
|
1594
1626
|
function stopEnvelope(param, base, amount, ADSR) {
|
|
1595
|
-
const
|
|
1627
|
+
const end = dv > 0 ? dv : (context.currentTime - start);
|
|
1628
|
+
const rate = ADSR[0] === 0.0 ? 1.0 : Math.min(end / (ADSR[0] / 1000), 1.0);
|
|
1596
1629
|
if (rate < 1.0) {
|
|
1597
1630
|
param.cancelScheduledValues(start);
|
|
1598
1631
|
param.setValueAtTime(base, start);
|
|
@@ -1600,7 +1633,7 @@ class Synthesizer {
|
|
|
1600
1633
|
param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000 * rate);
|
|
1601
1634
|
}
|
|
1602
1635
|
param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dv));
|
|
1603
|
-
param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate,
|
|
1636
|
+
param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, end) + ADSR[3] / 1000);
|
|
1604
1637
|
}
|
|
1605
1638
|
function startEnvelope(param, base, amount, ADSR) {
|
|
1606
1639
|
param.value = base;
|