@zcomponent/core 1.1.0 → 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.
- package/lib/animation/clips/clip.d.ts +3 -2
- package/lib/animation/clips/clip.js +20 -4
- package/lib/animation/index.d.ts +1 -0
- package/lib/animation/index.js +1 -0
- package/lib/animation/layerclip.d.ts +2 -0
- package/lib/animation/layerclip.js +18 -5
- package/lib/animation/stream.d.ts +1 -0
- package/lib/animation/tracks/cliptrack.d.ts +4 -0
- package/lib/animation/tracks/cliptrack.js +25 -0
- package/lib/animation/tracks/streamtrack.d.ts +39 -0
- package/lib/animation/tracks/streamtrack.js +144 -0
- package/lib/behaviors/ActivateState.d.ts +48 -0
- package/lib/behaviors/ActivateState.js +39 -0
- package/lib/behaviors/stream/PauseStream.d.ts +22 -0
- package/lib/behaviors/stream/PauseStream.js +26 -0
- package/lib/behaviors/stream/PlayStream.d.ts +45 -0
- package/lib/behaviors/stream/PlayStream.js +37 -0
- package/lib/behaviors/stream/SeekStream.d.ts +29 -0
- package/lib/behaviors/stream/SeekStream.js +33 -0
- package/lib/behaviors/stream/StopStream.d.ts +22 -0
- package/lib/behaviors/stream/StopStream.js +26 -0
- package/lib/components/Audio.d.ts +59 -0
- package/lib/components/Audio.js +96 -0
- package/lib/components/AudioLayerSettings.d.ts +26 -0
- package/lib/components/AudioLayerSettings.js +22 -0
- package/lib/contexts/audiocontextcontext.d.ts +14 -0
- package/lib/contexts/audiocontextcontext.js +38 -0
- package/lib/data/animation.d.ts +7 -3
- package/lib/data/change.js +12 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/inflate.js +13 -2
- package/lib/types.d.ts +16 -2
- package/lib/types.js +7 -1
- package/lib/zcomponent.d.ts +8 -1
- package/lib/zcomponent.js +20 -0
- package/package.json +1 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ActionBehavior, } from "../../actionbehavior";
|
|
2
|
+
import { registerBehaviorRunAtDesignTime } from "../../behavior";
|
|
3
|
+
/**
|
|
4
|
+
* @zbehavior
|
|
5
|
+
* @zicon fast_forward
|
|
6
|
+
* @zgroup Stream Actions
|
|
7
|
+
*/
|
|
8
|
+
export class SeekStream extends ActionBehavior {
|
|
9
|
+
constructor(contextManager, instance, props) {
|
|
10
|
+
super(contextManager, instance, props);
|
|
11
|
+
this.zcomponent = this.getZComponentInstance();
|
|
12
|
+
/**
|
|
13
|
+
* @zprop
|
|
14
|
+
* @zgroup Stop Settings
|
|
15
|
+
* @zgrouppriority 20
|
|
16
|
+
* @zdefault 0
|
|
17
|
+
*/
|
|
18
|
+
this.time = 0;
|
|
19
|
+
}
|
|
20
|
+
perform() {
|
|
21
|
+
if (!this.stream)
|
|
22
|
+
return;
|
|
23
|
+
const stream = this.zcomponent.resolveStreamID(this.stream);
|
|
24
|
+
if (!stream)
|
|
25
|
+
return;
|
|
26
|
+
stream.seek(this.time ?? 0);
|
|
27
|
+
}
|
|
28
|
+
/** @zprop */
|
|
29
|
+
preview() {
|
|
30
|
+
this.perform();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
registerBehaviorRunAtDesignTime(SeekStream);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ActionBehavior, ActionBehaviorConstructorProps } from "../../actionbehavior";
|
|
2
|
+
import { Component } from "../../component";
|
|
3
|
+
import { ContextManager } from "../../context";
|
|
4
|
+
/**
|
|
5
|
+
* @zbehavior
|
|
6
|
+
* @zicon stop_circle
|
|
7
|
+
* @zgroup Stream Actions
|
|
8
|
+
*/
|
|
9
|
+
export declare class StopStream extends ActionBehavior {
|
|
10
|
+
private zcomponent;
|
|
11
|
+
/**
|
|
12
|
+
* @zprop
|
|
13
|
+
* @zgroup Stop Settings
|
|
14
|
+
* @zgrouppriority 20
|
|
15
|
+
* @zvalues streamids
|
|
16
|
+
*/
|
|
17
|
+
stream: string | undefined;
|
|
18
|
+
constructor(contextManager: ContextManager, instance: Component, props: ActionBehaviorConstructorProps);
|
|
19
|
+
perform(): void;
|
|
20
|
+
/** @zprop */
|
|
21
|
+
preview(): void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ActionBehavior, } from "../../actionbehavior";
|
|
2
|
+
import { registerBehaviorRunAtDesignTime } from "../../behavior";
|
|
3
|
+
/**
|
|
4
|
+
* @zbehavior
|
|
5
|
+
* @zicon stop_circle
|
|
6
|
+
* @zgroup Stream Actions
|
|
7
|
+
*/
|
|
8
|
+
export class StopStream extends ActionBehavior {
|
|
9
|
+
constructor(contextManager, instance, props) {
|
|
10
|
+
super(contextManager, instance, props);
|
|
11
|
+
this.zcomponent = this.getZComponentInstance();
|
|
12
|
+
}
|
|
13
|
+
perform() {
|
|
14
|
+
if (!this.stream)
|
|
15
|
+
return;
|
|
16
|
+
const stream = this.zcomponent.resolveStreamID(this.stream);
|
|
17
|
+
if (!stream)
|
|
18
|
+
return;
|
|
19
|
+
stream.stop();
|
|
20
|
+
}
|
|
21
|
+
/** @zprop */
|
|
22
|
+
preview() {
|
|
23
|
+
this.perform();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
registerBehaviorRunAtDesignTime(StopStream);
|
|
@@ -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/data/animation.d.ts
CHANGED
|
@@ -119,12 +119,15 @@ export interface ClipTrackEntity {
|
|
|
119
119
|
}
|
|
120
120
|
export interface StreamTrack extends BaseTrack {
|
|
121
121
|
type: TrackType.Stream;
|
|
122
|
+
name: string;
|
|
122
123
|
data: ByID<StreamTrackEntity>;
|
|
123
124
|
weight: ByID<Keyframe>;
|
|
125
|
+
property: (string | number)[];
|
|
124
126
|
}
|
|
125
|
-
export interface StreamTrackEntity
|
|
127
|
+
export interface StreamTrackEntity {
|
|
128
|
+
id: string;
|
|
126
129
|
t0: number;
|
|
127
|
-
t1
|
|
130
|
+
t1?: number;
|
|
128
131
|
s0: number;
|
|
129
132
|
rate: number;
|
|
130
133
|
}
|
|
@@ -134,7 +137,8 @@ export interface FunctionTrack extends BaseTrack {
|
|
|
134
137
|
}
|
|
135
138
|
export type FunctionTrackEntity = EntityFunctionTrackEntity | ImportFunctionTrackEntity;
|
|
136
139
|
export interface BaseFunctionTrackEntity {
|
|
137
|
-
|
|
140
|
+
id: string;
|
|
141
|
+
t0: number;
|
|
138
142
|
type: 'entity' | 'import';
|
|
139
143
|
args: ByID<any>;
|
|
140
144
|
}
|
package/lib/data/change.js
CHANGED
|
@@ -368,9 +368,20 @@ export function forEachNodeAncestor(zcomp, id, fn) {
|
|
|
368
368
|
fn(node.parent.id);
|
|
369
369
|
forEachNodeAncestor(zcomp, node.parent.id, fn);
|
|
370
370
|
}
|
|
371
|
+
const lastNumberRegex = new RegExp(/[0-9]*$/);
|
|
371
372
|
export function getUniqueLabel(zcomp, label) {
|
|
373
|
+
lastNumberRegex.lastIndex = 0;
|
|
374
|
+
let startIndex = 1;
|
|
375
|
+
const result = lastNumberRegex.exec(label);
|
|
376
|
+
if (result && result.length === 1) {
|
|
377
|
+
const num = parseInt(result[0]);
|
|
378
|
+
if (!isNaN(num)) {
|
|
379
|
+
startIndex = num + 1;
|
|
380
|
+
label = label.substring(0, result.index);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
372
383
|
const existingLabels = zcomp.entitiesByLabel ?? {};
|
|
373
|
-
for (let i =
|
|
384
|
+
for (let i = startIndex; i < 10000; i++) {
|
|
374
385
|
const testName = i === 1 ? label : `${label} ${i.toString()}`;
|
|
375
386
|
if (!Object.prototype.hasOwnProperty.call(existingLabels, testName)) {
|
|
376
387
|
label = testName;
|
package/lib/index.d.ts
CHANGED
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/inflate.js
CHANGED
|
@@ -5,6 +5,7 @@ import { LayerClip } from './animation/layerclip';
|
|
|
5
5
|
import { Layer } from './animation/layer';
|
|
6
6
|
import { ClipTrack } from './animation/tracks/cliptrack';
|
|
7
7
|
import { Bezier } from './animation/bezier';
|
|
8
|
+
import { StreamTrack } from './animation/tracks/streamtrack';
|
|
8
9
|
export function createTrackFromData(zcomp, anim, data) {
|
|
9
10
|
switch (data.type) {
|
|
10
11
|
case Data.TrackType.Property: {
|
|
@@ -27,6 +28,15 @@ export function createTrackFromData(zcomp, anim, data) {
|
|
|
27
28
|
ret.setWeightsById(processKeyframes(data.weight, anim.curves));
|
|
28
29
|
return ret;
|
|
29
30
|
}
|
|
31
|
+
case Data.TrackType.Stream: {
|
|
32
|
+
const entity = zcomp.entityByID.get(data.entityID);
|
|
33
|
+
if (!entity)
|
|
34
|
+
return;
|
|
35
|
+
const ret = new StreamTrack(anim, entity, data.property);
|
|
36
|
+
ret.setBlocksById(data.data);
|
|
37
|
+
ret.setWeightsById(processKeyframes(data.weight, anim.curves));
|
|
38
|
+
return ret;
|
|
39
|
+
}
|
|
30
40
|
}
|
|
31
41
|
return undefined;
|
|
32
42
|
}
|
|
@@ -84,7 +94,7 @@ export function createClipFromData(zcomp, anim, data) {
|
|
|
84
94
|
if (!keyframe)
|
|
85
95
|
continue;
|
|
86
96
|
length = Math.max(length, keyframe.t0);
|
|
87
|
-
length = Math.max(length, keyframe.t1);
|
|
97
|
+
length = Math.max(length, keyframe.t1 ?? length);
|
|
88
98
|
}
|
|
89
99
|
break;
|
|
90
100
|
case Data.TrackType.Stream:
|
|
@@ -92,7 +102,8 @@ export function createClipFromData(zcomp, anim, data) {
|
|
|
92
102
|
if (!keyframe)
|
|
93
103
|
continue;
|
|
94
104
|
length = Math.max(length, keyframe.t0);
|
|
95
|
-
|
|
105
|
+
if (keyframe.t1)
|
|
106
|
+
length = Math.max(length, keyframe.t1);
|
|
96
107
|
}
|
|
97
108
|
break;
|
|
98
109
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -71,10 +71,15 @@ export type Type = StringPrimitiveType | NumberPrimitiveType | BooleanPrimitiveT
|
|
|
71
71
|
export declare enum TypeHint {
|
|
72
72
|
'proportion' = "proportion",
|
|
73
73
|
'color-norm-rgb' = "color-norm-rgb",
|
|
74
|
+
'color-norm-rgba' = "color-norm-rgba",
|
|
74
75
|
'color-unnorm-rgb' = "color-unnorm-rgb",
|
|
76
|
+
'color-unnorm-rgba' = "color-unnorm-rgba",
|
|
75
77
|
'color-hex' = "color-hex",
|
|
78
|
+
'color-hexa' = "color-hexa",
|
|
76
79
|
'color-css' = "color-css",
|
|
77
|
-
'text-multiline' = "text-multiline"
|
|
80
|
+
'text-multiline' = "text-multiline",
|
|
81
|
+
'angle-degrees' = "angle-degrees",
|
|
82
|
+
'angle-radians' = "angle-radians"
|
|
78
83
|
}
|
|
79
84
|
export declare enum ValuesType {
|
|
80
85
|
'files' = "files",
|
|
@@ -86,7 +91,8 @@ export declare enum ValuesType {
|
|
|
86
91
|
'nodeids' = "nodeids",
|
|
87
92
|
'layerclipids' = "layerclipids",
|
|
88
93
|
'easings' = "easings",
|
|
89
|
-
'layerids' = "layerids"
|
|
94
|
+
'layerids' = "layerids",
|
|
95
|
+
'streamids' = "streamids"
|
|
90
96
|
}
|
|
91
97
|
export interface Values {
|
|
92
98
|
type: ValuesType;
|
|
@@ -102,6 +108,7 @@ export interface Prop {
|
|
|
102
108
|
values?: Values[];
|
|
103
109
|
order?: number;
|
|
104
110
|
priority?: number;
|
|
111
|
+
optional?: boolean;
|
|
105
112
|
}
|
|
106
113
|
export interface DefaultChild {
|
|
107
114
|
label: string;
|
|
@@ -129,6 +136,10 @@ export interface ComponentInfo {
|
|
|
129
136
|
allowedChildren: string[];
|
|
130
137
|
allowedParents?: string[];
|
|
131
138
|
defaultChildren?: DefaultChild[];
|
|
139
|
+
streams: StreamInfo[];
|
|
140
|
+
streamsObjects: {
|
|
141
|
+
[id: string]: string;
|
|
142
|
+
};
|
|
132
143
|
}
|
|
133
144
|
export interface ValueInfo {
|
|
134
145
|
name: string;
|
|
@@ -144,6 +155,9 @@ export interface PreviewInfo {
|
|
|
144
155
|
comments?: string[];
|
|
145
156
|
filePattern: string;
|
|
146
157
|
}
|
|
158
|
+
export interface StreamInfo {
|
|
159
|
+
property: (string | number)[];
|
|
160
|
+
}
|
|
147
161
|
export interface SourceFileTypeInfo {
|
|
148
162
|
components: {
|
|
149
163
|
[id: string]: ComponentInfo;
|
package/lib/types.js
CHANGED
|
@@ -19,10 +19,15 @@ export var TypeHint;
|
|
|
19
19
|
(function (TypeHint) {
|
|
20
20
|
TypeHint["proportion"] = "proportion";
|
|
21
21
|
TypeHint["color-norm-rgb"] = "color-norm-rgb";
|
|
22
|
+
TypeHint["color-norm-rgba"] = "color-norm-rgba";
|
|
22
23
|
TypeHint["color-unnorm-rgb"] = "color-unnorm-rgb";
|
|
24
|
+
TypeHint["color-unnorm-rgba"] = "color-unnorm-rgba";
|
|
23
25
|
TypeHint["color-hex"] = "color-hex";
|
|
26
|
+
TypeHint["color-hexa"] = "color-hexa";
|
|
24
27
|
TypeHint["color-css"] = "color-css";
|
|
25
28
|
TypeHint["text-multiline"] = "text-multiline";
|
|
29
|
+
TypeHint["angle-degrees"] = "angle-degrees";
|
|
30
|
+
TypeHint["angle-radians"] = "angle-radians";
|
|
26
31
|
})(TypeHint || (TypeHint = {}));
|
|
27
32
|
export var ValuesType;
|
|
28
33
|
(function (ValuesType) {
|
|
@@ -36,6 +41,7 @@ export var ValuesType;
|
|
|
36
41
|
ValuesType["layerclipids"] = "layerclipids";
|
|
37
42
|
ValuesType["easings"] = "easings";
|
|
38
43
|
ValuesType["layerids"] = "layerids";
|
|
44
|
+
ValuesType["streamids"] = "streamids";
|
|
39
45
|
})(ValuesType || (ValuesType = {}));
|
|
40
46
|
function valuesCompatible(l, r) {
|
|
41
47
|
if (!l && !r)
|
|
@@ -99,7 +105,7 @@ export function areTypesCompatible(a, b) {
|
|
|
99
105
|
}
|
|
100
106
|
if (a.ret && !bt.ret)
|
|
101
107
|
return false;
|
|
102
|
-
if (!a.ret &&
|
|
108
|
+
if (!a.ret && bt.ret)
|
|
103
109
|
return false;
|
|
104
110
|
if (a.ret && bt.ret)
|
|
105
111
|
return areTypesCompatible(a.ret, bt.ret);
|
package/lib/zcomponent.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Animation } from './animation/index';
|
|
1
|
+
import { Animation, Stream } from './animation/index';
|
|
2
2
|
import { Component, ComponentChildren, ConstructorForComponent, ConstructorProps } from './component';
|
|
3
3
|
import { ContextManager, Context } from './context';
|
|
4
4
|
import { Entity } from './entity';
|
|
@@ -44,6 +44,12 @@ export declare class ZComponent<RootType = any> extends Component<RootType> {
|
|
|
44
44
|
constructed: Promise<void>;
|
|
45
45
|
isConstructed: boolean;
|
|
46
46
|
animation: Animation;
|
|
47
|
+
/**
|
|
48
|
+
* @zstreams layerclipids
|
|
49
|
+
*/
|
|
50
|
+
streams: {
|
|
51
|
+
[id: string]: Stream;
|
|
52
|
+
};
|
|
47
53
|
private _nodesById;
|
|
48
54
|
private _behaviorsToInitialize;
|
|
49
55
|
private _constructorPropOverridesByEntityID;
|
|
@@ -63,5 +69,6 @@ export declare class ZComponent<RootType = any> extends Component<RootType> {
|
|
|
63
69
|
private _setEntityProp;
|
|
64
70
|
private _setEntityPropPath;
|
|
65
71
|
_getNodeById(id: string): Component | undefined;
|
|
72
|
+
resolveStreamID(id: string): Stream | undefined;
|
|
66
73
|
dispose(): never;
|
|
67
74
|
}
|
package/lib/zcomponent.js
CHANGED
|
@@ -31,6 +31,10 @@ export class ZComponent extends Component {
|
|
|
31
31
|
this.constructed = new Promise(resolve => this._constructedResolve = resolve);
|
|
32
32
|
this.isConstructed = false;
|
|
33
33
|
this.animation = new Animation(false);
|
|
34
|
+
/**
|
|
35
|
+
* @zstreams layerclipids
|
|
36
|
+
*/
|
|
37
|
+
this.streams = {};
|
|
34
38
|
this._nodesById = new Map();
|
|
35
39
|
this._behaviorsToInitialize = [];
|
|
36
40
|
this._constructorPropOverridesByEntityID = new Map();
|
|
@@ -60,6 +64,10 @@ export class ZComponent extends Component {
|
|
|
60
64
|
if (this._opts.data.animation)
|
|
61
65
|
populateAnimationTracksFromData(this, this.animation, this._opts.data.animation);
|
|
62
66
|
this.animation.initialize();
|
|
67
|
+
for (const layerClip of this.animation.layerClipByID.values()) {
|
|
68
|
+
if (layerClip.id)
|
|
69
|
+
this.streams[layerClip.id] = layerClip;
|
|
70
|
+
}
|
|
63
71
|
this.isConstructed = true;
|
|
64
72
|
this._constructedResolve();
|
|
65
73
|
started(contextManager).then(() => {
|
|
@@ -372,6 +380,18 @@ export class ZComponent extends Component {
|
|
|
372
380
|
_getNodeById(id) {
|
|
373
381
|
return this._nodesById.get(id);
|
|
374
382
|
}
|
|
383
|
+
resolveStreamID(id) {
|
|
384
|
+
const parts = id.split('.');
|
|
385
|
+
let obj = this.entityByID.get(parts[0]);
|
|
386
|
+
if (!obj)
|
|
387
|
+
return undefined;
|
|
388
|
+
for (let i = 1; i < parts.length; i++) {
|
|
389
|
+
if (!obj)
|
|
390
|
+
return undefined;
|
|
391
|
+
obj = obj[parts[i]];
|
|
392
|
+
}
|
|
393
|
+
return obj;
|
|
394
|
+
}
|
|
375
395
|
dispose() {
|
|
376
396
|
this.animation.dispose();
|
|
377
397
|
for (const entity of this.entityByID.values()) {
|