@mulsense/xnew 0.1.8 → 0.1.9

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.
@@ -1,2 +1,55 @@
1
- export declare const context: AudioContext;
2
- export declare const master: GainNode;
1
+ export declare const audio: {
2
+ load(path: string): AudioFile;
3
+ synthesizer(props: SynthProps): Synthesizer;
4
+ volume: number;
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
+ type SynthProps = {
17
+ oscillator: OscillatorOptions;
18
+ amp: AmpOptions;
19
+ filter?: FilterOptions;
20
+ reverb?: ReverbOptions;
21
+ bpm?: number;
22
+ };
23
+ type OscillatorOptions = {
24
+ type: OscillatorType;
25
+ envelope?: Envelope;
26
+ LFO?: LFO;
27
+ };
28
+ type FilterOptions = {
29
+ type: BiquadFilterType;
30
+ cutoff: number;
31
+ };
32
+ type AmpOptions = {
33
+ envelope: Envelope;
34
+ };
35
+ type ReverbOptions = {
36
+ time: number;
37
+ mix: number;
38
+ };
39
+ type Envelope = {
40
+ amount: number;
41
+ ADSR: [number, number, number, number];
42
+ };
43
+ type LFO = {
44
+ amount: number;
45
+ type: OscillatorType;
46
+ rate: number;
47
+ };
48
+ declare class Synthesizer {
49
+ props: SynthProps;
50
+ constructor(props: SynthProps);
51
+ press(frequency: number | string, duration?: number | string, wait?: number): {
52
+ release: () => void;
53
+ } | undefined;
54
+ }
55
+ export {};
@@ -43,13 +43,14 @@ export declare class UnitPromise {
43
43
  export declare class Unit {
44
44
  [key: string]: any;
45
45
  _: UnitInternal;
46
- constructor(parent: Unit | null, target: Object | null, component?: Function | string, props?: Object);
46
+ constructor(parent: Unit | null, ...args: any[]);
47
47
  get element(): UnitElement;
48
48
  get components(): Function[];
49
49
  start(): void;
50
50
  stop(): void;
51
51
  finalize(): void;
52
52
  reboot(): void;
53
+ append(...args: any[]): void;
53
54
  static initialize(unit: Unit, anchor: UnitElement | null): void;
54
55
  static finalize(unit: Unit): void;
55
56
  static nest(unit: Unit, tag: string): UnitElement;
@@ -67,9 +68,9 @@ export declare class Unit {
67
68
  static scope(snapshot: Snapshot, func: Function, ...args: any[]): any;
68
69
  static snapshot(unit: Unit): Snapshot;
69
70
  static context(unit: Unit, key: string, value?: any): any;
70
- static componentUnits: MapSet<Function, Unit>;
71
+ static component2units: MapSet<Function, Unit>;
71
72
  static find(component: Function): Unit[];
72
- static typeUnits: MapSet<string, Unit>;
73
+ static type2units: MapSet<string, Unit>;
73
74
  on(type: string, listener: Function, options?: boolean | AddEventListenerOptions): void;
74
75
  off(type?: string, listener?: Function): void;
75
76
  emit(type: string, ...args: any[]): void;
@@ -119,16 +119,6 @@ export declare const xnew: CreateUnit & {
119
119
  * buttons.forEach(btn => btn.finalize())
120
120
  */
121
121
  find(component: Function): Unit[];
122
- /**
123
- * Appends new components to existing component(s) in the tree
124
- * @param anchor - Component function or Unit instance to append to
125
- * @param args - Arguments to pass to xnew for creating child components
126
- * @throws Error if anchor parameter is invalid
127
- * @example
128
- * xnew.append(MyContainer, ChildComponent, { prop: 'value' })
129
- * xnew.append(unitInstance, AnotherComponent)
130
- */
131
- append(anchor: Unit, ...args: any[]): void;
132
122
  /**
133
123
  * Executes a callback once after a delay, managed by component lifecycle
134
124
  * @param callback - Function to execute after delay
@@ -138,7 +128,7 @@ export declare const xnew: CreateUnit & {
138
128
  * const timer = xnew.timeout(() => console.log('Delayed'), 1000)
139
129
  * // Cancel if needed: timer.clear()
140
130
  */
141
- timeout(callback: Function, delay: number): any;
131
+ timeout(callback: Function, delay?: number): any;
142
132
  /**
143
133
  * Executes a callback repeatedly at specified intervals, managed by component lifecycle
144
134
  * @param callback - Function to execute at each interval
@@ -10,8 +10,7 @@ import { TabFrame, TabButton, TabContent } from './basics/Tab';
10
10
  import { AccordionFrame, AccordionHeader, AccordionBullet, AccordionContent } from './basics/Accordion';
11
11
  import { DragFrame, DragTarget } from './basics/Drag';
12
12
  import { AnalogStick, DirectionalPad } from './basics/Controller';
13
- import { load } from './audio/file';
14
- import { synthesizer } from './audio/synthesizer';
13
+ import { audio } from './audio/audio';
15
14
  declare const basics: {
16
15
  Screen: typeof Screen;
17
16
  PointerEvent: typeof PointerEvent;
@@ -32,12 +31,6 @@ declare const basics: {
32
31
  AnalogStick: typeof AnalogStick;
33
32
  DirectionalPad: typeof DirectionalPad;
34
33
  };
35
- declare const audio: {
36
- master: GainNode;
37
- context: AudioContext;
38
- synthesizer: typeof synthesizer;
39
- load: typeof load;
40
- };
41
34
  declare namespace xnew {
42
35
  type Unit = InstanceType<typeof Unit>;
43
36
  }
package/dist/xnew.d.ts CHANGED
@@ -69,13 +69,14 @@ declare class UnitPromise {
69
69
  declare class Unit {
70
70
  [key: string]: any;
71
71
  _: UnitInternal;
72
- constructor(parent: Unit | null, target: Object | null, component?: Function | string, props?: Object);
72
+ constructor(parent: Unit | null, ...args: any[]);
73
73
  get element(): UnitElement;
74
74
  get components(): Function[];
75
75
  start(): void;
76
76
  stop(): void;
77
77
  finalize(): void;
78
78
  reboot(): void;
79
+ append(...args: any[]): void;
79
80
  static initialize(unit: Unit, anchor: UnitElement | null): void;
80
81
  static finalize(unit: Unit): void;
81
82
  static nest(unit: Unit, tag: string): UnitElement;
@@ -93,9 +94,9 @@ declare class Unit {
93
94
  static scope(snapshot: Snapshot, func: Function, ...args: any[]): any;
94
95
  static snapshot(unit: Unit): Snapshot;
95
96
  static context(unit: Unit, key: string, value?: any): any;
96
- static componentUnits: MapSet<Function, Unit>;
97
+ static component2units: MapSet<Function, Unit>;
97
98
  static find(component: Function): Unit[];
98
- static typeUnits: MapSet<string, Unit>;
99
+ static type2units: MapSet<string, Unit>;
99
100
  on(type: string, listener: Function, options?: boolean | AddEventListenerOptions): void;
100
101
  off(type?: string, listener?: Function): void;
101
102
  emit(type: string, ...args: any[]): void;
@@ -223,16 +224,6 @@ declare const xnew$1: CreateUnit & {
223
224
  * buttons.forEach(btn => btn.finalize())
224
225
  */
225
226
  find(component: Function): Unit[];
226
- /**
227
- * Appends new components to existing component(s) in the tree
228
- * @param anchor - Component function or Unit instance to append to
229
- * @param args - Arguments to pass to xnew for creating child components
230
- * @throws Error if anchor parameter is invalid
231
- * @example
232
- * xnew.append(MyContainer, ChildComponent, { prop: 'value' })
233
- * xnew.append(unitInstance, AnotherComponent)
234
- */
235
- append(anchor: Unit, ...args: any[]): void;
236
227
  /**
237
228
  * Executes a callback once after a delay, managed by component lifecycle
238
229
  * @param callback - Function to execute after delay
@@ -242,7 +233,7 @@ declare const xnew$1: CreateUnit & {
242
233
  * const timer = xnew.timeout(() => console.log('Delayed'), 1000)
243
234
  * // Cancel if needed: timer.clear()
244
235
  */
245
- timeout(callback: Function, delay: number): any;
236
+ timeout(callback: Function, delay?: number): any;
246
237
  /**
247
238
  * Executes a callback repeatedly at specified intervals, managed by component lifecycle
248
239
  * @param callback - Function to execute at each interval
@@ -395,7 +386,11 @@ declare function DirectionalPad(self: Unit, { size, diagonal, fill, fillOpacity,
395
386
  strokeLinejoin?: string;
396
387
  }): void;
397
388
 
398
- declare function load(path: string): AudioFile;
389
+ declare const audio: {
390
+ load(path: string): AudioFile;
391
+ synthesizer(props: SynthProps): Synthesizer;
392
+ volume: number;
393
+ };
399
394
  declare class AudioFile {
400
395
  buffer?: AudioBuffer;
401
396
  promise: Promise<void>;
@@ -406,8 +401,6 @@ declare class AudioFile {
406
401
  play(offset?: number, loop?: boolean): void;
407
402
  pause(): number | undefined;
408
403
  }
409
-
410
- declare function synthesizer(props: SynthProps): Synthesizer;
411
404
  type SynthProps = {
412
405
  oscillator: OscillatorOptions;
413
406
  amp: AmpOptions;
@@ -468,12 +461,6 @@ declare const basics: {
468
461
  AnalogStick: typeof AnalogStick;
469
462
  DirectionalPad: typeof DirectionalPad;
470
463
  };
471
- declare const audio: {
472
- master: GainNode;
473
- context: AudioContext;
474
- synthesizer: typeof synthesizer;
475
- load: typeof load;
476
- };
477
464
  declare namespace xnew {
478
465
  type Unit = InstanceType<typeof Unit>;
479
466
  }
package/dist/xnew.js CHANGED
@@ -220,8 +220,26 @@
220
220
  // unit
221
221
  //----------------------------------------------------------------------------------------------------
222
222
  class Unit {
223
- constructor(parent, target, component, props) {
223
+ constructor(parent, ...args) {
224
224
  var _a;
225
+ let target;
226
+ if (args[0] instanceof HTMLElement || args[0] instanceof SVGElement) {
227
+ target = args.shift(); // an existing html element
228
+ }
229
+ else if (typeof args[0] === 'string' && args[0].match(/<((\w+)[^>]*?)\/?>/)) {
230
+ target = args.shift();
231
+ }
232
+ else if (typeof args[0] === 'string') {
233
+ const query = args.shift();
234
+ target = document.querySelector(query);
235
+ if (target === null)
236
+ throw new Error(`'${query}' can not be found.`);
237
+ }
238
+ else {
239
+ target = null;
240
+ }
241
+ const component = args.shift();
242
+ const props = args.shift();
225
243
  let baseElement;
226
244
  if (target instanceof HTMLElement || target instanceof SVGElement) {
227
245
  baseElement = target;
@@ -274,6 +292,9 @@
274
292
  Unit.finalize(this);
275
293
  Unit.initialize(this, anchor);
276
294
  }
295
+ append(...args) {
296
+ new Unit(this, ...args);
297
+ }
277
298
  static initialize(unit, anchor) {
278
299
  const backup = Unit.current;
279
300
  Unit.current = unit;
@@ -315,7 +336,7 @@
315
336
  unit._.systems.finalize.forEach((listener) => Unit.scope(Unit.snapshot(unit), listener));
316
337
  unit.off();
317
338
  Unit.suboff(unit, null);
318
- unit._.components.forEach((component) => Unit.componentUnits.delete(component, unit));
339
+ unit._.components.forEach((component) => Unit.component2units.delete(component, unit));
319
340
  if (unit._.elements.length > 0) {
320
341
  unit._.baseElement.removeChild(unit._.elements[0]);
321
342
  unit._.currentElement = unit._.baseElement;
@@ -353,7 +374,7 @@
353
374
  static extend(unit, component, props) {
354
375
  var _a;
355
376
  unit._.components.push(component);
356
- Unit.componentUnits.add(component, unit);
377
+ Unit.component2units.add(component, unit);
357
378
  const defines = (_a = component(unit, props)) !== null && _a !== void 0 ? _a : {};
358
379
  Object.keys(defines).forEach((key) => {
359
380
  if (unit[key] !== undefined && unit._.defines[key] === undefined) {
@@ -361,12 +382,10 @@
361
382
  }
362
383
  const descriptor = Object.getOwnPropertyDescriptor(defines, key);
363
384
  const wrapper = { configurable: true, enumerable: true };
364
- if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.get) {
385
+ if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.get)
365
386
  wrapper.get = Unit.wrap(unit, descriptor.get);
366
- }
367
- if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.set) {
387
+ if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.set)
368
388
  wrapper.set = Unit.wrap(unit, descriptor.set);
369
- }
370
389
  if (typeof (descriptor === null || descriptor === void 0 ? void 0 : descriptor.value) === 'function') {
371
390
  wrapper.value = Unit.wrap(unit, descriptor.value);
372
391
  }
@@ -452,7 +471,7 @@
452
471
  }
453
472
  static find(component) {
454
473
  var _a;
455
- return [...((_a = Unit.componentUnits.get(component)) !== null && _a !== void 0 ? _a : [])];
474
+ return [...((_a = Unit.component2units.get(component)) !== null && _a !== void 0 ? _a : [])];
456
475
  }
457
476
  on(type, listener, options) {
458
477
  if (this._.state === 'finalized')
@@ -464,7 +483,7 @@
464
483
  if (this._.listeners1.has(type, listener) === false) {
465
484
  const execute = Unit.wrap(Unit.current, listener);
466
485
  this._.listeners1.set(type, listener, [this.element, execute]);
467
- Unit.typeUnits.add(type, this);
486
+ Unit.type2units.add(type, this);
468
487
  if (/^[A-Za-z]/.test(type)) {
469
488
  this.element.addEventListener(type, execute, options);
470
489
  }
@@ -488,7 +507,7 @@
488
507
  }
489
508
  });
490
509
  if (this._.listeners1.has(type) === false) {
491
- Unit.typeUnits.delete(type, this);
510
+ Unit.type2units.delete(type, this);
492
511
  }
493
512
  });
494
513
  }
@@ -497,7 +516,7 @@
497
516
  if (this._.state === 'finalized')
498
517
  return;
499
518
  if (type[0] === '+') {
500
- (_a = Unit.typeUnits.get(type)) === null || _a === void 0 ? void 0 : _a.forEach((unit) => {
519
+ (_a = Unit.type2units.get(type)) === null || _a === void 0 ? void 0 : _a.forEach((unit) => {
501
520
  var _a;
502
521
  (_a = unit._.listeners1.get(type)) === null || _a === void 0 ? void 0 : _a.forEach(([_, execute]) => execute(...args));
503
522
  });
@@ -531,36 +550,17 @@
531
550
  });
532
551
  }
533
552
  }
534
- Unit.componentUnits = new MapSet();
553
+ Unit.component2units = new MapSet();
535
554
  //----------------------------------------------------------------------------------------------------
536
555
  // event
537
556
  //----------------------------------------------------------------------------------------------------
538
- Unit.typeUnits = new MapSet();
557
+ Unit.type2units = new MapSet();
539
558
 
540
559
  const xnew$1 = Object.assign(function (...args) {
541
560
  if (Unit.root === undefined) {
542
561
  Unit.reset();
543
562
  }
544
- let target;
545
- if (args[0] instanceof HTMLElement || args[0] instanceof SVGElement) {
546
- target = args.shift(); // an existing html element
547
- }
548
- else if (typeof args[0] === 'string') {
549
- const str = args.shift(); // a selector for an existing html element
550
- if (str.match(/<([^>]*)\/?>/)) {
551
- target = str;
552
- }
553
- else {
554
- target = document.querySelector(str);
555
- if (target == null) {
556
- throw new Error(`'${str}' can not be found.`);
557
- }
558
- }
559
- }
560
- else {
561
- target = null;
562
- }
563
- return new Unit(Unit.current, target, ...args);
563
+ return new Unit(Unit.current, ...args);
564
564
  }, {
565
565
  /**
566
566
  * Creates a nested HTML/SVG element within the current component
@@ -733,27 +733,6 @@
733
733
  throw new Error('xnew.find(component: Function): [component] is invalid.');
734
734
  }
735
735
  },
736
- /**
737
- * Appends new components to existing component(s) in the tree
738
- * @param anchor - Component function or Unit instance to append to
739
- * @param args - Arguments to pass to xnew for creating child components
740
- * @throws Error if anchor parameter is invalid
741
- * @example
742
- * xnew.append(MyContainer, ChildComponent, { prop: 'value' })
743
- * xnew.append(unitInstance, AnotherComponent)
744
- */
745
- append(anchor, ...args) {
746
- if (typeof anchor === 'function') {
747
- const units = Unit.find(anchor);
748
- Unit.scope(Unit.snapshot(units[0]), xnew$1, ...args);
749
- }
750
- else if (anchor instanceof Unit) {
751
- Unit.scope(Unit.snapshot(anchor), xnew$1, ...args);
752
- }
753
- else {
754
- throw new Error('xnew.append(anchor: Function | Unit, xnew arguments): [anchor] is invalid.');
755
- }
756
- },
757
736
  /**
758
737
  * Executes a callback once after a delay, managed by component lifecycle
759
738
  * @param callback - Function to execute after delay
@@ -763,7 +742,7 @@
763
742
  * const timer = xnew.timeout(() => console.log('Delayed'), 1000)
764
743
  * // Cancel if needed: timer.clear()
765
744
  */
766
- timeout(callback, delay) {
745
+ timeout(callback, delay = 0) {
767
746
  const snapshot = Unit.snapshot(Unit.current);
768
747
  const unit = xnew$1((self) => {
769
748
  const timer = new Timer(() => {
@@ -832,21 +811,21 @@
832
811
  const timer = new Timer(() => {
833
812
  Unit.scope(snapshot, callback, 1.0);
834
813
  self.finalize();
835
- }, (progress) => {
836
- if (progress < 1.0) {
814
+ }, (x) => {
815
+ if (x < 1.0) {
837
816
  if (easing === 'ease-out') {
838
- progress = Math.pow((1.0 - Math.pow((1.0 - progress), 2.0)), 0.5);
817
+ x = Math.pow((1.0 - Math.pow((1.0 - x), 2.0)), 0.5);
839
818
  }
840
819
  else if (easing === 'ease-in') {
841
- progress = Math.pow((1.0 - Math.pow((1.0 - progress), 0.5)), 2.0);
820
+ x = Math.pow((1.0 - Math.pow((1.0 - x), 0.5)), 2.0);
842
821
  }
843
822
  else if (easing === 'ease') {
844
- progress = (1.0 - Math.cos(progress * Math.PI)) / 2.0;
823
+ x = (1.0 - Math.cos(x * Math.PI)) / 2.0;
845
824
  }
846
825
  else if (easing === 'ease-in-out') {
847
- progress = (1.0 - Math.cos(progress * Math.PI)) / 2.0;
826
+ x = (1.0 - Math.cos(x * Math.PI)) / 2.0;
848
827
  }
849
- Unit.scope(snapshot, callback, progress);
828
+ Unit.scope(snapshot, callback, x);
850
829
  }
851
830
  }, interval);
852
831
  self.on('finalize', () => {
@@ -1473,29 +1452,41 @@
1473
1452
  const master = context.createGain();
1474
1453
  master.gain.value = 1.0;
1475
1454
  master.connect(context.destination);
1476
-
1477
- function load(path) {
1478
- return new AudioFile(path);
1455
+ window.addEventListener('touchstart', initialize, true);
1456
+ window.addEventListener('mousedown', initialize, true);
1457
+ function initialize() {
1458
+ new Synthesizer({ oscillator: { type: 'sine' }, amp: { envelope: { amount: 0, ADSR: [0, 0, 0, 0] } } }).press(440);
1459
+ window.removeEventListener('touchstart', initialize, true);
1460
+ window.removeEventListener('mousedown', initialize, true);
1479
1461
  }
1480
- const store = new Map();
1462
+ const audio = {
1463
+ load(path) {
1464
+ return new AudioFile(path);
1465
+ },
1466
+ synthesizer(props) {
1467
+ return new Synthesizer(props);
1468
+ },
1469
+ get volume() {
1470
+ return master.gain.value;
1471
+ },
1472
+ set volume(value) {
1473
+ master.gain.value = value;
1474
+ }
1475
+ };
1476
+ //----------------------------------------------------------------------------------------------------
1477
+ // audio file
1478
+ //----------------------------------------------------------------------------------------------------
1481
1479
  class AudioFile {
1482
1480
  constructor(path) {
1483
- if (store.has(path)) {
1484
- this.buffer = store.get(path);
1485
- this.promise = Promise.resolve();
1486
- }
1487
- else {
1488
- this.promise = fetch(path)
1489
- .then((response) => response.arrayBuffer())
1490
- .then((response) => context.decodeAudioData(response))
1491
- .then((response) => {
1492
- this.buffer = response;
1493
- })
1494
- .catch(() => {
1495
- console.warn(`"${path}" could not be loaded.`);
1496
- });
1497
- store.set(path, this.buffer);
1498
- }
1481
+ this.promise = fetch(path)
1482
+ .then((response) => response.arrayBuffer())
1483
+ .then((response) => context.decodeAudioData(response))
1484
+ .then((response) => {
1485
+ this.buffer = response;
1486
+ })
1487
+ .catch(() => {
1488
+ console.warn(`"${path}" could not be loaded.`);
1489
+ });
1499
1490
  this.start = null;
1500
1491
  }
1501
1492
  // set volume(value: number) {
@@ -1534,17 +1525,6 @@
1534
1525
  }
1535
1526
  }
1536
1527
  }
1537
-
1538
- function synthesizer(props) {
1539
- return new Synthesizer(props);
1540
- }
1541
- window.addEventListener('touchstart', initialize, true);
1542
- window.addEventListener('mousedown', initialize, true);
1543
- function initialize() {
1544
- new Synthesizer({ oscillator: { type: 'sine' }, amp: { envelope: { amount: 0, ADSR: [0, 0, 0, 0] } } }).press(440);
1545
- window.removeEventListener('touchstart', initialize, true);
1546
- window.removeEventListener('mousedown', initialize, true);
1547
- }
1548
1528
  const keymap = {
1549
1529
  'A0': 27.500, 'A#0': 29.135, 'B0': 30.868,
1550
1530
  '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,
@@ -1560,23 +1540,21 @@
1560
1540
  '1m': 4.000, '2n': 2.000, '4n': 1.000, '8n': 0.500, '16n': 0.250, '32n': 0.125,
1561
1541
  };
1562
1542
  class Synthesizer {
1563
- constructor(props) {
1564
- this.props = props;
1565
- }
1543
+ constructor(props) { this.props = props; }
1566
1544
  press(frequency, duration, wait) {
1567
1545
  var _a;
1568
1546
  const props = this.props;
1569
- const freq = typeof frequency === 'string' ? keymap[frequency] : frequency;
1570
- const dura = typeof duration === 'string' ? (notemap[duration] * 60 / ((_a = props.bpm) !== null && _a !== void 0 ? _a : 120)) : (typeof duration === 'number' ? (duration / 1000) : 0);
1547
+ const fv = typeof frequency === 'string' ? keymap[frequency] : frequency;
1548
+ const dv = typeof duration === 'string' ? (notemap[duration] * 60 / ((_a = props.bpm) !== null && _a !== void 0 ? _a : 120)) : (typeof duration === 'number' ? (duration / 1000) : 0);
1571
1549
  const start = context.currentTime + (wait !== null && wait !== void 0 ? wait : 0) / 1000;
1572
1550
  const nodes = {};
1573
1551
  nodes.oscillator = context.createOscillator();
1574
1552
  nodes.oscillator.type = props.oscillator.type;
1575
- nodes.oscillator.frequency.value = freq;
1553
+ nodes.oscillator.frequency.value = fv;
1576
1554
  if (props.oscillator.LFO) {
1577
1555
  nodes.oscillatorLFO = context.createOscillator();
1578
1556
  nodes.oscillatorLFODepth = context.createGain();
1579
- nodes.oscillatorLFODepth.gain.value = freq * (Math.pow(2.0, props.oscillator.LFO.amount / 12.0) - 1.0);
1557
+ nodes.oscillatorLFODepth.gain.value = fv * (Math.pow(2.0, props.oscillator.LFO.amount / 12.0) - 1.0);
1580
1558
  nodes.oscillatorLFO.type = props.oscillator.LFO.type;
1581
1559
  nodes.oscillatorLFO.frequency.value = props.oscillator.LFO.rate;
1582
1560
  nodes.oscillatorLFO.start(start);
@@ -1589,7 +1567,7 @@
1589
1567
  nodes.target.gain.value = 1.0;
1590
1568
  nodes.amp.connect(nodes.target);
1591
1569
  nodes.target.connect(master);
1592
- if (props.filter && props.filter.type && props.filter.cutoff) {
1570
+ if (props.filter) {
1593
1571
  nodes.filter = context.createBiquadFilter();
1594
1572
  nodes.filter.type = props.filter.type;
1595
1573
  nodes.filter.frequency.value = props.filter.cutoff;
@@ -1611,22 +1589,22 @@
1611
1589
  nodes.convolverDepth.connect(master);
1612
1590
  }
1613
1591
  if (props.oscillator.envelope) {
1614
- const amount = freq * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
1615
- startEnvelope(nodes.oscillator.frequency, freq, amount, props.oscillator.envelope.ADSR);
1592
+ const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
1593
+ startEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
1616
1594
  }
1617
1595
  if (props.amp.envelope) {
1618
1596
  startEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
1619
1597
  }
1620
- let stop = null;
1621
1598
  nodes.oscillator.start(start);
1622
- if (dura > 0) {
1599
+ if (dv > 0) {
1623
1600
  release();
1624
1601
  }
1625
1602
  else {
1626
1603
  return { release };
1627
1604
  }
1628
1605
  function release() {
1629
- const end = dura > 0 ? dura : (context.currentTime - start);
1606
+ let stop = null;
1607
+ const end = dv > 0 ? dv : (context.currentTime - start);
1630
1608
  if (props.amp.envelope) {
1631
1609
  const ADSR = props.amp.envelope.ADSR;
1632
1610
  const adsr = [ADSR[0] / 1000, ADSR[1] / 1000, ADSR[2], ADSR[3] / 1000];
@@ -1640,8 +1618,8 @@
1640
1618
  nodes.oscillatorLFO.stop(stop);
1641
1619
  }
1642
1620
  if (props.oscillator.envelope) {
1643
- const amount = freq * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
1644
- stopEnvelope(nodes.oscillator.frequency, freq, amount, props.oscillator.envelope.ADSR);
1621
+ const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
1622
+ stopEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
1645
1623
  }
1646
1624
  if (props.amp.envelope) {
1647
1625
  stopEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
@@ -1660,15 +1638,15 @@
1660
1638
  }, 2000);
1661
1639
  }
1662
1640
  function stopEnvelope(param, base, amount, ADSR) {
1663
- const rate = ADSR[0] === 0.0 ? 1.0 : Math.min(dura / (ADSR[0] / 1000), 1.0);
1641
+ const rate = ADSR[0] === 0.0 ? 1.0 : Math.min(dv / (ADSR[0] / 1000), 1.0);
1664
1642
  if (rate < 1.0) {
1665
1643
  param.cancelScheduledValues(start);
1666
1644
  param.setValueAtTime(base, start);
1667
1645
  param.linearRampToValueAtTime(base + amount * rate, start + ADSR[0] / 1000 * rate);
1668
1646
  param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000 * rate);
1669
1647
  }
1670
- param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dura));
1671
- param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dura) + ADSR[3] / 1000);
1648
+ param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dv));
1649
+ param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dv) + ADSR[3] / 1000);
1672
1650
  }
1673
1651
  function startEnvelope(param, base, amount, ADSR) {
1674
1652
  param.value = base;
@@ -1710,12 +1688,6 @@
1710
1688
  AnalogStick,
1711
1689
  DirectionalPad,
1712
1690
  };
1713
- const audio = {
1714
- master,
1715
- context,
1716
- synthesizer,
1717
- load
1718
- };
1719
1691
  const xnew = Object.assign(xnew$1, {
1720
1692
  basics,
1721
1693
  audio
package/dist/xnew.mjs CHANGED
@@ -214,8 +214,26 @@ class UnitPromise {
214
214
  // unit
215
215
  //----------------------------------------------------------------------------------------------------
216
216
  class Unit {
217
- constructor(parent, target, component, props) {
217
+ constructor(parent, ...args) {
218
218
  var _a;
219
+ let target;
220
+ if (args[0] instanceof HTMLElement || args[0] instanceof SVGElement) {
221
+ target = args.shift(); // an existing html element
222
+ }
223
+ else if (typeof args[0] === 'string' && args[0].match(/<((\w+)[^>]*?)\/?>/)) {
224
+ target = args.shift();
225
+ }
226
+ else if (typeof args[0] === 'string') {
227
+ const query = args.shift();
228
+ target = document.querySelector(query);
229
+ if (target === null)
230
+ throw new Error(`'${query}' can not be found.`);
231
+ }
232
+ else {
233
+ target = null;
234
+ }
235
+ const component = args.shift();
236
+ const props = args.shift();
219
237
  let baseElement;
220
238
  if (target instanceof HTMLElement || target instanceof SVGElement) {
221
239
  baseElement = target;
@@ -268,6 +286,9 @@ class Unit {
268
286
  Unit.finalize(this);
269
287
  Unit.initialize(this, anchor);
270
288
  }
289
+ append(...args) {
290
+ new Unit(this, ...args);
291
+ }
271
292
  static initialize(unit, anchor) {
272
293
  const backup = Unit.current;
273
294
  Unit.current = unit;
@@ -309,7 +330,7 @@ class Unit {
309
330
  unit._.systems.finalize.forEach((listener) => Unit.scope(Unit.snapshot(unit), listener));
310
331
  unit.off();
311
332
  Unit.suboff(unit, null);
312
- unit._.components.forEach((component) => Unit.componentUnits.delete(component, unit));
333
+ unit._.components.forEach((component) => Unit.component2units.delete(component, unit));
313
334
  if (unit._.elements.length > 0) {
314
335
  unit._.baseElement.removeChild(unit._.elements[0]);
315
336
  unit._.currentElement = unit._.baseElement;
@@ -347,7 +368,7 @@ class Unit {
347
368
  static extend(unit, component, props) {
348
369
  var _a;
349
370
  unit._.components.push(component);
350
- Unit.componentUnits.add(component, unit);
371
+ Unit.component2units.add(component, unit);
351
372
  const defines = (_a = component(unit, props)) !== null && _a !== void 0 ? _a : {};
352
373
  Object.keys(defines).forEach((key) => {
353
374
  if (unit[key] !== undefined && unit._.defines[key] === undefined) {
@@ -355,12 +376,10 @@ class Unit {
355
376
  }
356
377
  const descriptor = Object.getOwnPropertyDescriptor(defines, key);
357
378
  const wrapper = { configurable: true, enumerable: true };
358
- if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.get) {
379
+ if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.get)
359
380
  wrapper.get = Unit.wrap(unit, descriptor.get);
360
- }
361
- if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.set) {
381
+ if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.set)
362
382
  wrapper.set = Unit.wrap(unit, descriptor.set);
363
- }
364
383
  if (typeof (descriptor === null || descriptor === void 0 ? void 0 : descriptor.value) === 'function') {
365
384
  wrapper.value = Unit.wrap(unit, descriptor.value);
366
385
  }
@@ -446,7 +465,7 @@ class Unit {
446
465
  }
447
466
  static find(component) {
448
467
  var _a;
449
- return [...((_a = Unit.componentUnits.get(component)) !== null && _a !== void 0 ? _a : [])];
468
+ return [...((_a = Unit.component2units.get(component)) !== null && _a !== void 0 ? _a : [])];
450
469
  }
451
470
  on(type, listener, options) {
452
471
  if (this._.state === 'finalized')
@@ -458,7 +477,7 @@ class Unit {
458
477
  if (this._.listeners1.has(type, listener) === false) {
459
478
  const execute = Unit.wrap(Unit.current, listener);
460
479
  this._.listeners1.set(type, listener, [this.element, execute]);
461
- Unit.typeUnits.add(type, this);
480
+ Unit.type2units.add(type, this);
462
481
  if (/^[A-Za-z]/.test(type)) {
463
482
  this.element.addEventListener(type, execute, options);
464
483
  }
@@ -482,7 +501,7 @@ class Unit {
482
501
  }
483
502
  });
484
503
  if (this._.listeners1.has(type) === false) {
485
- Unit.typeUnits.delete(type, this);
504
+ Unit.type2units.delete(type, this);
486
505
  }
487
506
  });
488
507
  }
@@ -491,7 +510,7 @@ class Unit {
491
510
  if (this._.state === 'finalized')
492
511
  return;
493
512
  if (type[0] === '+') {
494
- (_a = Unit.typeUnits.get(type)) === null || _a === void 0 ? void 0 : _a.forEach((unit) => {
513
+ (_a = Unit.type2units.get(type)) === null || _a === void 0 ? void 0 : _a.forEach((unit) => {
495
514
  var _a;
496
515
  (_a = unit._.listeners1.get(type)) === null || _a === void 0 ? void 0 : _a.forEach(([_, execute]) => execute(...args));
497
516
  });
@@ -525,36 +544,17 @@ class Unit {
525
544
  });
526
545
  }
527
546
  }
528
- Unit.componentUnits = new MapSet();
547
+ Unit.component2units = new MapSet();
529
548
  //----------------------------------------------------------------------------------------------------
530
549
  // event
531
550
  //----------------------------------------------------------------------------------------------------
532
- Unit.typeUnits = new MapSet();
551
+ Unit.type2units = new MapSet();
533
552
 
534
553
  const xnew$1 = Object.assign(function (...args) {
535
554
  if (Unit.root === undefined) {
536
555
  Unit.reset();
537
556
  }
538
- let target;
539
- if (args[0] instanceof HTMLElement || args[0] instanceof SVGElement) {
540
- target = args.shift(); // an existing html element
541
- }
542
- else if (typeof args[0] === 'string') {
543
- const str = args.shift(); // a selector for an existing html element
544
- if (str.match(/<([^>]*)\/?>/)) {
545
- target = str;
546
- }
547
- else {
548
- target = document.querySelector(str);
549
- if (target == null) {
550
- throw new Error(`'${str}' can not be found.`);
551
- }
552
- }
553
- }
554
- else {
555
- target = null;
556
- }
557
- return new Unit(Unit.current, target, ...args);
557
+ return new Unit(Unit.current, ...args);
558
558
  }, {
559
559
  /**
560
560
  * Creates a nested HTML/SVG element within the current component
@@ -727,27 +727,6 @@ const xnew$1 = Object.assign(function (...args) {
727
727
  throw new Error('xnew.find(component: Function): [component] is invalid.');
728
728
  }
729
729
  },
730
- /**
731
- * Appends new components to existing component(s) in the tree
732
- * @param anchor - Component function or Unit instance to append to
733
- * @param args - Arguments to pass to xnew for creating child components
734
- * @throws Error if anchor parameter is invalid
735
- * @example
736
- * xnew.append(MyContainer, ChildComponent, { prop: 'value' })
737
- * xnew.append(unitInstance, AnotherComponent)
738
- */
739
- append(anchor, ...args) {
740
- if (typeof anchor === 'function') {
741
- const units = Unit.find(anchor);
742
- Unit.scope(Unit.snapshot(units[0]), xnew$1, ...args);
743
- }
744
- else if (anchor instanceof Unit) {
745
- Unit.scope(Unit.snapshot(anchor), xnew$1, ...args);
746
- }
747
- else {
748
- throw new Error('xnew.append(anchor: Function | Unit, xnew arguments): [anchor] is invalid.');
749
- }
750
- },
751
730
  /**
752
731
  * Executes a callback once after a delay, managed by component lifecycle
753
732
  * @param callback - Function to execute after delay
@@ -757,7 +736,7 @@ const xnew$1 = Object.assign(function (...args) {
757
736
  * const timer = xnew.timeout(() => console.log('Delayed'), 1000)
758
737
  * // Cancel if needed: timer.clear()
759
738
  */
760
- timeout(callback, delay) {
739
+ timeout(callback, delay = 0) {
761
740
  const snapshot = Unit.snapshot(Unit.current);
762
741
  const unit = xnew$1((self) => {
763
742
  const timer = new Timer(() => {
@@ -826,21 +805,21 @@ const xnew$1 = Object.assign(function (...args) {
826
805
  const timer = new Timer(() => {
827
806
  Unit.scope(snapshot, callback, 1.0);
828
807
  self.finalize();
829
- }, (progress) => {
830
- if (progress < 1.0) {
808
+ }, (x) => {
809
+ if (x < 1.0) {
831
810
  if (easing === 'ease-out') {
832
- progress = Math.pow((1.0 - Math.pow((1.0 - progress), 2.0)), 0.5);
811
+ x = Math.pow((1.0 - Math.pow((1.0 - x), 2.0)), 0.5);
833
812
  }
834
813
  else if (easing === 'ease-in') {
835
- progress = Math.pow((1.0 - Math.pow((1.0 - progress), 0.5)), 2.0);
814
+ x = Math.pow((1.0 - Math.pow((1.0 - x), 0.5)), 2.0);
836
815
  }
837
816
  else if (easing === 'ease') {
838
- progress = (1.0 - Math.cos(progress * Math.PI)) / 2.0;
817
+ x = (1.0 - Math.cos(x * Math.PI)) / 2.0;
839
818
  }
840
819
  else if (easing === 'ease-in-out') {
841
- progress = (1.0 - Math.cos(progress * Math.PI)) / 2.0;
820
+ x = (1.0 - Math.cos(x * Math.PI)) / 2.0;
842
821
  }
843
- Unit.scope(snapshot, callback, progress);
822
+ Unit.scope(snapshot, callback, x);
844
823
  }
845
824
  }, interval);
846
825
  self.on('finalize', () => {
@@ -1467,29 +1446,41 @@ const context = new AudioContext();
1467
1446
  const master = context.createGain();
1468
1447
  master.gain.value = 1.0;
1469
1448
  master.connect(context.destination);
1470
-
1471
- function load(path) {
1472
- return new AudioFile(path);
1449
+ window.addEventListener('touchstart', initialize, true);
1450
+ window.addEventListener('mousedown', initialize, true);
1451
+ function initialize() {
1452
+ new Synthesizer({ oscillator: { type: 'sine' }, amp: { envelope: { amount: 0, ADSR: [0, 0, 0, 0] } } }).press(440);
1453
+ window.removeEventListener('touchstart', initialize, true);
1454
+ window.removeEventListener('mousedown', initialize, true);
1473
1455
  }
1474
- const store = new Map();
1456
+ const audio = {
1457
+ load(path) {
1458
+ return new AudioFile(path);
1459
+ },
1460
+ synthesizer(props) {
1461
+ return new Synthesizer(props);
1462
+ },
1463
+ get volume() {
1464
+ return master.gain.value;
1465
+ },
1466
+ set volume(value) {
1467
+ master.gain.value = value;
1468
+ }
1469
+ };
1470
+ //----------------------------------------------------------------------------------------------------
1471
+ // audio file
1472
+ //----------------------------------------------------------------------------------------------------
1475
1473
  class AudioFile {
1476
1474
  constructor(path) {
1477
- if (store.has(path)) {
1478
- this.buffer = store.get(path);
1479
- this.promise = Promise.resolve();
1480
- }
1481
- else {
1482
- this.promise = fetch(path)
1483
- .then((response) => response.arrayBuffer())
1484
- .then((response) => context.decodeAudioData(response))
1485
- .then((response) => {
1486
- this.buffer = response;
1487
- })
1488
- .catch(() => {
1489
- console.warn(`"${path}" could not be loaded.`);
1490
- });
1491
- store.set(path, this.buffer);
1492
- }
1475
+ this.promise = fetch(path)
1476
+ .then((response) => response.arrayBuffer())
1477
+ .then((response) => context.decodeAudioData(response))
1478
+ .then((response) => {
1479
+ this.buffer = response;
1480
+ })
1481
+ .catch(() => {
1482
+ console.warn(`"${path}" could not be loaded.`);
1483
+ });
1493
1484
  this.start = null;
1494
1485
  }
1495
1486
  // set volume(value: number) {
@@ -1528,17 +1519,6 @@ class AudioFile {
1528
1519
  }
1529
1520
  }
1530
1521
  }
1531
-
1532
- function synthesizer(props) {
1533
- return new Synthesizer(props);
1534
- }
1535
- window.addEventListener('touchstart', initialize, true);
1536
- window.addEventListener('mousedown', initialize, true);
1537
- function initialize() {
1538
- new Synthesizer({ oscillator: { type: 'sine' }, amp: { envelope: { amount: 0, ADSR: [0, 0, 0, 0] } } }).press(440);
1539
- window.removeEventListener('touchstart', initialize, true);
1540
- window.removeEventListener('mousedown', initialize, true);
1541
- }
1542
1522
  const keymap = {
1543
1523
  'A0': 27.500, 'A#0': 29.135, 'B0': 30.868,
1544
1524
  '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,
@@ -1554,23 +1534,21 @@ const notemap = {
1554
1534
  '1m': 4.000, '2n': 2.000, '4n': 1.000, '8n': 0.500, '16n': 0.250, '32n': 0.125,
1555
1535
  };
1556
1536
  class Synthesizer {
1557
- constructor(props) {
1558
- this.props = props;
1559
- }
1537
+ constructor(props) { this.props = props; }
1560
1538
  press(frequency, duration, wait) {
1561
1539
  var _a;
1562
1540
  const props = this.props;
1563
- const freq = typeof frequency === 'string' ? keymap[frequency] : frequency;
1564
- const dura = typeof duration === 'string' ? (notemap[duration] * 60 / ((_a = props.bpm) !== null && _a !== void 0 ? _a : 120)) : (typeof duration === 'number' ? (duration / 1000) : 0);
1541
+ const fv = typeof frequency === 'string' ? keymap[frequency] : frequency;
1542
+ const dv = typeof duration === 'string' ? (notemap[duration] * 60 / ((_a = props.bpm) !== null && _a !== void 0 ? _a : 120)) : (typeof duration === 'number' ? (duration / 1000) : 0);
1565
1543
  const start = context.currentTime + (wait !== null && wait !== void 0 ? wait : 0) / 1000;
1566
1544
  const nodes = {};
1567
1545
  nodes.oscillator = context.createOscillator();
1568
1546
  nodes.oscillator.type = props.oscillator.type;
1569
- nodes.oscillator.frequency.value = freq;
1547
+ nodes.oscillator.frequency.value = fv;
1570
1548
  if (props.oscillator.LFO) {
1571
1549
  nodes.oscillatorLFO = context.createOscillator();
1572
1550
  nodes.oscillatorLFODepth = context.createGain();
1573
- nodes.oscillatorLFODepth.gain.value = freq * (Math.pow(2.0, props.oscillator.LFO.amount / 12.0) - 1.0);
1551
+ nodes.oscillatorLFODepth.gain.value = fv * (Math.pow(2.0, props.oscillator.LFO.amount / 12.0) - 1.0);
1574
1552
  nodes.oscillatorLFO.type = props.oscillator.LFO.type;
1575
1553
  nodes.oscillatorLFO.frequency.value = props.oscillator.LFO.rate;
1576
1554
  nodes.oscillatorLFO.start(start);
@@ -1583,7 +1561,7 @@ class Synthesizer {
1583
1561
  nodes.target.gain.value = 1.0;
1584
1562
  nodes.amp.connect(nodes.target);
1585
1563
  nodes.target.connect(master);
1586
- if (props.filter && props.filter.type && props.filter.cutoff) {
1564
+ if (props.filter) {
1587
1565
  nodes.filter = context.createBiquadFilter();
1588
1566
  nodes.filter.type = props.filter.type;
1589
1567
  nodes.filter.frequency.value = props.filter.cutoff;
@@ -1605,22 +1583,22 @@ class Synthesizer {
1605
1583
  nodes.convolverDepth.connect(master);
1606
1584
  }
1607
1585
  if (props.oscillator.envelope) {
1608
- const amount = freq * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
1609
- startEnvelope(nodes.oscillator.frequency, freq, amount, props.oscillator.envelope.ADSR);
1586
+ const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
1587
+ startEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
1610
1588
  }
1611
1589
  if (props.amp.envelope) {
1612
1590
  startEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
1613
1591
  }
1614
- let stop = null;
1615
1592
  nodes.oscillator.start(start);
1616
- if (dura > 0) {
1593
+ if (dv > 0) {
1617
1594
  release();
1618
1595
  }
1619
1596
  else {
1620
1597
  return { release };
1621
1598
  }
1622
1599
  function release() {
1623
- const end = dura > 0 ? dura : (context.currentTime - start);
1600
+ let stop = null;
1601
+ const end = dv > 0 ? dv : (context.currentTime - start);
1624
1602
  if (props.amp.envelope) {
1625
1603
  const ADSR = props.amp.envelope.ADSR;
1626
1604
  const adsr = [ADSR[0] / 1000, ADSR[1] / 1000, ADSR[2], ADSR[3] / 1000];
@@ -1634,8 +1612,8 @@ class Synthesizer {
1634
1612
  nodes.oscillatorLFO.stop(stop);
1635
1613
  }
1636
1614
  if (props.oscillator.envelope) {
1637
- const amount = freq * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
1638
- stopEnvelope(nodes.oscillator.frequency, freq, amount, props.oscillator.envelope.ADSR);
1615
+ const amount = fv * (Math.pow(2.0, props.oscillator.envelope.amount / 12.0) - 1.0);
1616
+ stopEnvelope(nodes.oscillator.frequency, fv, amount, props.oscillator.envelope.ADSR);
1639
1617
  }
1640
1618
  if (props.amp.envelope) {
1641
1619
  stopEnvelope(nodes.amp.gain, 0.0, props.amp.envelope.amount, props.amp.envelope.ADSR);
@@ -1654,15 +1632,15 @@ class Synthesizer {
1654
1632
  }, 2000);
1655
1633
  }
1656
1634
  function stopEnvelope(param, base, amount, ADSR) {
1657
- const rate = ADSR[0] === 0.0 ? 1.0 : Math.min(dura / (ADSR[0] / 1000), 1.0);
1635
+ const rate = ADSR[0] === 0.0 ? 1.0 : Math.min(dv / (ADSR[0] / 1000), 1.0);
1658
1636
  if (rate < 1.0) {
1659
1637
  param.cancelScheduledValues(start);
1660
1638
  param.setValueAtTime(base, start);
1661
1639
  param.linearRampToValueAtTime(base + amount * rate, start + ADSR[0] / 1000 * rate);
1662
1640
  param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + (ADSR[0] + ADSR[1]) / 1000 * rate);
1663
1641
  }
1664
- param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dura));
1665
- param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dura) + ADSR[3] / 1000);
1642
+ param.linearRampToValueAtTime(base + amount * rate * ADSR[2], start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dv));
1643
+ param.linearRampToValueAtTime(base, start + Math.max((ADSR[0] + ADSR[1]) / 1000 * rate, dv) + ADSR[3] / 1000);
1666
1644
  }
1667
1645
  function startEnvelope(param, base, amount, ADSR) {
1668
1646
  param.value = base;
@@ -1704,12 +1682,6 @@ const basics = {
1704
1682
  AnalogStick,
1705
1683
  DirectionalPad,
1706
1684
  };
1707
- const audio = {
1708
- master,
1709
- context,
1710
- synthesizer,
1711
- load
1712
- };
1713
1685
  const xnew = Object.assign(xnew$1, {
1714
1686
  basics,
1715
1687
  audio
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "keywords": [
5
5
  "Component-Oriented Programming"
6
6
  ],
7
- "version": "0.1.8",
7
+ "version": "0.1.9",
8
8
  "main": "dist/xnew.js",
9
9
  "module": "dist/xnew.mjs",
10
10
  "types": "dist/xnew.d.ts",