@babylonjs/addons 8.22.2 → 8.23.0

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.
Files changed (46) hide show
  1. package/lottie/index.d.ts +1 -0
  2. package/lottie/index.js +3 -0
  3. package/lottie/index.js.map +1 -0
  4. package/lottie/lottie/animationParser.d.ts +47 -0
  5. package/lottie/lottie/animationParser.js +368 -0
  6. package/lottie/lottie/animationParser.js.map +1 -0
  7. package/lottie/lottie/parsedTypes.d.ts +140 -0
  8. package/lottie/lottie/parsedTypes.js +2 -0
  9. package/lottie/lottie/parsedTypes.js.map +1 -0
  10. package/lottie/lottie/rawTypes.d.ts +152 -0
  11. package/lottie/lottie/rawTypes.js +4 -0
  12. package/lottie/lottie/rawTypes.js.map +1 -0
  13. package/lottie/lottiePlayer.d.ts +92 -0
  14. package/lottie/lottiePlayer.js +101 -0
  15. package/lottie/lottiePlayer.js.map +1 -0
  16. package/lottie/maths/bezier.d.ts +44 -0
  17. package/lottie/maths/bezier.js +53 -0
  18. package/lottie/maths/bezier.js.map +1 -0
  19. package/lottie/maths/boundingBox.d.ts +28 -0
  20. package/lottie/maths/boundingBox.js +155 -0
  21. package/lottie/maths/boundingBox.js.map +1 -0
  22. package/lottie/maths/matrix.d.ts +91 -0
  23. package/lottie/maths/matrix.js +174 -0
  24. package/lottie/maths/matrix.js.map +1 -0
  25. package/lottie/rendering/animationController.d.ts +72 -0
  26. package/lottie/rendering/animationController.js +210 -0
  27. package/lottie/rendering/animationController.js.map +1 -0
  28. package/lottie/rendering/controlNode.d.ts +32 -0
  29. package/lottie/rendering/controlNode.js +39 -0
  30. package/lottie/rendering/controlNode.js.map +1 -0
  31. package/lottie/rendering/node.d.ts +97 -0
  32. package/lottie/rendering/node.js +331 -0
  33. package/lottie/rendering/node.js.map +1 -0
  34. package/lottie/rendering/renderingManager.d.ts +45 -0
  35. package/lottie/rendering/renderingManager.js +61 -0
  36. package/lottie/rendering/renderingManager.js.map +1 -0
  37. package/lottie/sprites/spriteNode.d.ts +32 -0
  38. package/lottie/sprites/spriteNode.js +52 -0
  39. package/lottie/sprites/spriteNode.js.map +1 -0
  40. package/lottie/sprites/spritePacker.d.ts +101 -0
  41. package/lottie/sprites/spritePacker.js +237 -0
  42. package/lottie/sprites/spritePacker.js.map +1 -0
  43. package/lottie/worker.d.ts +1 -0
  44. package/lottie/worker.js +39 -0
  45. package/lottie/worker.js.map +1 -0
  46. package/package.json +2 -2
