@zcomponent/core 0.0.19 → 0.0.21
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/animation.d.ts +46 -0
- package/lib/animation/animation.js +159 -0
- package/lib/animation/animationstate.d.ts +27 -0
- package/lib/animation/animationstate.js +1 -0
- package/lib/animation/bezier.d.ts +9 -0
- package/lib/animation/bezier.js +93 -0
- package/lib/animation/clips/clip.d.ts +30 -0
- package/lib/animation/clips/clip.js +114 -0
- package/lib/animation/index.d.ts +7 -0
- package/lib/animation/index.js +7 -0
- package/lib/animation/interpolate.d.ts +2 -0
- package/lib/animation/interpolate.js +44 -0
- package/lib/animation/layer.d.ts +42 -0
- package/lib/animation/layer.js +211 -0
- package/lib/animation/layerclip.d.ts +46 -0
- package/lib/animation/layerclip.js +168 -0
- package/lib/animation/stream.d.ts +15 -0
- package/lib/animation/stream.js +6 -0
- package/lib/animation/tracks/cliptrack.d.ts +25 -0
- package/lib/animation/tracks/cliptrack.js +68 -0
- package/lib/animation/tracks/propertytrack.d.ts +32 -0
- package/lib/animation/tracks/propertytrack.js +79 -0
- package/lib/animation/tracks/track.d.ts +10 -0
- package/lib/animation/tracks/track.js +30 -0
- package/lib/animation.d.ts +86 -65
- package/lib/animation.js +83 -1
- package/lib/behaviors/PauseLayerClip.d.ts +20 -0
- package/lib/behaviors/PauseLayerClip.js +26 -0
- package/lib/behaviors/PlayLayerClip.d.ts +78 -0
- package/lib/behaviors/PlayLayerClip.js +62 -0
- package/lib/behaviors/SetLayerOff.d.ts +20 -0
- package/lib/behaviors/SetLayerOff.js +26 -0
- package/lib/data.d.ts +3 -2
- package/lib/data.js +8 -5
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/inflate.d.ts +13 -0
- package/lib/inflate.js +185 -0
- package/lib/interfaces.d.ts +1 -0
- package/lib/selectors.d.ts +5 -0
- package/lib/selectors.js +14 -0
- package/lib/types.d.ts +22 -2
- package/lib/types.js +41 -15
- package/lib/zcomponent.d.ts +11 -0
- package/lib/zcomponent.js +35 -0
- package/package.json +2 -1
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Layer } from './layer';
|
|
2
|
+
import { Observable } from '../observable';
|
|
3
|
+
import { Event } from '../event';
|
|
4
|
+
import { LayerClip } from './layerclip';
|
|
5
|
+
import { AnimationState } from './animationstate';
|
|
6
|
+
/** @internal */
|
|
7
|
+
export declare enum AnimationEvents {
|
|
8
|
+
onLayerClipActive = "onLayerClipActive",
|
|
9
|
+
onLayerClipState = "onLayerClipState"
|
|
10
|
+
}
|
|
11
|
+
export declare class Animation {
|
|
12
|
+
onTick: Event<[]>;
|
|
13
|
+
onLayerClipActive: Event<[layerClip: LayerClip]>;
|
|
14
|
+
onLayerClipState: Event<[layerClip: LayerClip]>;
|
|
15
|
+
hasLayers: Observable<boolean, never>;
|
|
16
|
+
layers: Layer[];
|
|
17
|
+
private _spotlightLayer?;
|
|
18
|
+
timeSource: (() => number) | undefined;
|
|
19
|
+
private _entityPaths;
|
|
20
|
+
private _defaultValues;
|
|
21
|
+
/** @internal */
|
|
22
|
+
_pendingEvents: {
|
|
23
|
+
evt: AnimationEvents;
|
|
24
|
+
args: any[];
|
|
25
|
+
}[];
|
|
26
|
+
constructor();
|
|
27
|
+
serializeState(): AnimationState;
|
|
28
|
+
restoreState(state: AnimationState): void;
|
|
29
|
+
dispose(): void;
|
|
30
|
+
addLayer(l: Layer): void;
|
|
31
|
+
insertLayer(l: Layer, indx: number): void;
|
|
32
|
+
removeLayer(l: Layer): void;
|
|
33
|
+
tick(): void;
|
|
34
|
+
registerEntityPath(path: string, entity: any, pathParts: (string | number)[]): void;
|
|
35
|
+
evaluateTouchedPaths(paths: string[], t?: number): void;
|
|
36
|
+
get spotlightLayer(): Layer | undefined;
|
|
37
|
+
set spotlightLayer(l: Layer | undefined);
|
|
38
|
+
clearCachedDefault(entityID: string, prop: string): void;
|
|
39
|
+
private _emitPendingEvents;
|
|
40
|
+
private _resolvePath;
|
|
41
|
+
private _evaluatePath;
|
|
42
|
+
}
|
|
43
|
+
export interface EntityPath {
|
|
44
|
+
entity: any;
|
|
45
|
+
pathParts: (string | number)[];
|
|
46
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { Observable } from '../observable';
|
|
2
|
+
import { clone } from '../data';
|
|
3
|
+
import { Event } from '../event';
|
|
4
|
+
/** @internal */
|
|
5
|
+
export var AnimationEvents;
|
|
6
|
+
(function (AnimationEvents) {
|
|
7
|
+
AnimationEvents["onLayerClipActive"] = "onLayerClipActive";
|
|
8
|
+
AnimationEvents["onLayerClipState"] = "onLayerClipState";
|
|
9
|
+
})(AnimationEvents || (AnimationEvents = {}));
|
|
10
|
+
export class Animation {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.onTick = new Event();
|
|
13
|
+
this.onLayerClipActive = new Event();
|
|
14
|
+
this.onLayerClipState = new Event();
|
|
15
|
+
this.hasLayers = new Observable(false);
|
|
16
|
+
this.layers = [];
|
|
17
|
+
this._entityPaths = new Map();
|
|
18
|
+
this._defaultValues = new Map();
|
|
19
|
+
/** @internal */
|
|
20
|
+
this._pendingEvents = [];
|
|
21
|
+
}
|
|
22
|
+
serializeState() {
|
|
23
|
+
const state = {
|
|
24
|
+
byLayer: {},
|
|
25
|
+
byLayerClip: {},
|
|
26
|
+
};
|
|
27
|
+
for (const layer of this.layers) {
|
|
28
|
+
layer._serialize(state);
|
|
29
|
+
}
|
|
30
|
+
this._spotlightLayer?._serialize(state);
|
|
31
|
+
return state;
|
|
32
|
+
}
|
|
33
|
+
restoreState(state) {
|
|
34
|
+
for (const layer of this.layers) {
|
|
35
|
+
layer._restore(state);
|
|
36
|
+
}
|
|
37
|
+
this._spotlightLayer?._restore(state);
|
|
38
|
+
}
|
|
39
|
+
dispose() {
|
|
40
|
+
this.onTick.clearListeners();
|
|
41
|
+
this.onLayerClipActive.clearListeners();
|
|
42
|
+
this.onLayerClipState.clearListeners();
|
|
43
|
+
}
|
|
44
|
+
addLayer(l) {
|
|
45
|
+
this.layers.push(l);
|
|
46
|
+
if (!this.hasLayers.value)
|
|
47
|
+
this.hasLayers.value = true;
|
|
48
|
+
}
|
|
49
|
+
insertLayer(l, indx) {
|
|
50
|
+
this.layers.splice(indx, 0, l);
|
|
51
|
+
if (!this.hasLayers.value)
|
|
52
|
+
this.hasLayers.value = true;
|
|
53
|
+
}
|
|
54
|
+
removeLayer(l) {
|
|
55
|
+
const indx = this.layers.indexOf(l);
|
|
56
|
+
if (indx >= 0)
|
|
57
|
+
this.layers.splice(indx, 1);
|
|
58
|
+
const hasLayers = this.layers.length > 0 || this._spotlightLayer !== undefined;
|
|
59
|
+
if (this.hasLayers.value !== hasLayers)
|
|
60
|
+
this.hasLayers.value = hasLayers;
|
|
61
|
+
}
|
|
62
|
+
tick() {
|
|
63
|
+
const t = this.timeSource?.() ?? performance.now();
|
|
64
|
+
const touchedPaths = [];
|
|
65
|
+
if (this._spotlightLayer) {
|
|
66
|
+
this._spotlightLayer.tick(t, touchedPaths);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
for (const layer of this.layers) {
|
|
70
|
+
layer.tick(t, touchedPaths);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
this.evaluateTouchedPaths(touchedPaths, t);
|
|
74
|
+
this.onTick.emit();
|
|
75
|
+
}
|
|
76
|
+
registerEntityPath(path, entity, pathParts) {
|
|
77
|
+
this._entityPaths.set(path, { entity, pathParts });
|
|
78
|
+
}
|
|
79
|
+
evaluateTouchedPaths(paths, t) {
|
|
80
|
+
t = t ?? this.timeSource?.() ?? performance.now();
|
|
81
|
+
const unique = new Set([...paths]);
|
|
82
|
+
for (const entry of unique.values()) {
|
|
83
|
+
this._evaluatePath(t, entry);
|
|
84
|
+
}
|
|
85
|
+
this._emitPendingEvents();
|
|
86
|
+
}
|
|
87
|
+
get spotlightLayer() {
|
|
88
|
+
return this._spotlightLayer;
|
|
89
|
+
}
|
|
90
|
+
set spotlightLayer(l) {
|
|
91
|
+
if (l === this._spotlightLayer)
|
|
92
|
+
return;
|
|
93
|
+
const touchedPaths = [];
|
|
94
|
+
if (this._spotlightLayer)
|
|
95
|
+
touchedPaths.push(...this._spotlightLayer.influencedPaths.values());
|
|
96
|
+
this._spotlightLayer = l;
|
|
97
|
+
for (const layer of this.layers) {
|
|
98
|
+
touchedPaths.push(...layer.influencedPaths.values());
|
|
99
|
+
if (l)
|
|
100
|
+
layer.pause();
|
|
101
|
+
}
|
|
102
|
+
this.evaluateTouchedPaths(touchedPaths);
|
|
103
|
+
const hasLayers = this.layers.length > 0 || this._spotlightLayer !== undefined;
|
|
104
|
+
if (this.hasLayers.value !== hasLayers)
|
|
105
|
+
this.hasLayers.value = hasLayers;
|
|
106
|
+
}
|
|
107
|
+
clearCachedDefault(entityID, prop) {
|
|
108
|
+
const prefix = entityID + '.' + prop;
|
|
109
|
+
for (const entityPath of this._defaultValues.keys()) {
|
|
110
|
+
if (entityPath.indexOf(prefix) === 0)
|
|
111
|
+
this._defaultValues.delete(entityPath);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
_emitPendingEvents() {
|
|
115
|
+
while (this._pendingEvents.length > 0) {
|
|
116
|
+
const entry = this._pendingEvents.shift();
|
|
117
|
+
if (!entry)
|
|
118
|
+
continue;
|
|
119
|
+
this[entry.evt].emit(...entry.args);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
_resolvePath(p) {
|
|
123
|
+
const path = this._entityPaths.get(p);
|
|
124
|
+
if (!path || path.pathParts.length === 0)
|
|
125
|
+
return;
|
|
126
|
+
let parent = path.entity;
|
|
127
|
+
let currentKey = path.pathParts[0];
|
|
128
|
+
if (parent[currentKey] instanceof Observable) {
|
|
129
|
+
parent = parent[currentKey];
|
|
130
|
+
currentKey = 'value';
|
|
131
|
+
}
|
|
132
|
+
for (let i = 1; i < path.pathParts.length; i++) {
|
|
133
|
+
parent = parent[currentKey];
|
|
134
|
+
currentKey = path.pathParts[i];
|
|
135
|
+
}
|
|
136
|
+
return [parent, currentKey];
|
|
137
|
+
}
|
|
138
|
+
_evaluatePath(t, p) {
|
|
139
|
+
const resolved = this._resolvePath(p);
|
|
140
|
+
if (!resolved)
|
|
141
|
+
return;
|
|
142
|
+
if (!this._defaultValues.has(p)) {
|
|
143
|
+
this._defaultValues.set(p, clone(resolved[0][resolved[1]]));
|
|
144
|
+
}
|
|
145
|
+
let val = this._defaultValues.get(p);
|
|
146
|
+
if (this._spotlightLayer) {
|
|
147
|
+
if (this._spotlightLayer.influencedPaths.has(p))
|
|
148
|
+
val = this._spotlightLayer.computePathProperty(t, p, val);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
for (const layer of this.layers) {
|
|
152
|
+
if (!layer.influencedPaths.has(p))
|
|
153
|
+
continue;
|
|
154
|
+
val = layer.computePathProperty(t, p, val);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
resolved[0][resolved[1]] = val;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { QueueEntry } from "./layer";
|
|
2
|
+
import { StreamState } from "./stream";
|
|
3
|
+
export interface AnimationState {
|
|
4
|
+
byLayer: {
|
|
5
|
+
[id: string]: LayerState;
|
|
6
|
+
};
|
|
7
|
+
byLayerClip: {
|
|
8
|
+
[id: string]: LayerClipState;
|
|
9
|
+
};
|
|
10
|
+
spotlightLayer?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface LayerState {
|
|
13
|
+
queue: LayerQueueEntryState[];
|
|
14
|
+
active?: number | null;
|
|
15
|
+
}
|
|
16
|
+
export type LayerQueueEntryState = Omit<QueueEntry, 'layerClip'> & {
|
|
17
|
+
layerClip: string | null | undefined;
|
|
18
|
+
};
|
|
19
|
+
export interface LayerClipState {
|
|
20
|
+
t0: number;
|
|
21
|
+
t1: number | null;
|
|
22
|
+
pauseTime?: number;
|
|
23
|
+
rate: number;
|
|
24
|
+
loop: boolean;
|
|
25
|
+
stopped: boolean;
|
|
26
|
+
state: StreamState;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Bezier as BezierData, predefinedCurve } from "../animation";
|
|
2
|
+
export type Easing = keyof typeof predefinedCurve | null | Bezier;
|
|
3
|
+
export declare class Bezier {
|
|
4
|
+
private _curves;
|
|
5
|
+
private _curveEvaluator;
|
|
6
|
+
constructor(_curves: BezierData[]);
|
|
7
|
+
evaluate(t: number, epsilon?: number): number;
|
|
8
|
+
}
|
|
9
|
+
export declare function computeEasing(t: number, easing?: Easing): number;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { predefinedCurve } from "../animation";
|
|
2
|
+
function BezierFactory(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) {
|
|
3
|
+
function sampleCurveX(t) {
|
|
4
|
+
return (Math.pow(1 - t, 3) * p0x +
|
|
5
|
+
3 * Math.pow(1 - t, 2) * t * p1x +
|
|
6
|
+
3 * (1 - t) * t * t * p2x +
|
|
7
|
+
t * t * t * p3x);
|
|
8
|
+
}
|
|
9
|
+
function sampleCurveY(t) {
|
|
10
|
+
return (Math.pow(1 - t, 3) * p0y +
|
|
11
|
+
3 * Math.pow(1 - t, 2) * t * p1y +
|
|
12
|
+
3 * (1 - t) * t * t * p2y +
|
|
13
|
+
t * t * t * p3y);
|
|
14
|
+
}
|
|
15
|
+
function sampleCurveDerivativeX(t) {
|
|
16
|
+
return (3 * Math.pow(1 - t, 2) * (p1x - p0x) +
|
|
17
|
+
6 * (1 - t) * t * (p2x - p1x) +
|
|
18
|
+
3 * t * t * (p3x - p2x));
|
|
19
|
+
}
|
|
20
|
+
function solveCurveX(x, epsilon) {
|
|
21
|
+
let t2 = x;
|
|
22
|
+
let x2 = 0;
|
|
23
|
+
let d2 = 0;
|
|
24
|
+
let i = 0;
|
|
25
|
+
// First try a few iterations of Newton's method -- normally very fast.
|
|
26
|
+
for (t2 = x, i = 0; i < 8; i++) {
|
|
27
|
+
x2 = sampleCurveX(t2) - x;
|
|
28
|
+
if (Math.abs(x2) < epsilon)
|
|
29
|
+
return t2;
|
|
30
|
+
d2 = sampleCurveDerivativeX(t2);
|
|
31
|
+
if (Math.abs(d2) < 1e-6)
|
|
32
|
+
break;
|
|
33
|
+
t2 = t2 - x2 / d2;
|
|
34
|
+
}
|
|
35
|
+
// Fall back to the bisection method for reliability.
|
|
36
|
+
let t0 = 0.0;
|
|
37
|
+
let t1 = 1.0;
|
|
38
|
+
t2 = x;
|
|
39
|
+
if (t2 < t0)
|
|
40
|
+
return t0;
|
|
41
|
+
if (t2 > t1)
|
|
42
|
+
return t1;
|
|
43
|
+
while (t0 < t1) {
|
|
44
|
+
x2 = sampleCurveX(t2);
|
|
45
|
+
if (Math.abs(x2 - x) < epsilon)
|
|
46
|
+
return t2;
|
|
47
|
+
if (x > x2)
|
|
48
|
+
t0 = t2;
|
|
49
|
+
else
|
|
50
|
+
t1 = t2;
|
|
51
|
+
t2 = (t1 - t0) * 0.5 + t0;
|
|
52
|
+
}
|
|
53
|
+
// Failure.
|
|
54
|
+
return t2;
|
|
55
|
+
}
|
|
56
|
+
return (x, epsilon) => {
|
|
57
|
+
return sampleCurveY(solveCurveX(x, epsilon));
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export class Bezier {
|
|
61
|
+
constructor(_curves) {
|
|
62
|
+
this._curves = _curves;
|
|
63
|
+
this._curveEvaluator = [];
|
|
64
|
+
for (const curve of _curves) {
|
|
65
|
+
this._curveEvaluator.push(BezierFactory(curve[0][0], curve[0][1], curve[1][0], curve[1][1], curve[2][0], curve[2][1], curve[3][0], curve[3][1]));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
evaluate(t, epsilon = 1e-6) {
|
|
69
|
+
for (let i = 0; i < this._curves.length; i++) {
|
|
70
|
+
if (t < this._curves[i][3][0])
|
|
71
|
+
return this._curveEvaluator[i](t, epsilon);
|
|
72
|
+
}
|
|
73
|
+
return this._curveEvaluator[this._curveEvaluator.length - 1](t, epsilon);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const bezierCache = new Map();
|
|
77
|
+
export function computeEasing(t, easing) {
|
|
78
|
+
if (easing === null || easing === undefined)
|
|
79
|
+
return 0;
|
|
80
|
+
if (easing === 'linear')
|
|
81
|
+
return t;
|
|
82
|
+
if (easing instanceof Bezier)
|
|
83
|
+
return easing.evaluate(t);
|
|
84
|
+
if (predefinedCurve[easing]) {
|
|
85
|
+
let bezier = bezierCache.get(easing);
|
|
86
|
+
if (!bezier) {
|
|
87
|
+
bezier = new Bezier(predefinedCurve[easing]);
|
|
88
|
+
bezierCache.set(easing, bezier);
|
|
89
|
+
}
|
|
90
|
+
return bezier.evaluate(t);
|
|
91
|
+
}
|
|
92
|
+
return t;
|
|
93
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as Data from '../../animation';
|
|
2
|
+
import { Observable } from '../../observable';
|
|
3
|
+
import { Animation } from '../animation';
|
|
4
|
+
import { Track } from '../tracks/track';
|
|
5
|
+
export declare class Clip {
|
|
6
|
+
animation: Animation;
|
|
7
|
+
length: number;
|
|
8
|
+
id?: string;
|
|
9
|
+
influencedPathsDirty: Observable<boolean, never>;
|
|
10
|
+
defaultFadeParameters?: Data.FadeParameters;
|
|
11
|
+
private _influencedPaths;
|
|
12
|
+
private _tracksByPath;
|
|
13
|
+
private _tracksByPathDirty;
|
|
14
|
+
private _tracks;
|
|
15
|
+
constructor(animation: Animation, length: number);
|
|
16
|
+
computePathProperty(t: number, p: string, valueBefore: any, parentWeight?: number): any;
|
|
17
|
+
addTrack(t: Track): void;
|
|
18
|
+
clearTracks(): void;
|
|
19
|
+
private _dirty;
|
|
20
|
+
get tracksByPath(): Map<string, Track[]>;
|
|
21
|
+
get influencedPaths(): string[];
|
|
22
|
+
fadePropertiesByPath(props: {
|
|
23
|
+
[id: string]: Data.FadeParameters;
|
|
24
|
+
}): void;
|
|
25
|
+
resolveClipTime(t: number, t0: number, s0: number, rate: number, t1?: number): number;
|
|
26
|
+
streamPlay(speed?: number): void;
|
|
27
|
+
streamPause(): void;
|
|
28
|
+
streamStop(): void;
|
|
29
|
+
streamSeek(t: number): void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { Observable } from '../../observable';
|
|
2
|
+
import { ClipTrack } from '../tracks/cliptrack';
|
|
3
|
+
import { PropertyTrack } from '../tracks/propertytrack';
|
|
4
|
+
export class Clip {
|
|
5
|
+
constructor(animation, length) {
|
|
6
|
+
this.animation = animation;
|
|
7
|
+
this.length = length;
|
|
8
|
+
this.influencedPathsDirty = new Observable(false);
|
|
9
|
+
this._influencedPaths = [];
|
|
10
|
+
this._tracksByPath = new Map();
|
|
11
|
+
this._tracksByPathDirty = false;
|
|
12
|
+
this._tracks = [];
|
|
13
|
+
this._dirty = (v) => {
|
|
14
|
+
if (v) {
|
|
15
|
+
this.influencedPathsDirty.value = true;
|
|
16
|
+
this._tracksByPathDirty = true;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
computePathProperty(t, p, valueBefore, parentWeight) {
|
|
21
|
+
const tracks = this.tracksByPath.get(p);
|
|
22
|
+
if (!tracks)
|
|
23
|
+
return valueBefore;
|
|
24
|
+
for (const track of tracks) {
|
|
25
|
+
valueBefore = track.computePathProperty(t, p, valueBefore, parentWeight);
|
|
26
|
+
}
|
|
27
|
+
return valueBefore;
|
|
28
|
+
}
|
|
29
|
+
addTrack(t) {
|
|
30
|
+
this._tracks.push(t);
|
|
31
|
+
t.influencedPathsDirty.addListener(this._dirty);
|
|
32
|
+
this.influencedPathsDirty.value = true;
|
|
33
|
+
this._tracksByPathDirty = true;
|
|
34
|
+
}
|
|
35
|
+
clearTracks() {
|
|
36
|
+
const existingPaths = this._influencedPaths;
|
|
37
|
+
for (const track of this._tracks) {
|
|
38
|
+
track.influencedPathsDirty.removeListener(this._dirty);
|
|
39
|
+
}
|
|
40
|
+
this._tracks = [];
|
|
41
|
+
this.influencedPathsDirty.value = true;
|
|
42
|
+
this._tracksByPathDirty = true;
|
|
43
|
+
this.animation.evaluateTouchedPaths(existingPaths);
|
|
44
|
+
}
|
|
45
|
+
get tracksByPath() {
|
|
46
|
+
if (!this._tracksByPathDirty)
|
|
47
|
+
return this._tracksByPath;
|
|
48
|
+
const ret = new Map();
|
|
49
|
+
for (const track of this._tracks) {
|
|
50
|
+
for (const p of track.influencedPaths) {
|
|
51
|
+
const arr = ret.get(p) ?? [];
|
|
52
|
+
ret.set(p, arr);
|
|
53
|
+
arr.push(track);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
this._tracksByPath = ret;
|
|
57
|
+
this._tracksByPathDirty = false;
|
|
58
|
+
return this._tracksByPath;
|
|
59
|
+
}
|
|
60
|
+
get influencedPaths() {
|
|
61
|
+
if (!this.influencedPathsDirty.value)
|
|
62
|
+
return this._influencedPaths;
|
|
63
|
+
const paths = new Set();
|
|
64
|
+
for (const track of this._tracks) {
|
|
65
|
+
track.influencedPaths.forEach(path => paths.add(path));
|
|
66
|
+
}
|
|
67
|
+
this._influencedPaths = [...paths.values()];
|
|
68
|
+
this.influencedPathsDirty.value = false;
|
|
69
|
+
return this._influencedPaths;
|
|
70
|
+
}
|
|
71
|
+
fadePropertiesByPath(props) {
|
|
72
|
+
if (this.defaultFadeParameters) {
|
|
73
|
+
// Replace any existing fade properties with our defaults
|
|
74
|
+
for (const id in props) {
|
|
75
|
+
props[id] = { ...this.defaultFadeParameters };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const track of this._tracks) {
|
|
79
|
+
if (track instanceof PropertyTrack) {
|
|
80
|
+
if (track.fadeParameters || this.defaultFadeParameters) {
|
|
81
|
+
const params = {
|
|
82
|
+
time: 0,
|
|
83
|
+
easing: null,
|
|
84
|
+
pin: 0,
|
|
85
|
+
...this.defaultFadeParameters,
|
|
86
|
+
...track.fadeParameters,
|
|
87
|
+
};
|
|
88
|
+
props[track.path] = params;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else if (track instanceof ClipTrack) {
|
|
92
|
+
track.clip.fadePropertiesByPath(props);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
resolveClipTime(t, t0, s0, rate, t1 = Infinity) {
|
|
97
|
+
if (this.length === 0)
|
|
98
|
+
return 0;
|
|
99
|
+
t = Math.min(t, t1);
|
|
100
|
+
const ct = s0 + (t - t0) * rate;
|
|
101
|
+
let bounded = ct % this.length;
|
|
102
|
+
if (bounded < 0)
|
|
103
|
+
bounded += this.length;
|
|
104
|
+
if (bounded === 0 && rate >= +0 && t === t1)
|
|
105
|
+
bounded += this.length;
|
|
106
|
+
if (bounded === 0 && rate < 0 && t === t0)
|
|
107
|
+
bounded += this.length;
|
|
108
|
+
return bounded;
|
|
109
|
+
}
|
|
110
|
+
streamPlay(speed) { }
|
|
111
|
+
streamPause() { }
|
|
112
|
+
streamStop() { }
|
|
113
|
+
streamSeek(t) { }
|
|
114
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function interpolate(a, b, prop) {
|
|
2
|
+
if (typeof a === 'number' && typeof b === 'number')
|
|
3
|
+
return interpNumber(a, b, prop);
|
|
4
|
+
if (Array.isArray(a) && Array.isArray(b))
|
|
5
|
+
return interpArray(a, b, prop);
|
|
6
|
+
return interpStep(a, b, prop);
|
|
7
|
+
}
|
|
8
|
+
function interpNumber(a, b, prop) {
|
|
9
|
+
return (1 - prop) * a + prop * b;
|
|
10
|
+
}
|
|
11
|
+
function interpStep(a, b, prop) {
|
|
12
|
+
return prop > 0 ? b : a;
|
|
13
|
+
}
|
|
14
|
+
function interpArray(a, b, prop) {
|
|
15
|
+
if (a.length !== b.length)
|
|
16
|
+
return interpStep(a, b, prop);
|
|
17
|
+
const ret = [];
|
|
18
|
+
for (let i = 0; i < a.length; i++) {
|
|
19
|
+
ret.push(interpolate(a[i], b[i], prop));
|
|
20
|
+
}
|
|
21
|
+
return ret;
|
|
22
|
+
}
|
|
23
|
+
export function addBlend(a, b, prop) {
|
|
24
|
+
if (typeof a === 'number' && typeof b === 'number')
|
|
25
|
+
return addBlendNumber(a, b, prop);
|
|
26
|
+
if (Array.isArray(a) && Array.isArray(b))
|
|
27
|
+
return addBlendArray(a, b, prop);
|
|
28
|
+
return addBlendStep(a, b, prop);
|
|
29
|
+
}
|
|
30
|
+
function addBlendNumber(a, b, prop) {
|
|
31
|
+
return a + prop * b;
|
|
32
|
+
}
|
|
33
|
+
function addBlendStep(a, b, prop) {
|
|
34
|
+
return prop >= 0.5 ? b : a;
|
|
35
|
+
}
|
|
36
|
+
function addBlendArray(a, b, prop) {
|
|
37
|
+
if (a.length !== b.length)
|
|
38
|
+
return interpStep(a, b, prop);
|
|
39
|
+
const ret = [];
|
|
40
|
+
for (let i = 0; i < a.length; i++) {
|
|
41
|
+
ret.push(addBlend(a[i], b[i], prop));
|
|
42
|
+
}
|
|
43
|
+
return ret;
|
|
44
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as Data from '../animation';
|
|
2
|
+
import { Observable } from '../observable';
|
|
3
|
+
import { Animation } from './animation';
|
|
4
|
+
import { AnimationState } from './animationstate';
|
|
5
|
+
import { LayerClip, LayerClipPlayOptions } from './layerclip';
|
|
6
|
+
export declare class Layer {
|
|
7
|
+
readonly animation: Animation;
|
|
8
|
+
id?: string;
|
|
9
|
+
influencedPathsDirty: Observable<boolean, never>;
|
|
10
|
+
private _influencedPaths;
|
|
11
|
+
private _active;
|
|
12
|
+
private _queue;
|
|
13
|
+
private _layerClips;
|
|
14
|
+
constructor(animation: Animation);
|
|
15
|
+
computePathProperty(t: number, p: string, valueBefore: any): any;
|
|
16
|
+
tick(t: number, touchedPaths: string[]): void;
|
|
17
|
+
pause(): void;
|
|
18
|
+
/** @internal */
|
|
19
|
+
_registerLayerClip(layerClip: LayerClip): void;
|
|
20
|
+
queue(layerClip: LayerClip | null, playOptions?: LayerClipPlayOptions): QueueEntry;
|
|
21
|
+
get active(): LayerClip | null | undefined;
|
|
22
|
+
set active(layerClip: LayerClip | null | undefined);
|
|
23
|
+
/** @internal */
|
|
24
|
+
_activateLayerClip(layerClip: LayerClip | null | undefined, playOptions?: LayerClipPlayOptions): void;
|
|
25
|
+
/** @internal */
|
|
26
|
+
_evaulate(): void;
|
|
27
|
+
/** @internal */
|
|
28
|
+
_serialize(state: AnimationState): void;
|
|
29
|
+
/** @internal */
|
|
30
|
+
_restore(state: AnimationState): void;
|
|
31
|
+
get influencedPaths(): Set<string>;
|
|
32
|
+
}
|
|
33
|
+
/** @internal */
|
|
34
|
+
export interface QueueEntry {
|
|
35
|
+
layerClip: LayerClip | null;
|
|
36
|
+
playOptions?: LayerClipPlayOptions;
|
|
37
|
+
fadeByPath: {
|
|
38
|
+
[id: string]: Data.FadeParameters;
|
|
39
|
+
};
|
|
40
|
+
fadeTime: number;
|
|
41
|
+
startTime?: number;
|
|
42
|
+
}
|