@zcomponent/core 1.4.1-beta → 1.5.0-beta

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,13 +1,17 @@
1
1
  import { ActionBehavior, ActionBehaviorConstructorProps } from "../actionbehavior";
2
2
  import { Component } from "../component";
3
3
  import { ContextManager } from "../context";
4
+ import { Observable } from "../observable";
4
5
  export interface PlaySoundProps extends ActionBehaviorConstructorProps {
5
- /** The URL of the file to play
6
- * @zprop
7
- * @zvalues files *.wav
8
- * @zvalues files *.mp3
9
- */
6
+ /** @zprop
7
+ * @zvalues files *.+(mp3|wav)
8
+ */
10
9
  source: string;
10
+ /**
11
+ * @zprop
12
+ * @zdefault default
13
+ */
14
+ audioLayer?: string;
11
15
  }
12
16
  /**
13
17
  * Plays a sound
@@ -17,7 +21,28 @@ export interface PlaySoundProps extends ActionBehaviorConstructorProps {
17
21
  * @zgroup Actions
18
22
  */
19
23
  export declare class PlaySound extends ActionBehavior<PlaySoundProps> {
20
- private _elm;
24
+ /** @zprop
25
+ * @zdefault false
26
+ * @zgroup Audio
27
+ * @zgrouppriority 20
28
+ */
29
+ muted: Observable<boolean>;
30
+ /**
31
+ * @zprop
32
+ * @ztype proportion
33
+ * @zgroup Audio
34
+ * @zgrouppriority 20
35
+ * @zdefault 1
36
+ */
37
+ volume: Observable<number>;
38
+ /**
39
+ * @zprop
40
+ * @zgroup Audio
41
+ * @zgrouppriority 20
42
+ * @zdefault 1
43
+ */
44
+ speed: Observable<number, never>;
45
+ private _component;
21
46
  constructor(contextManager: ContextManager, instance: Component, props: PlaySoundProps);
22
47
  perform(): void;
23
48
  /** @zprop */
@@ -1,6 +1,7 @@
1
1
  import { ActionBehavior, } from "../actionbehavior";
2
2
  import { registerBehaviorRunAtDesignTime } from "../behavior";
3
- import { registerLoadable } from "../contexts/loadcontext";
3
+ import { Audio } from "../components/Audio";
4
+ import { Observable } from "../observable";
4
5
  /**
5
6
  * Plays a sound
6
7
  *
@@ -11,28 +12,27 @@ import { registerLoadable } from "../contexts/loadcontext";
11
12
  export class PlaySound extends ActionBehavior {
12
13
  constructor(contextManager, instance, props) {
13
14
  super(contextManager, instance, props);
14
- this._elm = document.createElement('audio');
15
- registerLoadable(contextManager, new Promise((resolve, reject) => {
16
- this._elm.addEventListener('canplaythrough', () => resolve());
17
- this._elm.addEventListener('error', err => {
18
- console.error('Unable to create PlaySound', err);
19
- reject(err);
20
- });
21
- }));
22
- this._elm.src = props.source;
23
- this._elm.load();
15
+ /**
16
+ * @zprop
17
+ * @zgroup Audio
18
+ * @zgrouppriority 20
19
+ * @zdefault 1
20
+ */
21
+ this.speed = new Observable(1);
22
+ this._component = new Audio(contextManager, props);
23
+ this.muted = this._component.muted;
24
+ this.volume = this._component.volume;
24
25
  }
25
26
  perform() {
26
- this._elm.currentTime = 0;
27
- this._elm.play();
27
+ this._component.seek(0);
28
+ this._component.play({ speed: this.speed.value });
28
29
  }
29
30
  /** @zprop */
30
31
  preview() {
31
32
  this.perform();
32
33
  }
33
34
  dispose() {
34
- this._elm.pause();
35
- this._elm.src = '';
35
+ this._component.dispose();
36
36
  return super.dispose();
37
37
  }
38
38
  }
@@ -1,6 +1,7 @@
1
1
  import { PlayOptions, Stream } from "../animation";
2
2
  import { Component } from "../component";
3
3
  import { ContextManager } from "../context";
4
+ import { Event } from "../event";
4
5
  import { Observable } from "../observable";