@@ -0,0 +1,210 @@
1
+ import "@babylonjs/core/Engines/Extensions/engine.alpha.js";
2
+ import "@babylonjs/core/Shaders/sprites.vertex.js";
3
+ import "@babylonjs/core/Shaders/sprites.fragment.js";
4
+ import { ThinEngine } from "@babylonjs/core/Engines/thinEngine.js";
5
+ import { Viewport } from "@babylonjs/core/Maths/math.viewport.js";
6
+ import { RenderingManager } from "./renderingManager.js";
7
+ import { AnimationParser } from "../lottie/animationParser.js";
8
+ import { ThinMatrix } from "../maths/matrix.js";
9
+ import { SpritePacker } from "../sprites/spritePacker.js";
10
+ /**
11
+ * Defines the babylon combine alpha value to prevent a large import.
12
+ */
13
+ const AlphaCombine = 2;
14
+ /**
15
+ * Class that controls the playing of lottie animations using Babylon.js
16
+ */
17
+ export class AnimationController {
18
+ /**
19
+ * Gets the canvas used for rendering the animation.
20
+ * @returns The canvas element used for rendering.
21
+ */
22
+ get view() {
23
+ return this._engine.getRenderingCanvas();
24
+ }
25
+ /**
26
+ * Gets the height of the animation in pixels.
27
+ * @returns The height of the animation in pixels.
28
+ */
29
+ get animationHeight() {
30
+ return this._animation ? this._animation.heightPx : 0;
31
+ }
32
+ /**
33
+ * Gets the width of the animation in pixels.
34
+ * @returns The width of the animation in pixels.
35
+ */
36
+ get animationWidth() {
37
+ return this._animation ? this._animation.widthPx : 0;
38
+ }
39
+ /**
40
+ * Creates a new instance of the Player.
41
+ * @param canvas The canvas element to render the animation on.
42
+ * @param animationJson The JSON string of the Lottie animation to be played.
43
+ * @param configuration The configuration for the animation player.
44
+ */
45
+ constructor(canvas, animationJson, configuration) {
46
+ this._isReady = false;
47
+ this._canvas = canvas;
48
+ this._configuration = configuration;
49
+ this._currentFrame = 0;
50
+ this._isPlaying = false;
51
+ this._animationFrameId = null;
52
+ this._lastFrameTime = 0;
53
+ this._deltaTime = 0;
54
+ this._accumulatedTime = 0;
55
+ this._framesToAdvance = 0;
56
+ this._loop = false;
57
+ this._frameDuration = 1000 / 30; // Default to 30 FPS
58
+ this._engine = new ThinEngine(this._canvas, false, // Antialias
59
+ {
60
+ alpha: true,
61
+ stencil: false,
62
+ antialias: false,
63
+ audioEngine: false,
64
+ depth: false,
65
+ // Important to allow skip frame and tiled optimizations
66
+ preserveDrawingBuffer: false,
67
+ premultipliedAlpha: false,
68
+ doNotHandleContextLost: this._configuration.supportDeviceLost,
69
+ // Usefull during debug to simulate WebGL1 devices (Safari)
70
+ // disableWebGL2Support: true,
71
+ }, false);
72
+ // Prevent parallel shader compilation to simplify the boot sequence
73
+ // Only a couple of fast compile shaders.
74
+ this._engine.getCaps().parallelShaderCompile = undefined;
75
+ this._engine.depthCullingState.depthTest = false;
76
+ this._engine.stencilState.stencilTest = false;
77
+ this._engine.setAlphaMode(AlphaCombine);
78
+ this._spritePacker = new SpritePacker(this._engine, this._configuration);
79
+ this._renderingManager = new RenderingManager(this._engine, this._spritePacker.texture, this._configuration);
80
+ this._projectionMatrix = new ThinMatrix();
81
+ this._worldMatrix = new ThinMatrix();
82
+ this._worldMatrix.identity();
83
+ this._viewport = new Viewport(0, 0, 1, 1);
84
+ // Parse the animation
85
+ const parser = new AnimationParser(this._spritePacker, animationJson, this._configuration, this._renderingManager);
86
+ this._animation = parser.animationInfo;
87
+ this._frameDuration = 1000 / this._animation.frameRate;
88
+ this.setSize(this._animation.widthPx, this._animation.heightPx);
89
+ this._cleanTree(this._animation.nodes);
90
+ this._isReady = true;
91
+ }
92
+ /**
93
+ * Plays the animation.
94
+ * @param loop If true, the animation will loop when it reaches the end.
95
+ */
96
+ playAnimation(loop = false) {
97
+ if (this._animation === undefined || !this._isReady) {
98
+ return;
99
+ }
100
+ this._currentFrame = 0;
101
+ this._accumulatedTime = 0;
102
+ this._framesToAdvance = 0;
103
+ this._isPlaying = true;
104
+ this._loop = loop;
105
+ this._lastFrameTime = 0;
106
+ // Start the render loop
107
+ this._startRenderLoop();
108
+ }
109
+ /**
110
+ * Stops the animation playback.
111
+ */
112
+ stopAnimation() {
113
+ this._accumulatedTime = 0;
114
+ this._framesToAdvance = 0;
115
+ this._isPlaying = false;
116
+ if (this._animationFrameId !== null) {
117
+ cancelAnimationFrame(this._animationFrameId);
118
+ this._animationFrameId = null;
119
+ }
120
+ }
121
+ /**
122
+ * Sets the rendering size for the engine
123
+ * @param width Width of the rendering canvas
124
+ * @param height Height of the rendering canvas
125
+ */
126
+ setSize(width, height) {
127
+ const { _engine, _projectionMatrix, _worldMatrix } = this;
128
+ const devicePixelRatio = this._configuration.devicePixelRatio;
129
+ _engine.setSize(width * devicePixelRatio, height * devicePixelRatio);
130
+ this._canvas.width = width * devicePixelRatio;
131
+ this._canvas.height = height * devicePixelRatio;
132
+ // _engine.getRenderingCanvas()!.style.width = `${width}px`;
133
+ // _engine.getRenderingCanvas()!.style.height = `${height}px`;
134
+ const world = _worldMatrix.asArray();
135
+ world[5] = -1; // we are upside down with Lottie
136
+ _projectionMatrix.orthoOffCenterLeftHanded(0, _engine.getRenderWidth() / devicePixelRatio, _engine.getRenderHeight() / devicePixelRatio, 0, -100, 100);
137
+ }
138
+ /**
139
+ * Disposes the player and releases all resources.
140
+ */
141
+ dispose() {
142
+ this.stopAnimation();
143
+ this._engine.getRenderingCanvas()?.remove();
144
+ this._engine.dispose();
145
+ this._renderingManager.dispose();
146
+ this._spritePacker.texture.dispose();
147
+ }
148
+ _cleanTree(nodes) {
149
+ // Remove non shape nodes
150
+ for (let i = 0; i < nodes.length; i++) {
151
+ const node = nodes[i];
152
+ if (node.children.length === 0 && !node.isShape) {
153
+ nodes.splice(i, 1);
154
+ i--;
155
+ continue;
156
+ }
157
+ this._cleanTree(node.children);
158
+ }
159
+ }
160
+ _startRenderLoop() {
161
+ if (!this._isPlaying) {
162
+ return;
163
+ }
164
+ this._animationFrameId = requestAnimationFrame((currentTime) => {
165
+ this._deltaTime = currentTime - this._lastFrameTime;
166
+ this._lastFrameTime = currentTime;
167
+ this._render();
168
+ this._lastFrameTime = performance.now();
169
+ // Continue the loop if still playing
170
+ if (this._isPlaying) {
171
+ this._startRenderLoop();
172
+ }
173
+ });
174
+ }
175
+ _render() {
176
+ if (!this._animation || !this._isPlaying) {
177
+ return;
178
+ }
179
+ this._engine.setViewport(this._viewport);
180
+ // Calculate the new frame based on time
181
+ this._accumulatedTime += this._deltaTime;
182
+ this._framesToAdvance = Math.floor(this._accumulatedTime / this._frameDuration);
183
+ if (this._framesToAdvance <= 0) {
184
+ return;
185
+ }
186
+ this._accumulatedTime -= this._framesToAdvance * this._frameDuration;
187
+ this._currentFrame += this._framesToAdvance;
188
+ if (this._currentFrame < this._animation.startFrame) {
189
+ return;
190
+ }
191
+ if (this._currentFrame > this._animation.endFrame) {
192
+ if (this._loop) {
193
+ this._currentFrame = (this._currentFrame % (this._animation.endFrame - this._animation.startFrame)) + this._animation.startFrame;
194
+ for (let i = 0; i < this._animation.nodes.length; i++) {
195
+ this._animation.nodes[i].reset();
196
+ }
197
+ }
198
+ else {
199
+ this._isPlaying = false;
200
+ return;
201
+ }
202
+ }
203
+ for (let i = 0; i < this._animation.nodes.length; i++) {
204
+ this._animation.nodes[i].update(this._currentFrame);
205
+ }
206
+ // Render all layers of the animation
207
+ this._renderingManager.render(this._worldMatrix, this._projectionMatrix);
208
+ }
209
+ }
210
+ //# sourceMappingURL=animationController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animationController.js","sourceRoot":"","sources":["../../../../../dev/addons/src/lottie/rendering/animationController.ts"],"names":[],"mappings":"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","sourcesContent":["import \"core/Engines/Extensions/engine.alpha\";\r\nimport \"core/Shaders/sprites.vertex\";\r\nimport \"core/Shaders/sprites.fragment\";\r\n\r\nimport { ThinEngine } from \"core/Engines/thinEngine\";\r\nimport { Viewport } from \"core/Maths/math.viewport\";\r\n\r\nimport type { Node } from \"./node\";\r\nimport { RenderingManager } from \"./renderingManager\";\r\n\r\nimport type { AnimationInfo } from \"../lottie/parsedTypes\";\r\nimport { AnimationParser } from \"../lottie/animationParser\";\r\n\r\nimport { ThinMatrix } from \"../maths/matrix\";\r\n\r\nimport { SpritePacker } from \"../sprites/spritePacker\";\r\n\r\nimport type { AnimationConfiguration } from \"../lottiePlayer\";\r\n\r\n/**\r\n * Defines the babylon combine alpha value to prevent a large import.\r\n */\r\nconst AlphaCombine = 2;\r\n\r\n/**\r\n * Class that controls the playing of lottie animations using Babylon.js\r\n */\r\nexport class AnimationController {\r\n private _isReady: boolean;\r\n\r\n private readonly _canvas: HTMLCanvasElement;\r\n private readonly _configuration: AnimationConfiguration;\r\n private readonly _engine: ThinEngine;\r\n private readonly _spritePacker: SpritePacker;\r\n\r\n private _animation?: AnimationInfo;\r\n\r\n private readonly _viewport: Viewport;\r\n private readonly _projectionMatrix: ThinMatrix;\r\n private readonly _worldMatrix: ThinMatrix;\r\n\r\n private _frameDuration: number;\r\n private _currentFrame: number;\r\n private _isPlaying: boolean;\r\n private _animationFrameId: number | null;\r\n private _lastFrameTime: number;\r\n private _deltaTime: number;\r\n private _loop: boolean;\r\n\r\n private _accumulatedTime: number;\r\n private _framesToAdvance: number;\r\n\r\n private readonly _renderingManager: RenderingManager;\r\n\r\n /**\r\n * Gets the canvas used for rendering the animation.\r\n * @returns The canvas element used for rendering.\r\n */\r\n public get view(): HTMLCanvasElement {\r\n return this._engine.getRenderingCanvas()!;\r\n }\r\n\r\n /**\r\n * Gets the height of the animation in pixels.\r\n * @returns The height of the animation in pixels.\r\n */\r\n public get animationHeight(): number {\r\n return this._animation ? this._animation.heightPx : 0;\r\n }\r\n\r\n /**\r\n * Gets the width of the animation in pixels.\r\n * @returns The width of the animation in pixels.\r\n */\r\n public get animationWidth(): number {\r\n return this._animation ? this._animation.widthPx : 0;\r\n }\r\n\r\n /**\r\n * Creates a new instance of the Player.\r\n * @param canvas The canvas element to render the animation on.\r\n * @param animationJson The JSON string of the Lottie animation to be played.\r\n * @param configuration The configuration for the animation player.\r\n */\r\n public constructor(canvas: HTMLCanvasElement, animationJson: string, configuration: AnimationConfiguration) {\r\n this._isReady = false;\r\n this._canvas = canvas;\r\n this._configuration = configuration;\r\n this._currentFrame = 0;\r\n this._isPlaying = false;\r\n this._animationFrameId = null;\r\n this._lastFrameTime = 0;\r\n this._deltaTime = 0;\r\n this._accumulatedTime = 0;\r\n this._framesToAdvance = 0;\r\n this._loop = false;\r\n this._frameDuration = 1000 / 30; // Default to 30 FPS\r\n\r\n this._engine = new ThinEngine(\r\n this._canvas,\r\n false, // Antialias\r\n {\r\n alpha: true,\r\n stencil: false,\r\n antialias: false,\r\n audioEngine: false,\r\n depth: false,\r\n // Important to allow skip frame and tiled optimizations\r\n preserveDrawingBuffer: false,\r\n premultipliedAlpha: false,\r\n doNotHandleContextLost: this._configuration.supportDeviceLost,\r\n // Usefull during debug to simulate WebGL1 devices (Safari)\r\n // disableWebGL2Support: true,\r\n },\r\n false\r\n );\r\n\r\n // Prevent parallel shader compilation to simplify the boot sequence\r\n // Only a couple of fast compile shaders.\r\n this._engine.getCaps().parallelShaderCompile = undefined;\r\n this._engine.depthCullingState.depthTest = false;\r\n this._engine.stencilState.stencilTest = false;\r\n this._engine.setAlphaMode(AlphaCombine);\r\n\r\n this._spritePacker = new SpritePacker(this._engine, this._configuration);\r\n this._renderingManager = new RenderingManager(this._engine, this._spritePacker.texture, this._configuration);\r\n\r\n this._projectionMatrix = new ThinMatrix();\r\n this._worldMatrix = new ThinMatrix();\r\n this._worldMatrix.identity();\r\n\r\n this._viewport = new Viewport(0, 0, 1, 1);\r\n\r\n // Parse the animation\r\n const parser = new AnimationParser(this._spritePacker, animationJson, this._configuration, this._renderingManager);\r\n this._animation = parser.animationInfo;\r\n this._frameDuration = 1000 / this._animation.frameRate;\r\n\r\n this.setSize(this._animation.widthPx, this._animation.heightPx);\r\n this._cleanTree(this._animation.nodes);\r\n\r\n this._isReady = true;\r\n }\r\n\r\n /**\r\n * Plays the animation.\r\n * @param loop If true, the animation will loop when it reaches the end.\r\n */\r\n public playAnimation(loop: boolean = false): void {\r\n if (this._animation === undefined || !this._isReady) {\r\n return;\r\n }\r\n\r\n this._currentFrame = 0;\r\n this._accumulatedTime = 0;\r\n this._framesToAdvance = 0;\r\n this._isPlaying = true;\r\n this._loop = loop;\r\n this._lastFrameTime = 0;\r\n\r\n // Start the render loop\r\n this._startRenderLoop();\r\n }\r\n\r\n /**\r\n * Stops the animation playback.\r\n */\r\n public stopAnimation(): void {\r\n this._accumulatedTime = 0;\r\n this._framesToAdvance = 0;\r\n this._isPlaying = false;\r\n if (this._animationFrameId !== null) {\r\n cancelAnimationFrame(this._animationFrameId);\r\n this._animationFrameId = null;\r\n }\r\n }\r\n\r\n /**\r\n * Sets the rendering size for the engine\r\n * @param width Width of the rendering canvas\r\n * @param height Height of the rendering canvas\r\n */\r\n public setSize(width: number, height: number): void {\r\n const { _engine, _projectionMatrix, _worldMatrix } = this;\r\n const devicePixelRatio = this._configuration.devicePixelRatio;\r\n\r\n _engine.setSize(width * devicePixelRatio, height * devicePixelRatio);\r\n this._canvas.width = width * devicePixelRatio;\r\n this._canvas.height = height * devicePixelRatio;\r\n // _engine.getRenderingCanvas()!.style.width = `${width}px`;\r\n // _engine.getRenderingCanvas()!.style.height = `${height}px`;\r\n\r\n const world = _worldMatrix.asArray();\r\n world[5] = -1; // we are upside down with Lottie\r\n\r\n _projectionMatrix.orthoOffCenterLeftHanded(0, _engine.getRenderWidth() / devicePixelRatio, _engine.getRenderHeight() / devicePixelRatio, 0, -100, 100);\r\n }\r\n\r\n /**\r\n * Disposes the player and releases all resources.\r\n */\r\n public dispose(): void {\r\n this.stopAnimation();\r\n this._engine.getRenderingCanvas()?.remove();\r\n this._engine.dispose();\r\n this._renderingManager.dispose();\r\n this._spritePacker.texture.dispose();\r\n }\r\n\r\n private _cleanTree(nodes: Node[]): void {\r\n // Remove non shape nodes\r\n for (let i = 0; i < nodes.length; i++) {\r\n const node = nodes[i];\r\n if (node.children.length === 0 && !node.isShape) {\r\n nodes.splice(i, 1);\r\n i--;\r\n continue;\r\n }\r\n\r\n this._cleanTree(node.children);\r\n }\r\n }\r\n\r\n private _startRenderLoop(): void {\r\n if (!this._isPlaying) {\r\n return;\r\n }\r\n\r\n this._animationFrameId = requestAnimationFrame((currentTime) => {\r\n this._deltaTime = currentTime - this._lastFrameTime;\r\n this._lastFrameTime = currentTime;\r\n\r\n this._render();\r\n this._lastFrameTime = performance.now();\r\n\r\n // Continue the loop if still playing\r\n if (this._isPlaying) {\r\n this._startRenderLoop();\r\n }\r\n });\r\n }\r\n\r\n private _render(): void {\r\n if (!this._animation || !this._isPlaying) {\r\n return;\r\n }\r\n\r\n this._engine.setViewport(this._viewport);\r\n\r\n // Calculate the new frame based on time\r\n this._accumulatedTime += this._deltaTime;\r\n this._framesToAdvance = Math.floor(this._accumulatedTime / this._frameDuration);\r\n\r\n if (this._framesToAdvance <= 0) {\r\n return;\r\n }\r\n\r\n this._accumulatedTime -= this._framesToAdvance * this._frameDuration;\r\n\r\n this._currentFrame += this._framesToAdvance;\r\n\r\n if (this._currentFrame < this._animation.startFrame) {\r\n return;\r\n }\r\n\r\n if (this._currentFrame > this._animation.endFrame) {\r\n if (this._loop) {\r\n this._currentFrame = (this._currentFrame % (this._animation.endFrame - this._animation.startFrame)) + this._animation.startFrame;\r\n for (let i = 0; i < this._animation.nodes.length; i++) {\r\n this._animation.nodes[i].reset();\r\n }\r\n } else {\r\n this._isPlaying = false;\r\n return;\r\n }\r\n }\r\n\r\n for (let i = 0; i < this._animation.nodes.length; i++) {\r\n this._animation.nodes[i].update(this._currentFrame);\r\n }\r\n\r\n // Render all layers of the animation\r\n this._renderingManager.render(this._worldMatrix, this._projectionMatrix);\r\n }\r\n}\r\n"]}
@@ -0,0 +1,32 @@
1
+ import type { ScalarProperty, Vector2Property } from "../lottie/parsedTypes.js";
2
+ import { Node } from "./node.js";
3
+ /**
4
+ * This represents a top node of the scenegraph in a Lottie animation.
5
+ * Each top level layer in Lottie is represented by a control node node.
6
+ */
7
+ export declare class ControlNode extends Node {
8
+ private _inFrame;
9
+ private _outFrame;
10
+ /**
11
+ * Constructs a new control node.
12
+ * @param id Unique identifier for the node.
13
+ * @param ignoreOpacityAnimations If there are no animations on opacity, mark this as true to ignore and optimize CPU usage.
14
+ * @param inFrame Frame at which the node becomes active.
15
+ * @param outFrame Frame at which the node becomes inactive.
16
+ * @param position Position of the node in the scene.
17
+ * @param rotation Rotation of the node in degrees.
18
+ * @param scale Scale of the node in the scene.
19
+ * @param opacity Opacity of the node, from 0 to 1.
20
+ * @param parent Parent node in the scenegraph.
21
+ */
22
+ constructor(id: string, ignoreOpacityAnimations: boolean, inFrame: number, outFrame: number, position?: Vector2Property, rotation?: ScalarProperty, scale?: Vector2Property, opacity?: ScalarProperty, parent?: Node);
23
+ /**
24
+ * Updates the node's properties based on the current frame of the animation.
25
+ * This node will only be updated if the current frame is within the in and out range.
26
+ * @param frame Frame number we are playing in the animation.
27
+ * @param isParentUpdated Whether the parent node has been updated.
28
+ * @param isReset Whether the node is being reset.
29
+ * @returns True if the node was updated, false otherwise.
30
+ */
31
+ update(frame: number, isParentUpdated?: boolean, isReset?: boolean): boolean;
32
+ }
@@ -0,0 +1,39 @@
1
+ import { Node } from "./node.js";
2
+ /**
3
+ * This represents a top node of the scenegraph in a Lottie animation.
4
+ * Each top level layer in Lottie is represented by a control node node.
5
+ */
6
+ export class ControlNode extends Node {
7
+ /**
8
+ * Constructs a new control node.
9
+ * @param id Unique identifier for the node.
10
+ * @param ignoreOpacityAnimations If there are no animations on opacity, mark this as true to ignore and optimize CPU usage.
11
+ * @param inFrame Frame at which the node becomes active.
12
+ * @param outFrame Frame at which the node becomes inactive.
13
+ * @param position Position of the node in the scene.
14
+ * @param rotation Rotation of the node in degrees.
15
+ * @param scale Scale of the node in the scene.
16
+ * @param opacity Opacity of the node, from 0 to 1.
17
+ * @param parent Parent node in the scenegraph.
18
+ */
19
+ constructor(id, ignoreOpacityAnimations, inFrame, outFrame, position, rotation, scale, opacity, parent) {
20
+ super(id, ignoreOpacityAnimations, position, rotation, scale, opacity, parent);
21
+ this._inFrame = inFrame;
22
+ this._outFrame = outFrame;
23
+ this._isControl = true;
24
+ }
25
+ /**
26
+ * Updates the node's properties based on the current frame of the animation.
27
+ * This node will only be updated if the current frame is within the in and out range.
28
+ * @param frame Frame number we are playing in the animation.
29
+ * @param isParentUpdated Whether the parent node has been updated.
30
+ * @param isReset Whether the node is being reset.
31
+ * @returns True if the node was updated, false otherwise.
32
+ */
33
+ update(frame, isParentUpdated = false, isReset = false) {
34
+ // Only update if the frame is within the in and out range
35
+ this.isVisible = frame >= this._inFrame && frame <= this._outFrame - 1;
36
+ return super.update(frame, isParentUpdated, isReset);
37
+ }
38
+ }
39
+ //# sourceMappingURL=controlNode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controlNode.js","sourceRoot":"","sources":["../../../../../dev/addons/src/lottie/rendering/controlNode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,IAAI;IAIjC;;;;;;;;;;;OAWG;IACH,YACI,EAAU,EACV,uBAAgC,EAChC,OAAe,EACf,QAAgB,EAChB,QAA0B,EAC1B,QAAyB,EACzB,KAAuB,EACvB,OAAwB,EACxB,MAAa;QAEb,KAAK,CAAC,EAAE,EAAE,uBAAuB,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/E,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAE1B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IAC3B,CAAC;IAED;;;;;;;OAOG;IACa,MAAM,CAAC,KAAa,EAAE,eAAe,GAAG,KAAK,EAAE,OAAO,GAAG,KAAK;QAC1E,0DAA0D;QAC1D,IAAI,CAAC,SAAS,GAAG,KAAK,IAAI,IAAI,CAAC,QAAQ,IAAI,KAAK,IAAI,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACvE,OAAO,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;IACzD,CAAC;CACJ","sourcesContent":["import type { ScalarProperty, Vector2Property } from \"../lottie/parsedTypes\";\r\nimport { Node } from \"./node\";\r\n\r\n/**\r\n * This represents a top node of the scenegraph in a Lottie animation.\r\n * Each top level layer in Lottie is represented by a control node node.\r\n */\r\nexport class ControlNode extends Node {\r\n private _inFrame: number;\r\n private _outFrame: number;\r\n\r\n /**\r\n * Constructs a new control node.\r\n * @param id Unique identifier for the node.\r\n * @param ignoreOpacityAnimations If there are no animations on opacity, mark this as true to ignore and optimize CPU usage.\r\n * @param inFrame Frame at which the node becomes active.\r\n * @param outFrame Frame at which the node becomes inactive.\r\n * @param position Position of the node in the scene.\r\n * @param rotation Rotation of the node in degrees.\r\n * @param scale Scale of the node in the scene.\r\n * @param opacity Opacity of the node, from 0 to 1.\r\n * @param parent Parent node in the scenegraph.\r\n */\r\n public constructor(\r\n id: string,\r\n ignoreOpacityAnimations: boolean,\r\n inFrame: number,\r\n outFrame: number,\r\n position?: Vector2Property,\r\n rotation?: ScalarProperty,\r\n scale?: Vector2Property,\r\n opacity?: ScalarProperty,\r\n parent?: Node\r\n ) {\r\n super(id, ignoreOpacityAnimations, position, rotation, scale, opacity, parent);\r\n this._inFrame = inFrame;\r\n this._outFrame = outFrame;\r\n\r\n this._isControl = true;\r\n }\r\n\r\n /**\r\n * Updates the node's properties based on the current frame of the animation.\r\n * This node will only be updated if the current frame is within the in and out range.\r\n * @param frame Frame number we are playing in the animation.\r\n * @param isParentUpdated Whether the parent node has been updated.\r\n * @param isReset Whether the node is being reset.\r\n * @returns True if the node was updated, false otherwise.\r\n */\r\n public override update(frame: number, isParentUpdated = false, isReset = false): boolean {\r\n // Only update if the frame is within the in and out range\r\n this.isVisible = frame >= this._inFrame && frame <= this._outFrame - 1;\r\n return super.update(frame, isParentUpdated, isReset);\r\n }\r\n}\r\n"]}
@@ -0,0 +1,97 @@
1
+ import type { IVector2Like } from "@babylonjs/core/Maths/math.like.js";
2
+ import type { ScalarProperty, Vector2Property } from "../lottie/parsedTypes.js";
3
+ import { ThinMatrix } from "../maths/matrix.js";
4
+ /**
5
+ * Represents a node in the scenegraph that contains the animation information from a lottie animation layer or group.
6
+ */
7
+ export declare class Node {
8
+ private readonly _id;
9
+ private readonly _ignoreOpacityAnimations;
10
+ private readonly _position;
11
+ private readonly _rotation;
12
+ private readonly _scale;
13
+ private _worldMatrix;
14
+ private _localMatrix;
15
+ private _globalMatrix;
16
+ private readonly _opacity;
17
+ private readonly _parent;
18
+ private readonly _children;
19
+ private _isVisible;
20
+ private _isAnimated;
21
+ private _animationsFunctions;
22
+ protected _isControl: boolean;
23
+ protected _isShape: boolean;
24
+ /**
25
+ * Gets the id of this node.
26
+ * @returns The unique identifier of this node.
27
+ */
28
+ get id(): string;
29
+ /**
30
+ * Gets the childer of this node.
31
+ * @returns An array of child nodes.
32
+ */
33
+ get children(): Node[];
34
+ /**
35
+ * Gets whether this node is a shape.
36
+ * @returns True if this node is a shape, false otherwise.
37
+ */
38
+ get isShape(): boolean;
39
+ /**
40
+ * Gets the world matrix of this node.
41
+ * @returns The world matrix.
42
+ */
43
+ get worldMatrix(): ThinMatrix;
44
+ /**
45
+ * Gets whether this node is animated.
46
+ * @returns True if this node has animations, false otherwise.
47
+ */
48
+ get isAnimated(): boolean;
49
+ /**
50
+ * Gets the opacity of this node.
51
+ * If the node is not visible, the opacity will be 0.
52
+ * @returns The opacity of the node, from 0 to 1.
53
+ */
54
+ get opacity(): number;
55
+ /**
56
+ * Gets the initial scale of this node.
57
+ * @returns The initial scale.
58
+ */
59
+ get startScale(): IVector2Like;
60
+ /**
61
+ * Gets the parent node of this node.
62
+ * @returns The parent node, or undefined if this is a root node.
63
+ */
64
+ get parent(): Node | undefined;
65
+ /**
66
+ * Sets the node visibility.
67
+ * @param value The new visibility value.
68
+ */
69
+ set isVisible(value: boolean);
70
+ /**
71
+ * Constructs a new node.
72
+ * @param id Unique identifier for the node.
73
+ * @param ignoreOpacityAnimations If there are no animations on opacity, mark this as true to ignore and optimize CPU usage.
74
+ * @param position Position of the node in the scene.
75
+ * @param rotation Rotation of the node in degrees.
76
+ * @param scale Scale of the node in the scene.
77
+ * @param opacity Opacity of the node, from 0 to 1.
78
+ * @param parent Parent node in the scenegraph.
79
+ */
80
+ constructor(id: string, ignoreOpacityAnimations: boolean, position?: Vector2Property, rotation?: ScalarProperty, scale?: Vector2Property, opacity?: ScalarProperty, parent?: Node);
81
+ /**
82
+ * Resets the node's properties to their initial values.
83
+ */
84
+ reset(): void;
85
+ /**
86
+ * Updates the node's properties based on the current frame of the animation.
87
+ * @param frame Frame number we are playing in the animation.
88
+ * @param isParentUpdated Whether the parent node has been updated.
89
+ * @param isReset Whether the node is being reset.
90
+ * @returns True if the node was updated, false otherwise.
91
+ */
92
+ update(frame: number, isParentUpdated?: boolean, isReset?: boolean): boolean;
93
+ private _updatePosition;
94
+ private _updateRotation;
95
+ private _updateScale;
96
+ private _updateOpacity;
97
+ }