@zcomponent/core 1.2.0-beta → 1.3.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,5 +1,4 @@
1
1
  import { StreamTrackEntity } from '../../data';
2
- import { Entity } from '../../entity';
3
2
  import { Animation } from '../animation';
4
3
  import { Keyframe } from '../keyframe';
5
4
  import { Stream, StreamState } from '../stream';
@@ -18,7 +17,7 @@ export declare class StreamTrack extends Track {
18
17
  private _lastTick?;
19
18
  private _lastLoopNumber?;
20
19
  private _lastRate;
21
- constructor(animation: Animation, _entity: Entity, _property: (string | number)[]);
20
+ constructor(animation: Animation, _entity: any, _property: (string | number)[]);
22
21
  get influencedPaths(): string[];
23
22
  get stream(): Stream | undefined;
24
23
  computePathProperty(t: number, p: string, valueBefore: any, parentWeight?: number): any;
@@ -0,0 +1,59 @@
1
+ import { PlayOptions, Stream } from "../animation";
2
+ import { Component } from "../component";
3
+ import { ContextManager } from "../context";
4
+ import { Observable } from "../observable";
5
+ export interface AudioConstructorProps {
6
+ /** @zprop
7
+ * @zvalues files *.+(mp3|wav)
8
+ */
9
+ source: string;
10
+ /**
11
+ * @zprop
12
+ * @zdefault default
13
+ */
14
+ audioLayer?: string;
15
+ /** @zprop
16
+ * @zdefault false
17
+ */
18
+ autoplay?: boolean;
19
+ }
20
+ /**
21
+ * @zcomponent
22
+ * @ztag core/audio
23
+ * @zgroup Media
24
+ * @zicon music_note
25
+ * @zstream
26
+ */
27
+ export declare class Audio extends Component<undefined, AudioConstructorProps> implements Stream {
28
+ audioContext: AudioContext;
29
+ destination: AudioNode;
30
+ audioBuffer?: AudioBuffer;
31
+ private _gain;
32
+ private _playhead;
33
+ private _session?;
34
+ /** @zprop
35
+ * @zdefault false
36
+ * @zgroup Audio
37
+ * @zgrouppriority 20
38
+ */
39
+ muted: Observable<boolean, never>;
40
+ constructor(mgr: ContextManager, props: AudioConstructorProps);
41
+ private _load;
42
+ private _updateVolume;
43
+ /**
44
+ * @zprop
45
+ * @ztype proportion
46
+ * @zdefault 1
47
+ */
48
+ volume: Observable<number, never>;
49
+ /** @zprop */
50
+ play(opts?: PlayOptions): void;
51
+ /** @zprop */
52
+ pause(): void;
53
+ /** @zprop */
54
+ stop(): void;
55
+ /** @zprop */
56
+ seek(t: number): void;
57
+ length(): number | undefined;
58
+ dispose(): never;
59
+ }
@@ -0,0 +1,96 @@
1
+ import { Component } from "../component";
2
+ import { AudioContextContext, useAudioContext } from "../contexts/audiocontextcontext";
3
+ import { isDesignTime } from "../contexts/environmentcontext";
4
+ import { registerLoadable, started } from "../contexts/loadcontext";
5
+ import { Observable } from "../observable";
6
+ /**
7
+ * @zcomponent
8
+ * @ztag core/audio
9
+ * @zgroup Media
10
+ * @zicon music_note
11
+ * @zstream
12
+ */
13
+ export class Audio extends Component {
14
+ constructor(mgr, props) {
15
+ super(mgr, props);
16
+ this._playhead = 0;
17
+ /** @zprop
18
+ * @zdefault false
19
+ * @zgroup Audio
20
+ * @zgrouppriority 20
21
+ */
22
+ this.muted = new Observable(false);
23
+ this._updateVolume = () => {
24
+ this._gain.gain.value = this.muted.value === true ? 0 : this.volume.value;
25
+ };
26
+ /**
27
+ * @zprop
28
+ * @ztype proportion
29
+ * @zdefault 1
30
+ */
31
+ this.volume = new Observable(1, this._updateVolume);
32
+ const audioContextContext = mgr.get(AudioContextContext);
33
+ this.audioContext = useAudioContext(mgr);
34
+ this._gain = this.audioContext.createGain();
35
+ this._gain.connect(audioContextContext.getLayer(props.audioLayer));
36
+ this.destination = this._gain;
37
+ registerLoadable(mgr, this._load());
38
+ if (!isDesignTime(this.contextManager) && props.autoplay)
39
+ started(mgr).then(() => this.play());
40
+ }
41
+ async _load() {
42
+ const source = this.constructorProps?.source;
43
+ if (!source)
44
+ return;
45
+ const data = await (await fetch(source)).arrayBuffer();
46
+ const audioContext = useAudioContext(this.contextManager);
47
+ this.audioBuffer = await audioContext.decodeAudioData(data);
48
+ }
49
+ /** @zprop */
50
+ play(opts) {
51
+ if (!this.audioBuffer)
52
+ return;
53
+ if (this._session)
54
+ this.stop();
55
+ if (this._playhead >= this.audioBuffer.duration)
56
+ this._playhead = 0;
57
+ const source = this.audioContext.createBufferSource();
58
+ source.buffer = this.audioBuffer;
59
+ source.playbackRate.value = opts?.speed ?? 1;
60
+ source.connect(this.destination);
61
+ const startedAt = this.audioContext.currentTime - (this._playhead / source.playbackRate.value);
62
+ source.start(0, this._playhead);
63
+ this._session = { source, startedAt };
64
+ }
65
+ /** @zprop */
66
+ pause() {
67
+ if (!this._session)
68
+ return;
69
+ this._playhead = this._session.source.playbackRate.value * (this.audioContext.currentTime - this._session.startedAt);
70
+ this._session.source.stop();
71
+ this._session.source.disconnect();
72
+ delete this._session;
73
+ }
74
+ /** @zprop */
75
+ stop() {
76
+ this.pause();
77
+ this._playhead = 0;
78
+ }
79
+ /** @zprop */
80
+ seek(t) {
81
+ let previousSession = this._session;
82
+ if (previousSession)
83
+ this.pause();
84
+ this._playhead = t / 1000;
85
+ if (previousSession)
86
+ this.play({ speed: previousSession.source.playbackRate.value });
87
+ }
88
+ length() {
89
+ return this.audioBuffer ? (this.audioBuffer.duration * 1000) : undefined;
90
+ }
91
+ dispose() {
92
+ this.stop();
93
+ this._gain.disconnect();
94
+ return super.dispose();
95
+ }
96
+ }
@@ -0,0 +1,26 @@
1
+ import { Component } from "../component";
2
+ import { ContextManager } from "../context";
3
+ import { Observable } from "../observable";
4
+ interface AudioLayerSettingsConstuctorProps {
5
+ /**
6
+ * @zprop
7
+ * @zdefault default
8
+ */
9
+ layer?: string;
10
+ }
11
+ /**
12
+ * @zcomponent
13
+ * @ztag core/audiolayersettings
14
+ * @zgroup Media
15
+ * @zicon volume_up
16
+ */
17
+ export declare class AudioLayerSettings extends Component<undefined, AudioLayerSettingsConstuctorProps> {
18
+ constructor(contextManager: ContextManager, props: AudioLayerSettingsConstuctorProps);
19
+ /**
20
+ * @zprop
21
+ * @ztype proportion
22
+ * @zdefault 1
23
+ */
24
+ volume: Observable<number, never>;
25
+ }
26
+ export {};
@@ -0,0 +1,22 @@
1
+ import { Component } from "../component";
2
+ import { AudioContextContext } from "../contexts/audiocontextcontext";
3
+ import { Observable } from "../observable";
4
+ /**
5
+ * @zcomponent
6
+ * @ztag core/audiolayersettings
7
+ * @zgroup Media
8
+ * @zicon volume_up
9
+ */
10
+ export class AudioLayerSettings extends Component {
11
+ constructor(contextManager, props) {
12
+ super(contextManager, props);
13
+ /**
14
+ * @zprop
15
+ * @ztype proportion
16
+ * @zdefault 1
17
+ */
18
+ this.volume = new Observable(1, v => {
19
+ this.contextManager.get(AudioContextContext).setVolumeForLayer(this.constructorProps?.layer, v);
20
+ });
21
+ }
22
+ }
@@ -0,0 +1,14 @@
1
+ import { ContextManager, Context } from '../context';
2
+ /** @zcontext */
3
+ export declare class AudioContextContext extends Context {
4
+ constructorProps: {};
5
+ audioContext: AudioContext;
6
+ private _layers;
7
+ layers: Map<string, AudioNode>;
8
+ constructor(contextManager: ContextManager, constructorProps: {});
9
+ private _getLayer;
10
+ getLayer(name?: string): AudioNode;
11
+ setVolumeForLayer(name: string | undefined, v: number): void;
12
+ dispose(): never;
13
+ }
14
+ export declare function useAudioContext(ctx: ContextManager): AudioContext;
@@ -0,0 +1,38 @@
1
+ import { Context } from '../context';
2
+ import { nextUserEvent } from './usereventcontext';
3
+ /** @zcontext */
4
+ export class AudioContextContext extends Context {
5
+ constructor(contextManager, constructorProps) {
6
+ super(contextManager, constructorProps);
7
+ this.constructorProps = constructorProps;
8
+ this.audioContext = new AudioContext();
9
+ this._layers = new Map();
10
+ this.layers = this._layers;
11
+ nextUserEvent(contextManager).then(() => {
12
+ this.audioContext.resume();
13
+ });
14
+ }
15
+ _getLayer(name) {
16
+ let existing = this._layers.get(name ?? 'default');
17
+ if (!existing) {
18
+ existing = new GainNode(this.audioContext);
19
+ existing.connect(this.audioContext.destination);
20
+ this._layers.set(name ?? 'default', existing);
21
+ }
22
+ return existing;
23
+ }
24
+ getLayer(name) {
25
+ return this._getLayer(name);
26
+ }
27
+ setVolumeForLayer(name, v) {
28
+ const layer = this._getLayer(name);
29
+ layer.gain.value = v;
30
+ }
31
+ dispose() {
32
+ this.audioContext.close();
33
+ return super.dispose();
34
+ }
35
+ }
36
+ export function useAudioContext(ctx) {
37
+ return ctx.get(AudioContextContext).audioContext;
38
+ }
package/lib/index.d.ts CHANGED
@@ -14,4 +14,5 @@ export * from './contexts/tagcontext';
14
14
  export * from './contexts/gamepadcontext';
15
15
  export * from './observable';
16
16
  export * from './contexts/environmentcontext';
17
+ export * from './contexts/audiocontextcontext';
17
18
  export * from './animation';
package/lib/index.js CHANGED
@@ -14,6 +14,7 @@ export * from './contexts/tagcontext';
14
14
  export * from './contexts/gamepadcontext';
15
15
  export * from './observable';
16
16
  export * from './contexts/environmentcontext';
17
+ export * from './contexts/audiocontextcontext';
17
18
  export * from './animation';
18
19
  const link = document.createElement('link');
19
20
  link.setAttribute('rel', 'stylesheet');
package/lib/types.d.ts CHANGED
@@ -108,6 +108,7 @@ export interface Prop {
108
108
  values?: Values[];
109
109
  order?: number;
110
110
  priority?: number;
111
+ optional?: boolean;
111
112
  }
112
113
  export interface DefaultChild {
113
114
  label: string;
package/lib/types.js CHANGED
@@ -105,7 +105,7 @@ export function areTypesCompatible(a, b) {
105
105
  }
106
106
  if (a.ret && !bt.ret)
107
107
  return false;
108
- if (!a.ret && !bt.ret)
108
+ if (!a.ret && bt.ret)
109
109
  return false;
110
110
  if (a.ret && bt.ret)
111
111
  return areTypesCompatible(a.ret, bt.ret);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zcomponent/core",
3
- "version": "1.2.0-beta",
3
+ "version": "1.3.0-beta",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",