@lightningjs/renderer 0.9.0 → 0.9.2
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/dist/exports/index.d.ts +3 -0
- package/dist/{src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js → exports/index.js} +4 -11
- package/dist/exports/index.js.map +1 -0
- package/dist/src/common/IAnimationController.d.ts +58 -1
- package/dist/src/common/IAnimationController.js +0 -18
- package/dist/src/common/IAnimationController.js.map +1 -1
- package/dist/src/core/CoreTextureManager.js +1 -1
- package/dist/src/core/CoreTextureManager.js.map +1 -1
- package/dist/src/core/animations/CoreAnimation.d.ts +2 -2
- package/dist/src/core/animations/CoreAnimation.js +33 -10
- package/dist/src/core/animations/CoreAnimation.js.map +1 -1
- package/dist/src/core/animations/CoreAnimationController.d.ts +8 -12
- package/dist/src/core/animations/CoreAnimationController.js +42 -46
- package/dist/src/core/animations/CoreAnimationController.js.map +1 -1
- package/dist/src/core/lib/ImageWorker.js +8 -5
- package/dist/src/core/lib/ImageWorker.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +5 -0
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
- package/dist/src/core/textures/ImageTexture.d.ts +5 -1
- package/dist/src/core/textures/ImageTexture.js +14 -6
- package/dist/src/core/textures/ImageTexture.js.map +1 -1
- package/dist/src/core/utils.js +1 -6
- package/dist/src/core/utils.js.map +1 -1
- package/dist/src/main-api/INode.d.ts +1 -1
- package/dist/src/main-api/Renderer.d.ts +297 -0
- package/dist/src/main-api/Renderer.js +370 -0
- package/dist/src/main-api/Renderer.js.map +1 -0
- package/dist/src/main-api/utils.d.ts +2 -0
- package/dist/src/main-api/utils.js +34 -0
- package/dist/src/main-api/utils.js.map +1 -0
- package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.d.ts +8 -4
- package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js +53 -24
- package/dist/src/render-drivers/threadx/ThreadXMainAnimationController.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +6 -0
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/{dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js → exports/index.ts} +4 -14
- package/package.json +1 -1
- package/src/common/IAnimationController.ts +60 -1
- package/src/core/CoreTextureManager.ts +1 -1
- package/src/core/animations/CoreAnimation.ts +35 -11
- package/src/core/animations/CoreAnimationController.ts +48 -53
- package/src/core/lib/ImageWorker.ts +10 -7
- package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +5 -0
- package/src/core/textures/ImageTexture.ts +19 -6
- package/src/core/utils.ts +1 -7
- package/src/main-api/INode.ts +1 -1
- package/src/render-drivers/threadx/ThreadXMainAnimationController.ts +63 -27
- package/src/render-drivers/threadx/worker/ThreadXRendererNode.ts +6 -0
- package/dist/src/core/lib/WebGlContext.d.ts +0 -414
- package/dist/src/core/lib/WebGlContext.js +0 -640
- package/dist/src/core/lib/WebGlContext.js.map +0 -1
- package/dist/src/core/scene/Scene.d.ts +0 -59
- package/dist/src/core/scene/Scene.js +0 -106
- package/dist/src/core/scene/Scene.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.d.ts +0 -8
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.d.ts +0 -19
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js +0 -84
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.d.ts +0 -8
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js +0 -40
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.d.ts +0 -2
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js +0 -41
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.d.ts +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js +0 -4
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.d.ts +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js +0 -2
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.d.ts +0 -20
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js +0 -55
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.js.map +0 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.d.ts +0 -9
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js.map +0 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/unbound-method */
|
|
1
2
|
/*
|
|
2
3
|
* If not stated otherwise in this file or this component's LICENSE file the
|
|
3
4
|
* following copyright and licenses apply:
|
|
@@ -24,50 +25,48 @@ import type {
|
|
|
24
25
|
import type { AnimationManager } from './AnimationManager.js';
|
|
25
26
|
import type { CoreAnimation } from './CoreAnimation.js';
|
|
26
27
|
import { assertTruthy } from '../../utils.js';
|
|
28
|
+
import { EventEmitter } from '../../common/EventEmitter.js';
|
|
27
29
|
|
|
28
|
-
export class CoreAnimationController
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
startedResolve: ((scope?: any) => void) | null = null;
|
|
34
|
-
|
|
35
|
-
stoppedPromise: Promise<void> | null = null;
|
|
30
|
+
export class CoreAnimationController
|
|
31
|
+
extends EventEmitter
|
|
32
|
+
implements IAnimationController
|
|
33
|
+
{
|
|
34
|
+
stoppedPromise: Promise<void>;
|
|
36
35
|
/**
|
|
37
36
|
* If this is null, then the animation is in a finished / stopped state.
|
|
38
37
|
*/
|
|
39
38
|
stoppedResolve: (() => void) | null = null;
|
|
39
|
+
state: AnimationControllerState;
|
|
40
40
|
|
|
41
41
|
constructor(
|
|
42
42
|
private manager: AnimationManager,
|
|
43
43
|
private animation: CoreAnimation,
|
|
44
44
|
) {
|
|
45
|
+
super();
|
|
45
46
|
this.state = 'stopped';
|
|
46
|
-
|
|
47
|
+
// Initial stopped promise is resolved (since the animation is stopped)
|
|
48
|
+
this.stoppedPromise = Promise.resolve();
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
// Bind event handlers
|
|
51
|
+
this.onAnimating = this.onAnimating.bind(this);
|
|
52
|
+
this.onFinished = this.onFinished.bind(this);
|
|
53
|
+
}
|
|
49
54
|
|
|
50
55
|
start(): IAnimationController {
|
|
51
|
-
this.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
this.animation.once('finished', this.finished.bind(this));
|
|
56
|
-
|
|
57
|
-
// prevent registering the same animation twice
|
|
58
|
-
if (!this.manager.activeAnimations.has(this.animation)) {
|
|
59
|
-
this.manager.registerAnimation(this.animation);
|
|
56
|
+
if (this.state !== 'running') {
|
|
57
|
+
this.makeStoppedPromise();
|
|
58
|
+
this.registerAnimation();
|
|
59
|
+
this.state = 'running';
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
this.state = 'running';
|
|
63
61
|
return this;
|
|
64
62
|
}
|
|
65
63
|
|
|
66
64
|
stop(): IAnimationController {
|
|
67
|
-
this.
|
|
65
|
+
this.unregisterAnimation();
|
|
68
66
|
if (this.stoppedResolve !== null) {
|
|
69
67
|
this.stoppedResolve();
|
|
70
68
|
this.stoppedResolve = null;
|
|
69
|
+
this.emit('stopped', this);
|
|
71
70
|
}
|
|
72
71
|
this.animation.reset();
|
|
73
72
|
this.state = 'stopped';
|
|
@@ -75,7 +74,7 @@ export class CoreAnimationController implements IAnimationController {
|
|
|
75
74
|
}
|
|
76
75
|
|
|
77
76
|
pause(): IAnimationController {
|
|
78
|
-
this.
|
|
77
|
+
this.unregisterAnimation();
|
|
79
78
|
this.state = 'paused';
|
|
80
79
|
return this;
|
|
81
80
|
}
|
|
@@ -86,26 +85,24 @@ export class CoreAnimationController implements IAnimationController {
|
|
|
86
85
|
return this;
|
|
87
86
|
}
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
this.
|
|
91
|
-
const promise = this.startedPromise;
|
|
92
|
-
assertTruthy(promise);
|
|
93
|
-
return promise;
|
|
88
|
+
waitUntilStopped(): Promise<void> {
|
|
89
|
+
return this.stoppedPromise;
|
|
94
90
|
}
|
|
95
91
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
92
|
+
private registerAnimation(): void {
|
|
93
|
+
// Hook up event listeners
|
|
94
|
+
this.animation.once('finished', this.onFinished);
|
|
95
|
+
this.animation.on('animating', this.onAnimating);
|
|
96
|
+
// Then register the animation
|
|
97
|
+
this.manager.registerAnimation(this.animation);
|
|
101
98
|
}
|
|
102
99
|
|
|
103
|
-
private
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
100
|
+
private unregisterAnimation(): void {
|
|
101
|
+
// First unregister the animation
|
|
102
|
+
this.manager.unregisterAnimation(this.animation);
|
|
103
|
+
// Then unhook event listeners
|
|
104
|
+
this.animation.off('finished', this.onFinished);
|
|
105
|
+
this.animation.off('animating', this.onAnimating);
|
|
109
106
|
}
|
|
110
107
|
|
|
111
108
|
private makeStoppedPromise(): void {
|
|
@@ -116,33 +113,31 @@ export class CoreAnimationController implements IAnimationController {
|
|
|
116
113
|
}
|
|
117
114
|
}
|
|
118
115
|
|
|
119
|
-
private
|
|
120
|
-
assertTruthy(this.startedResolve);
|
|
121
|
-
// resolve promise (and pass current this to continue to the chain)
|
|
122
|
-
this.startedResolve(this);
|
|
123
|
-
this.startedResolve = null;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
private finished(): void {
|
|
116
|
+
private onFinished(this: CoreAnimationController): void {
|
|
127
117
|
assertTruthy(this.stoppedResolve);
|
|
128
118
|
// If the animation is looping, then we need to restart it.
|
|
129
119
|
const { loop, stopMethod } = this.animation.settings;
|
|
130
120
|
|
|
131
121
|
if (stopMethod === 'reverse') {
|
|
132
122
|
this.animation.reverse();
|
|
133
|
-
this.start();
|
|
134
123
|
return;
|
|
135
124
|
}
|
|
136
125
|
|
|
137
|
-
// resolve promise
|
|
138
|
-
this.stoppedResolve();
|
|
139
|
-
this.stoppedResolve = null;
|
|
140
|
-
|
|
141
126
|
if (loop) {
|
|
142
127
|
return;
|
|
143
128
|
}
|
|
144
129
|
|
|
145
130
|
// unregister animation
|
|
146
|
-
this.
|
|
131
|
+
this.unregisterAnimation();
|
|
132
|
+
|
|
133
|
+
// resolve promise
|
|
134
|
+
this.stoppedResolve();
|
|
135
|
+
this.stoppedResolve = null;
|
|
136
|
+
this.emit('stopped', this);
|
|
137
|
+
this.state = 'stopped';
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private onAnimating(this: CoreAnimationController): void {
|
|
141
|
+
this.emit('animating', this);
|
|
147
142
|
}
|
|
148
143
|
}
|
|
@@ -119,10 +119,10 @@ export class ImageWorkerManager {
|
|
|
119
119
|
return workers;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
private getNextWorker(): Worker {
|
|
122
|
+
private getNextWorker(): Worker | undefined {
|
|
123
123
|
const worker = this.workers[this.workerIndex];
|
|
124
124
|
this.workerIndex = (this.workerIndex + 1) % this.workers.length;
|
|
125
|
-
return worker
|
|
125
|
+
return worker;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
private convertUrlToAbsolute(url: string): string {
|
|
@@ -140,11 +140,14 @@ export class ImageWorkerManager {
|
|
|
140
140
|
const absoluteSrcUrl = this.convertUrlToAbsolute(src);
|
|
141
141
|
const id = this.nextId++;
|
|
142
142
|
this.messageManager[id] = [resolve, reject];
|
|
143
|
-
this.getNextWorker()
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
143
|
+
const nextWorker = this.getNextWorker();
|
|
144
|
+
if (nextWorker) {
|
|
145
|
+
nextWorker.postMessage({
|
|
146
|
+
id,
|
|
147
|
+
src: absoluteSrcUrl,
|
|
148
|
+
premultiplyAlpha,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
148
151
|
}
|
|
149
152
|
} catch (error) {
|
|
150
153
|
reject(error);
|
|
@@ -92,6 +92,7 @@ export class WebGlCoreCtxTexture extends CoreContextTexture {
|
|
|
92
92
|
this._nativeCtxTexture = this.createNativeCtxTexture();
|
|
93
93
|
this.onLoadRequest()
|
|
94
94
|
.then(({ width, height }) => {
|
|
95
|
+
// If the texture has been freed while loading, return early.
|
|
95
96
|
if (this._state === 'freed') {
|
|
96
97
|
return;
|
|
97
98
|
}
|
|
@@ -103,6 +104,10 @@ export class WebGlCoreCtxTexture extends CoreContextTexture {
|
|
|
103
104
|
this.textureSource.setState('loaded', { width, height });
|
|
104
105
|
})
|
|
105
106
|
.catch((err) => {
|
|
107
|
+
// If the texture has been freed while loading, return early.
|
|
108
|
+
if (this._state === 'freed') {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
106
111
|
this._state = 'failed';
|
|
107
112
|
this.textureSource.setState('failed', err);
|
|
108
113
|
console.error(err);
|
|
@@ -37,7 +37,7 @@ export interface ImageTextureProps {
|
|
|
37
37
|
*
|
|
38
38
|
* @default ''
|
|
39
39
|
*/
|
|
40
|
-
src?: string | ImageData;
|
|
40
|
+
src?: string | ImageData | (() => ImageData);
|
|
41
41
|
/**
|
|
42
42
|
* Whether to premultiply the alpha channel into the color channels of the
|
|
43
43
|
* image.
|
|
@@ -50,6 +50,10 @@ export interface ImageTextureProps {
|
|
|
50
50
|
* @default true
|
|
51
51
|
*/
|
|
52
52
|
premultiplyAlpha?: boolean | null;
|
|
53
|
+
/**
|
|
54
|
+
* `ImageData` textures are not cached unless a `key` is provided
|
|
55
|
+
*/
|
|
56
|
+
key?: string | null;
|
|
53
57
|
}
|
|
54
58
|
|
|
55
59
|
/**
|
|
@@ -85,9 +89,16 @@ export class ImageTexture extends Texture {
|
|
|
85
89
|
data: null,
|
|
86
90
|
};
|
|
87
91
|
}
|
|
88
|
-
|
|
92
|
+
|
|
93
|
+
if (typeof src !== 'string') {
|
|
94
|
+
if (src instanceof ImageData) {
|
|
95
|
+
return {
|
|
96
|
+
data: src,
|
|
97
|
+
premultiplyAlpha,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
89
100
|
return {
|
|
90
|
-
data: src,
|
|
101
|
+
data: src(),
|
|
91
102
|
premultiplyAlpha,
|
|
92
103
|
};
|
|
93
104
|
}
|
|
@@ -137,11 +148,12 @@ export class ImageTexture extends Texture {
|
|
|
137
148
|
|
|
138
149
|
static override makeCacheKey(props: ImageTextureProps): string | false {
|
|
139
150
|
const resolvedProps = ImageTexture.resolveDefaults(props);
|
|
140
|
-
//
|
|
141
|
-
|
|
151
|
+
// Only cache key-able textures; prioritise key
|
|
152
|
+
const key = resolvedProps.key || resolvedProps.src;
|
|
153
|
+
if (typeof key !== 'string') {
|
|
142
154
|
return false;
|
|
143
155
|
}
|
|
144
|
-
return `ImageTexture,${
|
|
156
|
+
return `ImageTexture,${key},${resolvedProps.premultiplyAlpha ?? 'true'}`;
|
|
145
157
|
}
|
|
146
158
|
|
|
147
159
|
static override resolveDefaults(
|
|
@@ -150,6 +162,7 @@ export class ImageTexture extends Texture {
|
|
|
150
162
|
return {
|
|
151
163
|
src: props.src ?? '',
|
|
152
164
|
premultiplyAlpha: props.premultiplyAlpha ?? true, // null,
|
|
165
|
+
key: props.key ?? null
|
|
153
166
|
};
|
|
154
167
|
}
|
|
155
168
|
|
package/src/core/utils.ts
CHANGED
|
@@ -177,7 +177,7 @@ const parseCubicBezier = (str: string) => {
|
|
|
177
177
|
export const getTimingFunction = (
|
|
178
178
|
str: string,
|
|
179
179
|
): ((time: number) => number | undefined) => {
|
|
180
|
-
if (str === '') {
|
|
180
|
+
if (str === 'linear') {
|
|
181
181
|
return defaultTiming;
|
|
182
182
|
}
|
|
183
183
|
|
|
@@ -185,12 +185,6 @@ export const getTimingFunction = (
|
|
|
185
185
|
return timingMapping[str] || defaultTiming;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
if (str === 'linear') {
|
|
189
|
-
return (time: number) => {
|
|
190
|
-
return time;
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
|
|
194
188
|
if (str === 'step-start') {
|
|
195
189
|
return () => {
|
|
196
190
|
return 1;
|
package/src/main-api/INode.ts
CHANGED
|
@@ -443,7 +443,7 @@ export interface INodeWritableProps {
|
|
|
443
443
|
* The data stored can only be of type string, number or boolean.
|
|
444
444
|
*/
|
|
445
445
|
export type CustomDataMap = {
|
|
446
|
-
[key: string]: string | number | boolean;
|
|
446
|
+
[key: string]: string | number | boolean | undefined;
|
|
447
447
|
};
|
|
448
448
|
|
|
449
449
|
export type INodeAnimatableProps = {
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
/* eslint-disable @typescript-eslint/unbound-method */
|
|
21
|
+
import { EventEmitter } from '../../common/EventEmitter.js';
|
|
21
22
|
import type {
|
|
22
23
|
AnimationControllerState,
|
|
23
24
|
IAnimationController,
|
|
@@ -25,37 +26,48 @@ import type {
|
|
|
25
26
|
import { assertTruthy } from '../../utils.js';
|
|
26
27
|
import type { ThreadXMainNode } from './ThreadXMainNode.js';
|
|
27
28
|
|
|
28
|
-
export class ThreadXMainAnimationController
|
|
29
|
-
|
|
29
|
+
export class ThreadXMainAnimationController
|
|
30
|
+
extends EventEmitter
|
|
31
|
+
implements IAnimationController
|
|
32
|
+
{
|
|
33
|
+
stoppedPromise: Promise<void>;
|
|
30
34
|
/**
|
|
31
35
|
* If this is null, then the animation is in a finished / stopped state.
|
|
32
36
|
*/
|
|
33
37
|
stoppedResolve: (() => void) | null = null;
|
|
38
|
+
state: AnimationControllerState;
|
|
34
39
|
|
|
35
40
|
constructor(private node: ThreadXMainNode, private id: number) {
|
|
36
|
-
|
|
41
|
+
super();
|
|
37
42
|
this.state = 'stopped';
|
|
38
|
-
}
|
|
39
43
|
|
|
40
|
-
|
|
44
|
+
// Initial stopped promise is resolved (since the animation is stopped)
|
|
45
|
+
this.stoppedPromise = Promise.resolve();
|
|
46
|
+
|
|
47
|
+
// Bind event handlers
|
|
48
|
+
this.onAnimating = this.onAnimating.bind(this);
|
|
49
|
+
this.onFinished = this.onFinished.bind(this);
|
|
50
|
+
}
|
|
41
51
|
|
|
42
52
|
start(): IAnimationController {
|
|
43
|
-
if (this.
|
|
53
|
+
if (this.state !== 'running') {
|
|
44
54
|
this.makeStoppedPromise();
|
|
45
|
-
this.
|
|
55
|
+
this.sendStart();
|
|
56
|
+
this.state = 'running';
|
|
46
57
|
}
|
|
47
|
-
this.state = 'running';
|
|
48
|
-
this.node.emit('startAnimation', { id: this.id });
|
|
49
58
|
return this;
|
|
50
59
|
}
|
|
51
60
|
|
|
52
61
|
stop(): IAnimationController {
|
|
53
|
-
this.
|
|
54
|
-
|
|
55
|
-
if (this.stoppedResolve !== null) {
|
|
56
|
-
this.stoppedResolve();
|
|
57
|
-
this.stoppedResolve = null;
|
|
62
|
+
if (this.state === 'stopped') {
|
|
63
|
+
return this;
|
|
58
64
|
}
|
|
65
|
+
this.sendStop();
|
|
66
|
+
// if (this.stoppedResolve !== null) {
|
|
67
|
+
// this.stoppedResolve();
|
|
68
|
+
// this.stoppedResolve = null;
|
|
69
|
+
// this.emit('stopped', this);
|
|
70
|
+
// }
|
|
59
71
|
this.state = 'stopped';
|
|
60
72
|
return this;
|
|
61
73
|
}
|
|
@@ -71,29 +83,53 @@ export class ThreadXMainAnimationController implements IAnimationController {
|
|
|
71
83
|
}
|
|
72
84
|
|
|
73
85
|
waitUntilStopped(): Promise<void> {
|
|
74
|
-
this.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
86
|
+
return this.stoppedPromise;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private sendStart(): void {
|
|
90
|
+
// Hook up event listeners
|
|
91
|
+
this.node.on('animationFinished', this.onFinished);
|
|
92
|
+
this.node.on('animationAnimating', this.onAnimating);
|
|
93
|
+
// Then register the animation
|
|
94
|
+
this.node.emit('startAnimation', { id: this.id });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private sendStop(): void {
|
|
98
|
+
// First unregister the animation
|
|
99
|
+
this.node.emit('stopAnimation', { id: this.id });
|
|
100
|
+
// Then unhook event listeners
|
|
101
|
+
this.node.off('animationFinished', this.onFinished);
|
|
102
|
+
this.node.off('animationAnimating', this.onAnimating);
|
|
78
103
|
}
|
|
79
104
|
|
|
80
|
-
private
|
|
105
|
+
private makeStoppedPromise(): void {
|
|
106
|
+
if (this.stoppedResolve === null) {
|
|
107
|
+
this.stoppedPromise = new Promise((resolve) => {
|
|
108
|
+
this.stoppedResolve = resolve;
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private onFinished(
|
|
81
114
|
target: ThreadXMainNode,
|
|
82
|
-
{ id
|
|
115
|
+
{ id }: { id: number; loop: boolean },
|
|
83
116
|
) {
|
|
84
117
|
if (id === this.id) {
|
|
85
|
-
|
|
86
|
-
this.
|
|
118
|
+
assertTruthy(this.stoppedResolve);
|
|
119
|
+
this.node.off('animationFinished', this.onFinished);
|
|
120
|
+
this.node.off('animationAnimating', this.onAnimating);
|
|
121
|
+
|
|
122
|
+
// resolve promise
|
|
123
|
+
this.stoppedResolve();
|
|
87
124
|
this.stoppedResolve = null;
|
|
125
|
+
this.emit('stopped', this);
|
|
88
126
|
this.state = 'stopped';
|
|
89
127
|
}
|
|
90
128
|
}
|
|
91
129
|
|
|
92
|
-
private
|
|
93
|
-
if (
|
|
94
|
-
this.
|
|
95
|
-
this.stoppedResolve = resolve;
|
|
96
|
-
});
|
|
130
|
+
private onAnimating(target: ThreadXMainNode, { id }: { id: number }) {
|
|
131
|
+
if (id === this.id) {
|
|
132
|
+
this.emit('animating', this);
|
|
97
133
|
}
|
|
98
134
|
}
|
|
99
135
|
}
|
|
@@ -84,6 +84,12 @@ export class ThreadXRendererNode extends SharedNode {
|
|
|
84
84
|
props as Partial<INodeAnimatableProps>,
|
|
85
85
|
settings as Partial<AnimationSettings>,
|
|
86
86
|
);
|
|
87
|
+
animation.on('animating', () => {
|
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
89
|
+
this.emit('animationAnimating', {
|
|
90
|
+
id: id as number,
|
|
91
|
+
});
|
|
92
|
+
});
|
|
87
93
|
animation.on('finished', () => {
|
|
88
94
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
89
95
|
this.emit('animationFinished', {
|