@mulsense/xnew 0.1.12 → 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 +3 -10
- package/dist/addons/xpixi.mjs +3 -10
- 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/core/time.d.ts +1 -1
- package/dist/types/core/xnew.d.ts +0 -1
- package/dist/xnew.d.ts +2 -13
- package/dist/xnew.js +92 -51
- package/dist/xnew.mjs +92 -51
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ providing a flexible architecture well-suited for applications with dynamic scen
|
|
|
13
13
|
### Via CDN
|
|
14
14
|
Include the following script in your HTML file:
|
|
15
15
|
```html
|
|
16
|
-
<script src="https://unpkg.com/@mulsense/xnew@0.
|
|
16
|
+
<script src="https://unpkg.com/@mulsense/xnew@0.2.x/dist/xnew.js"></script>
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
### Via CDN (ESM)
|
|
@@ -22,7 +22,7 @@ Use the ES module version with an import map:
|
|
|
22
22
|
<script type="importmap">
|
|
23
23
|
{
|
|
24
24
|
"imports": {
|
|
25
|
-
"@mulsense/xnew": "https://unpkg.com/@mulsense/xnew@0.
|
|
25
|
+
"@mulsense/xnew": "https://unpkg.com/@mulsense/xnew@0.2.x/dist/xnew.mjs"
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
</script>
|
|
@@ -37,7 +37,7 @@ import xnew from '@mulsense/xnew';
|
|
|
37
37
|
### Via npm
|
|
38
38
|
Install `xnew` using npm:
|
|
39
39
|
```bash
|
|
40
|
-
npm install @mulsense/xnew@0.
|
|
40
|
+
npm install @mulsense/xnew@0.2.x
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
Then import it in your JavaScript file:
|
package/dist/addons/xmatter.js
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
root.isActive = true;
|
|
24
24
|
root.engine = engine !== null && engine !== void 0 ? engine : Matter.Engine.create();
|
|
25
25
|
xnew.context('xmatter.object', root.engine.world);
|
|
26
|
-
self.on('update', () => {
|
|
26
|
+
self.on('-update', () => {
|
|
27
27
|
if (root.isActive) {
|
|
28
28
|
Matter.Engine.update(root.engine);
|
|
29
29
|
}
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
const parent = xnew.context('xmatter.object');
|
|
34
34
|
xnew.context('xmatter.object', object);
|
|
35
35
|
Matter.Composite.add(parent, object);
|
|
36
|
-
self.on('finalize', () => {
|
|
36
|
+
self.on('-finalize', () => {
|
|
37
37
|
Matter.Composite.remove(parent, object);
|
|
38
38
|
});
|
|
39
39
|
}
|
package/dist/addons/xmatter.mjs
CHANGED
|
@@ -20,7 +20,7 @@ function Root(self, { engine }) {
|
|
|
20
20
|
root.isActive = true;
|
|
21
21
|
root.engine = engine !== null && engine !== void 0 ? engine : Matter.Engine.create();
|
|
22
22
|
xnew.context('xmatter.object', root.engine.world);
|
|
23
|
-
self.on('update', () => {
|
|
23
|
+
self.on('-update', () => {
|
|
24
24
|
if (root.isActive) {
|
|
25
25
|
Matter.Engine.update(root.engine);
|
|
26
26
|
}
|
|
@@ -30,7 +30,7 @@ function Nest(self, { object }) {
|
|
|
30
30
|
const parent = xnew.context('xmatter.object');
|
|
31
31
|
xnew.context('xmatter.object', object);
|
|
32
32
|
Matter.Composite.add(parent, object);
|
|
33
|
-
self.on('finalize', () => {
|
|
33
|
+
self.on('-finalize', () => {
|
|
34
34
|
Matter.Composite.remove(parent, object);
|
|
35
35
|
});
|
|
36
36
|
}
|
package/dist/addons/xpixi.js
CHANGED
|
@@ -50,13 +50,6 @@
|
|
|
50
50
|
var _a;
|
|
51
51
|
return (_a = xnew.context('xpixi.root')) === null || _a === void 0 ? void 0 : _a.canvas;
|
|
52
52
|
},
|
|
53
|
-
capture() {
|
|
54
|
-
var _a, _b;
|
|
55
|
-
const render = (_a = xnew.context('xpixi.root')) === null || _a === void 0 ? void 0 : _a.renderer;
|
|
56
|
-
const scene = (_b = xnew.context('xpixi.root')) === null || _b === void 0 ? void 0 : _b.scene;
|
|
57
|
-
const canvas = render.extract.canvas(scene);
|
|
58
|
-
return canvas.toDataURL('image/png', 1.0);
|
|
59
|
-
}
|
|
60
53
|
};
|
|
61
54
|
function Root(self, { canvas }) {
|
|
62
55
|
const root = {};
|
|
@@ -76,7 +69,7 @@
|
|
|
76
69
|
root.updates = [];
|
|
77
70
|
root.scene = new PIXI__namespace.Container();
|
|
78
71
|
xnew.context('xpixi.object', root.scene);
|
|
79
|
-
self.on('update', () => {
|
|
72
|
+
self.on('-update', () => {
|
|
80
73
|
root.updates.forEach((update) => {
|
|
81
74
|
update();
|
|
82
75
|
});
|
|
@@ -89,14 +82,14 @@
|
|
|
89
82
|
const parent = xnew.context('xpixi.object');
|
|
90
83
|
xnew.context('xpixi.object', object);
|
|
91
84
|
parent.addChild(object);
|
|
92
|
-
self.on('finalize', () => {
|
|
85
|
+
self.on('-finalize', () => {
|
|
93
86
|
parent.removeChild(object);
|
|
94
87
|
});
|
|
95
88
|
}
|
|
96
89
|
function PreUpdate(self, callback) {
|
|
97
90
|
const root = xnew.context('xpixi.root');
|
|
98
91
|
root.updates.push(callback);
|
|
99
|
-
self.on('finalize', () => {
|
|
92
|
+
self.on('-finalize', () => {
|
|
100
93
|
root.updates = root.updates.filter((update) => update !== callback);
|
|
101
94
|
});
|
|
102
95
|
}
|
package/dist/addons/xpixi.mjs
CHANGED
|
@@ -28,13 +28,6 @@ var xpixi = {
|
|
|
28
28
|
var _a;
|
|
29
29
|
return (_a = xnew.context('xpixi.root')) === null || _a === void 0 ? void 0 : _a.canvas;
|
|
30
30
|
},
|
|
31
|
-
capture() {
|
|
32
|
-
var _a, _b;
|
|
33
|
-
const render = (_a = xnew.context('xpixi.root')) === null || _a === void 0 ? void 0 : _a.renderer;
|
|
34
|
-
const scene = (_b = xnew.context('xpixi.root')) === null || _b === void 0 ? void 0 : _b.scene;
|
|
35
|
-
const canvas = render.extract.canvas(scene);
|
|
36
|
-
return canvas.toDataURL('image/png', 1.0);
|
|
37
|
-
}
|
|
38
31
|
};
|
|
39
32
|
function Root(self, { canvas }) {
|
|
40
33
|
const root = {};
|
|
@@ -54,7 +47,7 @@ function Root(self, { canvas }) {
|
|
|
54
47
|
root.updates = [];
|
|
55
48
|
root.scene = new PIXI.Container();
|
|
56
49
|
xnew.context('xpixi.object', root.scene);
|
|
57
|
-
self.on('update', () => {
|
|
50
|
+
self.on('-update', () => {
|
|
58
51
|
root.updates.forEach((update) => {
|
|
59
52
|
update();
|
|
60
53
|
});
|
|
@@ -67,14 +60,14 @@ function Nest(self, { object }) {
|
|
|
67
60
|
const parent = xnew.context('xpixi.object');
|
|
68
61
|
xnew.context('xpixi.object', object);
|
|
69
62
|
parent.addChild(object);
|
|
70
|
-
self.on('finalize', () => {
|
|
63
|
+
self.on('-finalize', () => {
|
|
71
64
|
parent.removeChild(object);
|
|
72
65
|
});
|
|
73
66
|
}
|
|
74
67
|
function PreUpdate(self, callback) {
|
|
75
68
|
const root = xnew.context('xpixi.root');
|
|
76
69
|
root.updates.push(callback);
|
|
77
|
-
self.on('finalize', () => {
|
|
70
|
+
self.on('-finalize', () => {
|
|
78
71
|
root.updates = root.updates.filter((update) => update !== callback);
|
|
79
72
|
});
|
|
80
73
|
}
|
package/dist/addons/xrapier2d.js
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
}
|
|
28
28
|
// xnew.extend(Nest, root.world);
|
|
29
29
|
});
|
|
30
|
-
self.on('update', () => {
|
|
30
|
+
self.on('-update', () => {
|
|
31
31
|
if (root.world) {
|
|
32
32
|
root.world.step();
|
|
33
33
|
}
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
console.log(temp, type, object);
|
|
41
41
|
// Rapier2D objects (RigidBody, Collider, etc.) are already added to the world
|
|
42
42
|
// when created, so we only need to handle removal on finalize
|
|
43
|
-
self.on('finalize', () => {
|
|
43
|
+
self.on('-finalize', () => {
|
|
44
44
|
try {
|
|
45
45
|
// Check if object is a RigidBody
|
|
46
46
|
if (type === 'rigidBody') {
|
|
@@ -24,7 +24,7 @@ function Root(self, { gravity, timestep }) {
|
|
|
24
24
|
}
|
|
25
25
|
// xnew.extend(Nest, root.world);
|
|
26
26
|
});
|
|
27
|
-
self.on('update', () => {
|
|
27
|
+
self.on('-update', () => {
|
|
28
28
|
if (root.world) {
|
|
29
29
|
root.world.step();
|
|
30
30
|
}
|
|
@@ -37,7 +37,7 @@ function Connect(self, { type, object }) {
|
|
|
37
37
|
console.log(temp, type, object);
|
|
38
38
|
// Rapier2D objects (RigidBody, Collider, etc.) are already added to the world
|
|
39
39
|
// when created, so we only need to handle removal on finalize
|
|
40
|
-
self.on('finalize', () => {
|
|
40
|
+
self.on('-finalize', () => {
|
|
41
41
|
try {
|
|
42
42
|
// Check if object is a RigidBody
|
|
43
43
|
if (type === 'rigidBody') {
|
package/dist/addons/xthree.js
CHANGED
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
root.camera = camera !== null && camera !== void 0 ? camera : new THREE__namespace.PerspectiveCamera(45, root.renderer.domElement.width / root.renderer.domElement.height);
|
|
58
58
|
root.scene = new THREE__namespace.Scene();
|
|
59
59
|
xnew.context('xthree.object', root.scene);
|
|
60
|
-
self.on('update', () => {
|
|
60
|
+
self.on('-update', () => {
|
|
61
61
|
root.renderer.render(root.scene, root.camera);
|
|
62
62
|
});
|
|
63
63
|
}
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
xnew.context('xthree.object', object);
|
|
67
67
|
if (parent) {
|
|
68
68
|
parent === null || parent === void 0 ? void 0 : parent.add(object);
|
|
69
|
-
self.on('finalize', () => {
|
|
69
|
+
self.on('-finalize', () => {
|
|
70
70
|
parent === null || parent === void 0 ? void 0 : parent.remove(object);
|
|
71
71
|
});
|
|
72
72
|
}
|
package/dist/addons/xthree.mjs
CHANGED
|
@@ -35,7 +35,7 @@ function Root(self, { canvas, camera }) {
|
|
|
35
35
|
root.camera = camera !== null && camera !== void 0 ? camera : new THREE.PerspectiveCamera(45, root.renderer.domElement.width / root.renderer.domElement.height);
|
|
36
36
|
root.scene = new THREE.Scene();
|
|
37
37
|
xnew.context('xthree.object', root.scene);
|
|
38
|
-
self.on('update', () => {
|
|
38
|
+
self.on('-update', () => {
|
|
39
39
|
root.renderer.render(root.scene, root.camera);
|
|
40
40
|
});
|
|
41
41
|
}
|
|
@@ -44,7 +44,7 @@ function Nest(self, { object }) {
|
|
|
44
44
|
xnew.context('xthree.object', object);
|
|
45
45
|
if (parent) {
|
|
46
46
|
parent === null || parent === void 0 ? void 0 : parent.add(object);
|
|
47
|
-
self.on('finalize', () => {
|
|
47
|
+
self.on('-finalize', () => {
|
|
48
48
|
parent === null || parent === void 0 ? void 0 : parent.remove(object);
|
|
49
49
|
});
|
|
50
50
|
}
|
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
export declare const audio: {
|
|
2
|
-
load(path: string):
|
|
2
|
+
load(path: string): import("../core/unit").UnitPromise;
|
|
3
3
|
synthesizer(props: SynthProps): Synthesizer;
|
|
4
4
|
volume: number;
|
|
5
5
|
};
|
|
6
|
-
declare class AudioFile {
|
|
7
|
-
buffer?: AudioBuffer;
|
|
8
|
-
promise: Promise<void>;
|
|
9
|
-
source?: AudioBufferSourceNode;
|
|
10
|
-
amp?: GainNode;
|
|
11
|
-
start: number | null;
|
|
12
|
-
constructor(path: string);
|
|
13
|
-
play(offset?: number, loop?: boolean): void;
|
|
14
|
-
pause(): number | undefined;
|
|
15
|
-
}
|
|
16
6
|
type SynthProps = {
|
|
17
7
|
oscillator: OscillatorOptions;
|
|
18
8
|
amp: AmpOptions;
|
package/dist/xnew.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ declare class MapMap<Key1, Key2, Value> extends Map<Key1, Map<Key2, Value>> {
|
|
|
22
22
|
|
|
23
23
|
declare class Ticker {
|
|
24
24
|
private id;
|
|
25
|
-
constructor(callback: Function);
|
|
25
|
+
constructor(callback: Function, fps?: number);
|
|
26
26
|
clear(): void;
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -257,7 +257,6 @@ declare const xnew$1: CreateUnit & {
|
|
|
257
257
|
* }, 300)
|
|
258
258
|
*/
|
|
259
259
|
transition(transition: Function, duration?: number, easing?: string): any;
|
|
260
|
-
style(text: string): void;
|
|
261
260
|
};
|
|
262
261
|
|
|
263
262
|
declare function AccordionFrame(frame: Unit, { open, duration, easing }?: {
|
|
@@ -360,20 +359,10 @@ declare function DirectionalPad(self: Unit, { size, diagonal, fill, fillOpacity,
|
|
|
360
359
|
}): void;
|
|
361
360
|
|
|
362
361
|
declare const audio: {
|
|
363
|
-
load(path: string):
|
|
362
|
+
load(path: string): UnitPromise;
|
|
364
363
|
synthesizer(props: SynthProps): Synthesizer;
|
|
365
364
|
volume: number;
|
|
366
365
|
};
|
|
367
|
-
declare class AudioFile {
|
|
368
|
-
buffer?: AudioBuffer;
|
|
369
|
-
promise: Promise<void>;
|
|
370
|
-
source?: AudioBufferSourceNode;
|
|
371
|
-
amp?: GainNode;
|
|
372
|
-
start: number | null;
|
|
373
|
-
constructor(path: string);
|
|
374
|
-
play(offset?: number, loop?: boolean): void;
|
|
375
|
-
pause(): number | undefined;
|
|
376
|
-
}
|
|
377
366
|
type SynthProps = {
|
|
378
367
|
oscillator: OscillatorOptions;
|
|
379
368
|
amp: AmpOptions;
|
package/dist/xnew.js
CHANGED
|
@@ -105,17 +105,16 @@
|
|
|
105
105
|
// ticker
|
|
106
106
|
//----------------------------------------------------------------------------------------------------
|
|
107
107
|
class Ticker {
|
|
108
|
-
constructor(callback) {
|
|
108
|
+
constructor(callback, fps = 60) {
|
|
109
109
|
const self = this;
|
|
110
110
|
this.id = null;
|
|
111
111
|
let previous = 0;
|
|
112
112
|
ticker();
|
|
113
113
|
function ticker() {
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
previous = time;
|
|
114
|
+
const delta = Date.now() - previous;
|
|
115
|
+
if (delta > (1000 / fps) * 0.9) {
|
|
116
|
+
callback();
|
|
117
|
+
previous += delta;
|
|
119
118
|
}
|
|
120
119
|
self.id = requestAnimationFrame(ticker);
|
|
121
120
|
}
|
|
@@ -147,7 +146,7 @@
|
|
|
147
146
|
p = Math.pow((1.0 - Math.pow((1.0 - p), 0.5)), 2.0);
|
|
148
147
|
}
|
|
149
148
|
else if (this.options.easing === 'ease') {
|
|
150
|
-
p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
|
|
149
|
+
p = (1.0 - Math.cos(p * Math.PI)) / 2.0; // todo
|
|
151
150
|
}
|
|
152
151
|
else if (this.options.easing === 'ease-in-out') {
|
|
153
152
|
p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
|
|
@@ -214,7 +213,7 @@
|
|
|
214
213
|
//----------------------------------------------------------------------------------------------------
|
|
215
214
|
// utils
|
|
216
215
|
//----------------------------------------------------------------------------------------------------
|
|
217
|
-
const SYSTEM_EVENTS = ['start', 'update', 'stop', 'finalize'];
|
|
216
|
+
const SYSTEM_EVENTS = ['-start', '-update', '-stop', '-finalize'];
|
|
218
217
|
//----------------------------------------------------------------------------------------------------
|
|
219
218
|
// unit
|
|
220
219
|
//----------------------------------------------------------------------------------------------------
|
|
@@ -309,7 +308,7 @@
|
|
|
309
308
|
components: [],
|
|
310
309
|
listeners: new MapMap(),
|
|
311
310
|
defines: {},
|
|
312
|
-
systems: { start: [], update: [], stop: [], finalize: [] },
|
|
311
|
+
systems: { '-start': [], '-update': [], '-stop': [], '-finalize': [] },
|
|
313
312
|
});
|
|
314
313
|
// nest html element
|
|
315
314
|
if (typeof unit._.target === 'string') {
|
|
@@ -325,7 +324,7 @@
|
|
|
325
324
|
if (unit._.state !== 'finalized') {
|
|
326
325
|
unit._.state = 'finalized';
|
|
327
326
|
unit._.children.forEach((child) => child.finalize());
|
|
328
|
-
unit._.systems
|
|
327
|
+
unit._.systems['-finalize'].forEach((listener) => Unit.scope(Unit.snapshot(unit), listener));
|
|
329
328
|
unit.off();
|
|
330
329
|
unit._.components.forEach((component) => Unit.component2units.delete(component, unit));
|
|
331
330
|
if (unit._.elements.length > 0) {
|
|
@@ -395,7 +394,7 @@
|
|
|
395
394
|
if (unit._.state === 'initialized' || unit._.state === 'stopped') {
|
|
396
395
|
unit._.state = 'started';
|
|
397
396
|
unit._.children.forEach((child) => Unit.start(child));
|
|
398
|
-
unit._.systems
|
|
397
|
+
unit._.systems['-start'].forEach((listener) => Unit.scope(Unit.snapshot(unit), listener));
|
|
399
398
|
}
|
|
400
399
|
else if (unit._.state === 'started') {
|
|
401
400
|
unit._.children.forEach((child) => Unit.start(child));
|
|
@@ -405,13 +404,13 @@
|
|
|
405
404
|
if (unit._.state === 'started') {
|
|
406
405
|
unit._.state = 'stopped';
|
|
407
406
|
unit._.children.forEach((child) => Unit.stop(child));
|
|
408
|
-
unit._.systems
|
|
407
|
+
unit._.systems['-stop'].forEach((listener) => Unit.scope(Unit.snapshot(unit), listener));
|
|
409
408
|
}
|
|
410
409
|
}
|
|
411
410
|
static update(unit) {
|
|
412
411
|
if (unit._.state === 'started') {
|
|
413
412
|
unit._.children.forEach((child) => Unit.update(child));
|
|
414
|
-
unit._.systems
|
|
413
|
+
unit._.systems['-update'].forEach((listener) => Unit.scope(Unit.snapshot(unit), listener));
|
|
415
414
|
}
|
|
416
415
|
}
|
|
417
416
|
static reset() {
|
|
@@ -419,7 +418,7 @@
|
|
|
419
418
|
(_a = Unit.root) === null || _a === void 0 ? void 0 : _a.finalize();
|
|
420
419
|
Unit.current = Unit.root = new Unit(null, null);
|
|
421
420
|
(_b = Unit.ticker) === null || _b === void 0 ? void 0 : _b.clear();
|
|
422
|
-
Unit.ticker = new Ticker((
|
|
421
|
+
Unit.ticker = new Ticker(() => {
|
|
423
422
|
Unit.start(Unit.root);
|
|
424
423
|
Unit.update(Unit.root);
|
|
425
424
|
});
|
|
@@ -561,7 +560,7 @@
|
|
|
561
560
|
}
|
|
562
561
|
else if (timer.stack.length === 0) {
|
|
563
562
|
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.current) }, options));
|
|
564
|
-
timer.unit.on('finalize', () => { UnitTimer.next(timer); });
|
|
563
|
+
timer.unit.on('-finalize', () => { UnitTimer.next(timer); });
|
|
565
564
|
}
|
|
566
565
|
else {
|
|
567
566
|
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.current) }, options));
|
|
@@ -570,7 +569,7 @@
|
|
|
570
569
|
static next(timer) {
|
|
571
570
|
if (timer.stack.length > 0) {
|
|
572
571
|
timer.unit = new Unit(Unit.current, UnitTimer.Component, timer.stack.shift());
|
|
573
|
-
timer.unit.on('finalize', () => { UnitTimer.next(timer); });
|
|
572
|
+
timer.unit.on('-finalize', () => { UnitTimer.next(timer); });
|
|
574
573
|
}
|
|
575
574
|
}
|
|
576
575
|
static Component(unit, options) {
|
|
@@ -589,7 +588,7 @@
|
|
|
589
588
|
}
|
|
590
589
|
}, duration: options.duration, iterations: options.iterations, easing: options.easing
|
|
591
590
|
});
|
|
592
|
-
unit.on('finalize', () => timer.clear());
|
|
591
|
+
unit.on('-finalize', () => timer.clear());
|
|
593
592
|
}
|
|
594
593
|
}
|
|
595
594
|
|
|
@@ -809,15 +808,6 @@
|
|
|
809
808
|
*/
|
|
810
809
|
transition(transition, duration = 0, easing = 'linear') {
|
|
811
810
|
return new UnitTimer({ transition, duration, easing, iterations: 1 });
|
|
812
|
-
},
|
|
813
|
-
style(text) {
|
|
814
|
-
const unit = new Unit(Unit.current);
|
|
815
|
-
const style = document.createElement('style');
|
|
816
|
-
style.textContent = text;
|
|
817
|
-
document.head.appendChild(style);
|
|
818
|
-
unit.on('finalize', () => {
|
|
819
|
-
document.head.removeChild(style);
|
|
820
|
-
});
|
|
821
811
|
}
|
|
822
812
|
});
|
|
823
813
|
|
|
@@ -909,7 +899,7 @@
|
|
|
909
899
|
if (resize.element) {
|
|
910
900
|
observer.observe(resize.element);
|
|
911
901
|
}
|
|
912
|
-
resize.on('finalize', () => {
|
|
902
|
+
resize.on('-finalize', () => {
|
|
913
903
|
if (resize.element) {
|
|
914
904
|
observer.unobserve(resize.element);
|
|
915
905
|
}
|
|
@@ -939,7 +929,7 @@
|
|
|
939
929
|
y: (state['ArrowUp'] ? -1 : 0) + (state['ArrowDown'] ? +1 : 0)
|
|
940
930
|
};
|
|
941
931
|
}
|
|
942
|
-
keyboard.on('finalize', () => {
|
|
932
|
+
keyboard.on('-finalize', () => {
|
|
943
933
|
window.removeEventListener('keydown', keydown);
|
|
944
934
|
window.removeEventListener('keyup', keyup);
|
|
945
935
|
});
|
|
@@ -950,8 +940,32 @@
|
|
|
950
940
|
internal.on('pointermove', (event) => unit.emit('-pointermove', { event, position: getPosition(unit.element, event) }));
|
|
951
941
|
internal.on('pointerup', (event) => unit.emit('-pointerup', { event, position: getPosition(unit.element, event) }));
|
|
952
942
|
internal.on('wheel', (event) => unit.emit('-wheel', { event, delta: { x: event.wheelDeltaX, y: event.wheelDeltaY } }));
|
|
953
|
-
internal.on('
|
|
954
|
-
internal.on('
|
|
943
|
+
internal.on('click', (event) => unit.emit('-click', { event, position: getPosition(unit.element, event) }));
|
|
944
|
+
internal.on('pointerover', (event) => unit.emit('-pointerover', { event, position: getPosition(unit.element, event) }));
|
|
945
|
+
internal.on('pointerout', (event) => unit.emit('-pointerout', { event, position: getPosition(unit.element, event) }));
|
|
946
|
+
document.addEventListener('pointerdown', pointerdownoutside);
|
|
947
|
+
document.addEventListener('pointerup', pointerupoutside);
|
|
948
|
+
document.addEventListener('click', clickoutside);
|
|
949
|
+
unit.on('-finalize', () => {
|
|
950
|
+
document.removeEventListener('pointerdown', pointerdownoutside);
|
|
951
|
+
document.removeEventListener('pointerup', pointerupoutside);
|
|
952
|
+
document.removeEventListener('click', clickoutside);
|
|
953
|
+
});
|
|
954
|
+
function pointerdownoutside(event) {
|
|
955
|
+
if (unit.element.contains(event.target) === false) {
|
|
956
|
+
unit.emit('-pointerdown:outside', { event, position: getPosition(unit.element, event) });
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
function pointerupoutside(event) {
|
|
960
|
+
if (unit.element.contains(event.target) === false) {
|
|
961
|
+
unit.emit('-pointerup:outside', { event, position: getPosition(unit.element, event) });
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
function clickoutside(event) {
|
|
965
|
+
if (unit.element.contains(event.target) === false) {
|
|
966
|
+
unit.emit('-click:outside', { event, position: getPosition(unit.element, event) });
|
|
967
|
+
}
|
|
968
|
+
}
|
|
955
969
|
const drag = xnew$1(DragEvent);
|
|
956
970
|
drag.on('-dragstart', (...args) => unit.emit('-dragstart', ...args));
|
|
957
971
|
drag.on('-dragmove', (...args) => unit.emit('-dragmove', ...args));
|
|
@@ -1004,7 +1018,7 @@
|
|
|
1004
1018
|
connect = false;
|
|
1005
1019
|
}
|
|
1006
1020
|
}
|
|
1007
|
-
internal.on('finalize', remove);
|
|
1021
|
+
internal.on('-finalize', remove);
|
|
1008
1022
|
});
|
|
1009
1023
|
unit.emit('-dragstart', { event, position });
|
|
1010
1024
|
}
|
|
@@ -1413,7 +1427,7 @@
|
|
|
1413
1427
|
}
|
|
1414
1428
|
const audio = {
|
|
1415
1429
|
load(path) {
|
|
1416
|
-
return
|
|
1430
|
+
return AudioFile.load(path);
|
|
1417
1431
|
},
|
|
1418
1432
|
synthesizer(props) {
|
|
1419
1433
|
return new Synthesizer(props);
|
|
@@ -1439,43 +1453,69 @@
|
|
|
1439
1453
|
.catch(() => {
|
|
1440
1454
|
console.warn(`"${path}" could not be loaded.`);
|
|
1441
1455
|
});
|
|
1456
|
+
this.amp = context.createGain();
|
|
1457
|
+
this.amp.gain.value = 1.0;
|
|
1458
|
+
this.amp.connect(master);
|
|
1459
|
+
this.fade = context.createGain();
|
|
1460
|
+
this.fade.gain.value = 1.0;
|
|
1461
|
+
this.fade.connect(this.amp);
|
|
1462
|
+
this.source = null;
|
|
1442
1463
|
this.start = null;
|
|
1443
1464
|
}
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
play(offset = 0, loop = false) {
|
|
1465
|
+
set volume(value) {
|
|
1466
|
+
this.amp.gain.value = value;
|
|
1467
|
+
}
|
|
1468
|
+
get volume() {
|
|
1469
|
+
return this.amp.gain.value;
|
|
1470
|
+
}
|
|
1471
|
+
play({ offset = 0, loop = false, fade = 0 } = {}) {
|
|
1451
1472
|
if (this.buffer !== undefined && this.start === null) {
|
|
1452
1473
|
this.source = context.createBufferSource();
|
|
1453
1474
|
this.source.buffer = this.buffer;
|
|
1454
1475
|
this.source.loop = loop;
|
|
1455
|
-
this.
|
|
1456
|
-
this.amp.gain.value = 1.0;
|
|
1457
|
-
this.source.connect(this.amp);
|
|
1458
|
-
this.amp.connect(master);
|
|
1476
|
+
this.source.connect(this.fade);
|
|
1459
1477
|
this.start = context.currentTime;
|
|
1460
1478
|
this.source.playbackRate.value = 1;
|
|
1461
1479
|
this.source.start(context.currentTime, offset / 1000);
|
|
1480
|
+
// Apply fade-in effect if fade duration is specified
|
|
1481
|
+
if (fade > 0) {
|
|
1482
|
+
this.fade.gain.setValueAtTime(0, context.currentTime);
|
|
1483
|
+
this.fade.gain.linearRampToValueAtTime(1.0, context.currentTime + fade / 1000);
|
|
1484
|
+
}
|
|
1462
1485
|
this.source.onended = () => {
|
|
1463
|
-
var _a
|
|
1486
|
+
var _a;
|
|
1464
1487
|
this.start = null;
|
|
1465
1488
|
(_a = this.source) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
1466
|
-
|
|
1489
|
+
this.source = null;
|
|
1467
1490
|
};
|
|
1468
1491
|
}
|
|
1469
1492
|
}
|
|
1470
|
-
pause() {
|
|
1471
|
-
var _a;
|
|
1493
|
+
pause({ fade = 0 } = {}) {
|
|
1494
|
+
var _a, _b;
|
|
1472
1495
|
if (this.buffer !== undefined && this.start !== null) {
|
|
1473
|
-
(_a = this.source) === null || _a === void 0 ? void 0 : _a.stop(context.currentTime);
|
|
1474
1496
|
const elapsed = (context.currentTime - this.start) % this.buffer.duration * 1000;
|
|
1497
|
+
// Apply fade-out effect if fade duration is specified
|
|
1498
|
+
if (fade > 0) {
|
|
1499
|
+
this.fade.gain.setValueAtTime(1.0, context.currentTime);
|
|
1500
|
+
this.fade.gain.linearRampToValueAtTime(0, context.currentTime + fade / 1000);
|
|
1501
|
+
(_a = this.source) === null || _a === void 0 ? void 0 : _a.stop(context.currentTime + fade / 1000);
|
|
1502
|
+
}
|
|
1503
|
+
else {
|
|
1504
|
+
(_b = this.source) === null || _b === void 0 ? void 0 : _b.stop(context.currentTime);
|
|
1505
|
+
}
|
|
1475
1506
|
this.start = null;
|
|
1476
1507
|
return elapsed;
|
|
1477
1508
|
}
|
|
1478
1509
|
}
|
|
1510
|
+
static load(path) {
|
|
1511
|
+
const music = new AudioFile(path);
|
|
1512
|
+
return xnew$1.promise(music.promise).then(() => music);
|
|
1513
|
+
}
|
|
1514
|
+
static clear(file) {
|
|
1515
|
+
var _a;
|
|
1516
|
+
file.amp.disconnect();
|
|
1517
|
+
(_a = file.source) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
1518
|
+
}
|
|
1479
1519
|
}
|
|
1480
1520
|
const keymap = {
|
|
1481
1521
|
'A0': 27.500, 'A#0': 29.135, 'B0': 30.868,
|
|
@@ -1560,7 +1600,7 @@
|
|
|
1560
1600
|
if (props.amp.envelope) {
|
|
1561
1601
|
const ADSR = props.amp.envelope.ADSR;
|
|
1562
1602
|
const adsr = [ADSR[0] / 1000, ADSR[1] / 1000, ADSR[2], ADSR[3] / 1000];
|
|
1563
|
-
const rate = adsr[0] === 0.0 ? 1.0 : Math.min(end / adsr[0], 1.0);
|
|
1603
|
+
const rate = adsr[0] === 0.0 ? 1.0 : Math.min(end / (adsr[0] + 0.001), 1.0);
|
|
1564
1604
|
stop = start + Math.max((adsr[0] + adsr[1]) * rate, end) + adsr[3];
|
|
1565
1605
|
}
|
|
1566
1606
|
else {
|
|
@@ -1590,7 +1630,8 @@
|
|
|
1590
1630
|
}, 2000);
|
|
1591
1631
|
}
|
|
1592
1632
|
function stopEnvelope(param, base, amount, ADSR) {
|
|
1593
|
-
const
|
|
1633
|
+
const end = dv > 0 ? dv : (context.currentTime - start);
|
|
1634
|
+
const rate = ADSR[0] === 0.0 ? 1.0 : Math.min(end / (ADSR[0] / 1000), 1.0);
|
|
1594
1635
|
if (rate < 1.0) {
|
|
1595
1636
|
param.cancelScheduledValues(start);
|
|
1596
1637
|
param.setValueAtTime(base, start);
|
|
@@ -1598,7 +1639,7 @@
|
|
|
1598
1639
|
param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000 * rate);
|
|
1599
1640
|
}
|
|
1600
1641
|
param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dv));
|
|
1601
|
-
param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate,
|
|
1642
|
+
param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, end) + ADSR[3] / 1000);
|
|
1602
1643
|
}
|
|
1603
1644
|
function startEnvelope(param, base, amount, ADSR) {
|
|
1604
1645
|
param.value = base;
|
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
|
}
|
|
@@ -141,7 +140,7 @@ class Timer {
|
|
|
141
140
|
p = Math.pow((1.0 - Math.pow((1.0 - p), 0.5)), 2.0);
|
|
142
141
|
}
|
|
143
142
|
else if (this.options.easing === 'ease') {
|
|
144
|
-
p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
|
|
143
|
+
p = (1.0 - Math.cos(p * Math.PI)) / 2.0; // todo
|
|
145
144
|
}
|
|
146
145
|
else if (this.options.easing === 'ease-in-out') {
|
|
147
146
|
p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
|
|
@@ -208,7 +207,7 @@ class Timer {
|
|
|
208
207
|
//----------------------------------------------------------------------------------------------------
|
|
209
208
|
// utils
|
|
210
209
|
//----------------------------------------------------------------------------------------------------
|
|
211
|
-
const SYSTEM_EVENTS = ['start', 'update', 'stop', 'finalize'];
|
|
210
|
+
const SYSTEM_EVENTS = ['-start', '-update', '-stop', '-finalize'];
|
|
212
211
|
//----------------------------------------------------------------------------------------------------
|
|
213
212
|
// unit
|
|
214
213
|
//----------------------------------------------------------------------------------------------------
|
|
@@ -303,7 +302,7 @@ class Unit {
|
|
|
303
302
|
components: [],
|
|
304
303
|
listeners: new MapMap(),
|
|
305
304
|
defines: {},
|
|
306
|
-
systems: { start: [], update: [], stop: [], finalize: [] },
|
|
305
|
+
systems: { '-start': [], '-update': [], '-stop': [], '-finalize': [] },
|
|
307
306
|
});
|
|
308
307
|
// nest html element
|
|
309
308
|
if (typeof unit._.target === 'string') {
|
|
@@ -319,7 +318,7 @@ class Unit {
|
|
|
319
318
|
if (unit._.state !== 'finalized') {
|
|
320
319
|
unit._.state = 'finalized';
|
|
321
320
|
unit._.children.forEach((child) => child.finalize());
|
|
322
|
-
unit._.systems
|
|
321
|
+
unit._.systems['-finalize'].forEach((listener) => Unit.scope(Unit.snapshot(unit), listener));
|
|
323
322
|
unit.off();
|
|
324
323
|
unit._.components.forEach((component) => Unit.component2units.delete(component, unit));
|
|
325
324
|
if (unit._.elements.length > 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
|
});
|
|
@@ -555,7 +554,7 @@ class UnitTimer {
|
|
|
555
554
|
}
|
|
556
555
|
else if (timer.stack.length === 0) {
|
|
557
556
|
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.current) }, options));
|
|
558
|
-
timer.unit.on('finalize', () => { UnitTimer.next(timer); });
|
|
557
|
+
timer.unit.on('-finalize', () => { UnitTimer.next(timer); });
|
|
559
558
|
}
|
|
560
559
|
else {
|
|
561
560
|
timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.current) }, options));
|
|
@@ -564,7 +563,7 @@ class UnitTimer {
|
|
|
564
563
|
static next(timer) {
|
|
565
564
|
if (timer.stack.length > 0) {
|
|
566
565
|
timer.unit = new Unit(Unit.current, UnitTimer.Component, timer.stack.shift());
|
|
567
|
-
timer.unit.on('finalize', () => { UnitTimer.next(timer); });
|
|
566
|
+
timer.unit.on('-finalize', () => { UnitTimer.next(timer); });
|
|
568
567
|
}
|
|
569
568
|
}
|
|
570
569
|
static Component(unit, options) {
|
|
@@ -583,7 +582,7 @@ class UnitTimer {
|
|
|
583
582
|
}
|
|
584
583
|
}, duration: options.duration, iterations: options.iterations, easing: options.easing
|
|
585
584
|
});
|
|
586
|
-
unit.on('finalize', () => timer.clear());
|
|
585
|
+
unit.on('-finalize', () => timer.clear());
|
|
587
586
|
}
|
|
588
587
|
}
|
|
589
588
|
|
|
@@ -803,15 +802,6 @@ const xnew$1 = Object.assign(function (...args) {
|
|
|
803
802
|
*/
|
|
804
803
|
transition(transition, duration = 0, easing = 'linear') {
|
|
805
804
|
return new UnitTimer({ transition, duration, easing, iterations: 1 });
|
|
806
|
-
},
|
|
807
|
-
style(text) {
|
|
808
|
-
const unit = new Unit(Unit.current);
|
|
809
|
-
const style = document.createElement('style');
|
|
810
|
-
style.textContent = text;
|
|
811
|
-
document.head.appendChild(style);
|
|
812
|
-
unit.on('finalize', () => {
|
|
813
|
-
document.head.removeChild(style);
|
|
814
|
-
});
|
|
815
805
|
}
|
|
816
806
|
});
|
|
817
807
|
|
|
@@ -903,7 +893,7 @@ function ResizeEvent(resize) {
|
|
|
903
893
|
if (resize.element) {
|
|
904
894
|
observer.observe(resize.element);
|
|
905
895
|
}
|
|
906
|
-
resize.on('finalize', () => {
|
|
896
|
+
resize.on('-finalize', () => {
|
|
907
897
|
if (resize.element) {
|
|
908
898
|
observer.unobserve(resize.element);
|
|
909
899
|
}
|
|
@@ -933,7 +923,7 @@ function KeyboardEvent(keyboard) {
|
|
|
933
923
|
y: (state['ArrowUp'] ? -1 : 0) + (state['ArrowDown'] ? +1 : 0)
|
|
934
924
|
};
|
|
935
925
|
}
|
|
936
|
-
keyboard.on('finalize', () => {
|
|
926
|
+
keyboard.on('-finalize', () => {
|
|
937
927
|
window.removeEventListener('keydown', keydown);
|
|
938
928
|
window.removeEventListener('keyup', keyup);
|
|
939
929
|
});
|
|
@@ -944,8 +934,32 @@ function PointerEvent(unit) {
|
|
|
944
934
|
internal.on('pointermove', (event) => unit.emit('-pointermove', { event, position: getPosition(unit.element, event) }));
|
|
945
935
|
internal.on('pointerup', (event) => unit.emit('-pointerup', { event, position: getPosition(unit.element, event) }));
|
|
946
936
|
internal.on('wheel', (event) => unit.emit('-wheel', { event, delta: { x: event.wheelDeltaX, y: event.wheelDeltaY } }));
|
|
947
|
-
internal.on('
|
|
948
|
-
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
|
+
}
|
|
949
963
|
const drag = xnew$1(DragEvent);
|
|
950
964
|
drag.on('-dragstart', (...args) => unit.emit('-dragstart', ...args));
|
|
951
965
|
drag.on('-dragmove', (...args) => unit.emit('-dragmove', ...args));
|
|
@@ -998,7 +1012,7 @@ function DragEvent(unit) {
|
|
|
998
1012
|
connect = false;
|
|
999
1013
|
}
|
|
1000
1014
|
}
|
|
1001
|
-
internal.on('finalize', remove);
|
|
1015
|
+
internal.on('-finalize', remove);
|
|
1002
1016
|
});
|
|
1003
1017
|
unit.emit('-dragstart', { event, position });
|
|
1004
1018
|
}
|
|
@@ -1407,7 +1421,7 @@ function initialize() {
|
|
|
1407
1421
|
}
|
|
1408
1422
|
const audio = {
|
|
1409
1423
|
load(path) {
|
|
1410
|
-
return
|
|
1424
|
+
return AudioFile.load(path);
|
|
1411
1425
|
},
|
|
1412
1426
|
synthesizer(props) {
|
|
1413
1427
|
return new Synthesizer(props);
|
|
@@ -1433,43 +1447,69 @@ class AudioFile {
|
|
|
1433
1447
|
.catch(() => {
|
|
1434
1448
|
console.warn(`"${path}" could not be loaded.`);
|
|
1435
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;
|
|
1436
1457
|
this.start = null;
|
|
1437
1458
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
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 } = {}) {
|
|
1445
1466
|
if (this.buffer !== undefined && this.start === null) {
|
|
1446
1467
|
this.source = context.createBufferSource();
|
|
1447
1468
|
this.source.buffer = this.buffer;
|
|
1448
1469
|
this.source.loop = loop;
|
|
1449
|
-
this.
|
|
1450
|
-
this.amp.gain.value = 1.0;
|
|
1451
|
-
this.source.connect(this.amp);
|
|
1452
|
-
this.amp.connect(master);
|
|
1470
|
+
this.source.connect(this.fade);
|
|
1453
1471
|
this.start = context.currentTime;
|
|
1454
1472
|
this.source.playbackRate.value = 1;
|
|
1455
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
|
+
}
|
|
1456
1479
|
this.source.onended = () => {
|
|
1457
|
-
var _a
|
|
1480
|
+
var _a;
|
|
1458
1481
|
this.start = null;
|
|
1459
1482
|
(_a = this.source) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
1460
|
-
|
|
1483
|
+
this.source = null;
|
|
1461
1484
|
};
|
|
1462
1485
|
}
|
|
1463
1486
|
}
|
|
1464
|
-
pause() {
|
|
1465
|
-
var _a;
|
|
1487
|
+
pause({ fade = 0 } = {}) {
|
|
1488
|
+
var _a, _b;
|
|
1466
1489
|
if (this.buffer !== undefined && this.start !== null) {
|
|
1467
|
-
(_a = this.source) === null || _a === void 0 ? void 0 : _a.stop(context.currentTime);
|
|
1468
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
|
+
}
|
|
1469
1500
|
this.start = null;
|
|
1470
1501
|
return elapsed;
|
|
1471
1502
|
}
|
|
1472
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
|
+
}
|
|
1473
1513
|
}
|
|
1474
1514
|
const keymap = {
|
|
1475
1515
|
'A0': 27.500, 'A#0': 29.135, 'B0': 30.868,
|
|
@@ -1554,7 +1594,7 @@ class Synthesizer {
|
|
|
1554
1594
|
if (props.amp.envelope) {
|
|
1555
1595
|
const ADSR = props.amp.envelope.ADSR;
|
|
1556
1596
|
const adsr = [ADSR[0] / 1000, ADSR[1] / 1000, ADSR[2], ADSR[3] / 1000];
|
|
1557
|
-
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);
|
|
1558
1598
|
stop = start + Math.max((adsr[0] + adsr[1]) * rate, end) + adsr[3];
|
|
1559
1599
|
}
|
|
1560
1600
|
else {
|
|
@@ -1584,7 +1624,8 @@ class Synthesizer {
|
|
|
1584
1624
|
}, 2000);
|
|
1585
1625
|
}
|
|
1586
1626
|
function stopEnvelope(param, base, amount, ADSR) {
|
|
1587
|
-
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);
|
|
1588
1629
|
if (rate < 1.0) {
|
|
1589
1630
|
param.cancelScheduledValues(start);
|
|
1590
1631
|
param.setValueAtTime(base, start);
|
|
@@ -1592,7 +1633,7 @@ class Synthesizer {
|
|
|
1592
1633
|
param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000 * rate);
|
|
1593
1634
|
}
|
|
1594
1635
|
param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dv));
|
|
1595
|
-
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);
|
|
1596
1637
|
}
|
|
1597
1638
|
function startEnvelope(param, base, amount, ADSR) {
|
|
1598
1639
|
param.value = base;
|