5
6
  export interface AudioConstructorProps {
6
7
  /** @zprop
@@ -25,6 +26,10 @@ export interface AudioConstructorProps {
25
26
  * @zstream
26
27
  */
27
28
  export declare class Audio extends Component<undefined, AudioConstructorProps> implements Stream {
29
+ /** @zui */ onEnded: Event<[Audio]>;
30
+ /** @zui */ onStop: Event<[Audio]>;
31
+ /** @zui */ onPause: Event<[Audio]>;
32
+ /** @zui */ onPlay: Event<[Audio]>;
28
33
  audioContext: AudioContext;
29
34
  destination: AudioNode;
30
35
  audioBuffer?: AudioBuffer;
@@ -46,11 +51,14 @@ export declare class Audio extends Component<undefined, AudioConstructorProps> i
46
51
  /**
47
52
  * @zprop
48
53
  * @ztype proportion
54
+ * @zgroup Audio
55
+ * @zgrouppriority 20
49
56
  * @zdefault 1
50
57
  */
51
58
  volume: Observable<number, never>;
52
59
  /** @zprop */
53
60
  play(opts?: PlayOptions): void;
61
+ private _pause;
54
62
  /** @zprop */
55
63
  pause(): void;
56
64
  /** @zprop */
@@ -2,6 +2,7 @@ import { Component } from "../component";
2
2
  import { AudioContextContext, useAudioContext } from "../contexts/audiocontextcontext";
3
3
  import { isDesignTime } from "../contexts/environmentcontext";
4
4
  import { registerLoadable, started } from "../contexts/loadcontext";
5
+ import { Event } from "../event";
5
6
  import { Observable } from "../observable";
6
7
  /**
7
8
  * @zcomponent
@@ -13,6 +14,10 @@ import { Observable } from "../observable";
13
14
  export class Audio extends Component {
14
15
  constructor(mgr, props) {
15
16
  super(mgr, props);
17
+ /** @zui */ this.onEnded = new Event();
18
+ /** @zui */ this.onStop = new Event();
19
+ /** @zui */ this.onPause = new Event();
20
+ /** @zui */ this.onPlay = new Event();
16
21
  this._playhead = 0;
17
22
  this._rate = 1;
18
23
  this._updateVolume = () => {
@@ -27,6 +32,8 @@ export class Audio extends Component {
27
32
  /**
28
33
  * @zprop
29
34
  * @ztype proportion
35
+ * @zgroup Audio
36
+ * @zgrouppriority 20
30
37
  * @zdefault 1
31
38
  */
32
39
  this.volume = new Observable(1, this._updateVolume);
@@ -66,7 +73,7 @@ export class Audio extends Component {
66
73
  if (!this.audioBuffer)
67
74
  return;
68
75
  if (this._session)
69
- this.pause();
76
+ this._pause();
70
77
  this._rate = opts?.speed ?? 1;
71
78
  let resolvedPlayhead = this._playhead;
72
79
  if (this._rate >= +0) {
@@ -84,10 +91,11 @@ export class Audio extends Component {
84
91
  source.connect(this.destination);
85
92
  const startedAt = this.audioContext.currentTime - (resolvedPlayhead / source.playbackRate.value);
86
93
  source.start(0, resolvedPlayhead);
94
+ source.addEventListener("ended", () => this.onEnded.emit(this));
87
95
  this._session = { source, startedAt };
96
+ this.onPlay.emit(this);
88
97
  }
89
- /** @zprop */
90
- pause() {
98
+ _pause() {
91
99
  if (!this._session)
92
100
  return;
93
101
  this._playhead = this._session.source.playbackRate.value * (this.audioContext.currentTime - this._session.startedAt);
@@ -98,15 +106,21 @@ export class Audio extends Component {
98
106
  delete this._session;
99
107
  }
100
108
  /** @zprop */
109
+ pause() {
110
+ this._pause();
111
+ this.onPause.emit(this);
112
+ }
113
+ /** @zprop */
101
114
  stop() {
102
- this.pause();
115
+ this._pause();
103
116
  this._playhead = 0;
117
+ this.onStop.emit(this);
104
118
  }
105
119
  /** @zprop */
106
120
  seek(t) {
107
121
  let previousSession = this._session;
108
122
  if (previousSession)
109
- this.pause();
123
+ this._pause();
110
124
  this._playhead = t / 1000;
111
125
  if (previousSession)
112
126
  this.play({ speed: this._rate });
package/lib/emitter.d.ts CHANGED
@@ -3,6 +3,8 @@ export declare class Emitter<Args extends Array<any> = []> {
3
3
  private _emitting;
4
4
  private _toUnbind;
5
5
  private _needsSort;
6
+ private _next;
7
+ private _nextFn;
6
8
  clearListeners(): void;
7
9
  /**
8
10
  * Add a new handler function
@@ -14,6 +16,10 @@ export declare class Emitter<Args extends Array<any> = []> {
14
16
  * @param f - The callback function to be unbound.
15
17
  */
16
18
  removeListener(f: (...args: Args) => void): void;
19
+ /**
20
+ * Returns a promise that will be resolved the next time this object emits.
21
+ */
22
+ get next(): Promise<Args>;
17
23
  /**
18
24
  * Emit an event
19
25
  *
package/lib/emitter.js CHANGED
@@ -32,6 +32,17 @@ export class Emitter {
32
32
  this._funcs.splice(indx, 1);
33
33
  }
34
34
  }
35
+ /**
36
+ * Returns a promise that will be resolved the next time this object emits.
37
+ */
38
+ get next() {
39
+ if (!this._next) {
40
+ this._next = new Promise(resolve => {
41
+ this._nextFn = resolve;
42
+ });
43
+ }
44
+ return this._next;
45
+ }
35
46
  /**
36
47
  * Emit an event
37
48
  *
@@ -58,5 +69,16 @@ export class Emitter {
58
69
  if (this._toUnbind.size > 0) {
59
70
  this._toUnbind.forEach(fn => this.removeListener(fn));
60
71
  }
72
+ if (this._nextFn) {
73
+ const fn = this._nextFn;
74
+ delete this._next;
75
+ delete this._nextFn;
76
+ try {
77
+ fn(args);
78
+ }
79
+ catch (ex) {
80
+ console.log('Exception in event handler', ex);
81
+ }
82
+ }
61
83
  }
62
84
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zcomponent/core",
3
- "version": "1.4.1-beta",
3
+ "version": "1.5.0-beta",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",