@babylonjs/lottie-player 8.24.1

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 (75) hide show
  1. package/animationConfiguration.d.ts +80 -0
  2. package/animationConfiguration.d.ts.map +1 -0
  3. package/animationConfiguration.js +16 -0
  4. package/animationConfiguration.js.map +1 -0
  5. package/index.d.ts +4 -0
  6. package/index.d.ts.map +1 -0
  7. package/index.js +3 -0
  8. package/index.js.map +1 -0
  9. package/license.md +21 -0
  10. package/localPlayer.d.ts +38 -0
  11. package/localPlayer.d.ts.map +1 -0
  12. package/localPlayer.js +100 -0
  13. package/localPlayer.js.map +1 -0
  14. package/maths/bezier.d.ts +45 -0
  15. package/maths/bezier.d.ts.map +1 -0
  16. package/maths/bezier.js +53 -0
  17. package/maths/bezier.js.map +1 -0
  18. package/maths/boundingBox.d.ts +39 -0
  19. package/maths/boundingBox.d.ts.map +1 -0
  20. package/maths/boundingBox.js +204 -0
  21. package/maths/boundingBox.js.map +1 -0
  22. package/maths/matrix.d.ts +92 -0
  23. package/maths/matrix.d.ts.map +1 -0
  24. package/maths/matrix.js +174 -0
  25. package/maths/matrix.js.map +1 -0
  26. package/messageTypes.d.ts +88 -0
  27. package/messageTypes.d.ts.map +1 -0
  28. package/messageTypes.js +2 -0
  29. package/messageTypes.js.map +1 -0
  30. package/nodes/controlNode.d.ts +32 -0
  31. package/nodes/controlNode.d.ts.map +1 -0
  32. package/nodes/controlNode.js +38 -0
  33. package/nodes/controlNode.js.map +1 -0
  34. package/nodes/node.d.ts +121 -0
  35. package/nodes/node.d.ts.map +1 -0
  36. package/nodes/node.js +357 -0
  37. package/nodes/node.js.map +1 -0
  38. package/nodes/spriteNode.d.ts +32 -0
  39. package/nodes/spriteNode.d.ts.map +1 -0
  40. package/nodes/spriteNode.js +51 -0
  41. package/nodes/spriteNode.js.map +1 -0
  42. package/package.json +48 -0
  43. package/parsing/parsedTypes.d.ts +141 -0
  44. package/parsing/parsedTypes.d.ts.map +1 -0
  45. package/parsing/parsedTypes.js +2 -0
  46. package/parsing/parsedTypes.js.map +1 -0
  47. package/parsing/parser.d.ts +59 -0
  48. package/parsing/parser.d.ts.map +1 -0
  49. package/parsing/parser.js +500 -0
  50. package/parsing/parser.js.map +1 -0
  51. package/parsing/rawTypes.d.ts +238 -0
  52. package/parsing/rawTypes.d.ts.map +1 -0
  53. package/parsing/rawTypes.js +4 -0
  54. package/parsing/rawTypes.js.map +1 -0
  55. package/parsing/spritePacker.d.ts +122 -0
  56. package/parsing/spritePacker.d.ts.map +1 -0
  57. package/parsing/spritePacker.js +409 -0
  58. package/parsing/spritePacker.js.map +1 -0
  59. package/player.d.ts +42 -0
  60. package/player.d.ts.map +1 -0
  61. package/player.js +146 -0
  62. package/player.js.map +1 -0
  63. package/readme.md +44 -0
  64. package/rendering/animationController.d.ts +93 -0
  65. package/rendering/animationController.d.ts.map +1 -0
  66. package/rendering/animationController.js +246 -0
  67. package/rendering/animationController.js.map +1 -0
  68. package/rendering/renderingManager.d.ts +46 -0
  69. package/rendering/renderingManager.d.ts.map +1 -0
  70. package/rendering/renderingManager.js +61 -0
  71. package/rendering/renderingManager.js.map +1 -0
  72. package/worker.d.ts +2 -0
  73. package/worker.d.ts.map +1 -0
  74. package/worker.js +62 -0
  75. package/worker.js.map +1 -0
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Configuration options for the Lottie animation player.
3
+ */
4
+ export type AnimationConfiguration = {
5
+ /**
6
+ * Whether the animation should play on a loop or not
7
+ */
8
+ loopAnimation: boolean;
9
+ /**
10
+ * Width of the sprite atlas texture.
11
+ * Default is 4096.
12
+ */
13
+ spriteAtlasWidth: number;
14
+ /**
15
+ * Height of the sprite atlas texture.
16
+ * Default is 4096.
17
+ */
18
+ spriteAtlasHeight: number;
19
+ /**
20
+ * Gap size around sprites in the atlas.
21
+ * Default is 5.
22
+ */
23
+ gapSize: number;
24
+ /**
25
+ * Maximum number of sprites the renderer can handle at once.
26
+ * Default is 64.
27
+ */
28
+ spritesCapacity: number;
29
+ /**
30
+ * Background color for the animation canvas.
31
+ * Default is white with full opacity.
32
+ */
33
+ backgroundColor: {
34
+ r: number;
35
+ g: number;
36
+ b: number;
37
+ a: number;
38
+ };
39
+ /**
40
+ * Minimum scale factor to prevent too small sprites.
41
+ * Default is 5.
42
+ */
43
+ scaleMultiplier: number;
44
+ /**
45
+ * Scale factor for the rendering.
46
+ * Default is 1.
47
+ */
48
+ devicePixelRatio: number;
49
+ /**
50
+ * Number of steps to sample cubic bezier easing functions for animations.
51
+ * Default is 4.
52
+ */
53
+ easingSteps: number;
54
+ /**
55
+ * Whether to support device lost events for WebGL contexts.
56
+ * Default is false.
57
+ */
58
+ supportDeviceLost: boolean;
59
+ };
60
+ /**
61
+ * Default configuration for lottie animations playback.
62
+ */
63
+ export declare const DefaultConfiguration: {
64
+ readonly loopAnimation: false;
65
+ readonly spriteAtlasWidth: 4096;
66
+ readonly spriteAtlasHeight: 4096;
67
+ readonly gapSize: 5;
68
+ readonly spritesCapacity: 64;
69
+ readonly backgroundColor: {
70
+ readonly r: 1;
71
+ readonly g: 1;
72
+ readonly b: 1;
73
+ readonly a: 1;
74
+ };
75
+ readonly scaleMultiplier: 5;
76
+ readonly devicePixelRatio: 1;
77
+ readonly easingSteps: 4;
78
+ readonly supportDeviceLost: false;
79
+ };
80
+ //# sourceMappingURL=animationConfiguration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animationConfiguration.d.ts","sourceRoot":"","sources":["../../../dev/lottiePlayer/src/animationConfiguration.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,eAAe,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,iBAAiB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;CAWU,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Default configuration for lottie animations playback.
3
+ */
4
+ export const DefaultConfiguration = {
5
+ loopAnimation: false, // By default do not loop animations
6
+ spriteAtlasWidth: 4096, // Size of the texture atlas
7
+ spriteAtlasHeight: 4096, // Size of the texture atlas
8
+ gapSize: 5, // Gap around the sprites in the atlas
9
+ spritesCapacity: 64, // Maximum number of sprites the renderer can handle at once
10
+ backgroundColor: { r: 1, g: 1, b: 1, a: 1 }, // Background color for the animation canvas
11
+ scaleMultiplier: 5, // Minimum scale factor to prevent too small sprites,
12
+ devicePixelRatio: 1, // Scale factor,
13
+ easingSteps: 4, // Number of steps to sample easing functions for animations - Less than 4 causes issues with some interpolations
14
+ supportDeviceLost: false, // Whether to support device lost events for WebGL contexts,
15
+ };
16
+ //# sourceMappingURL=animationConfiguration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animationConfiguration.js","sourceRoot":"","sources":["../../../dev/lottiePlayer/src/animationConfiguration.ts"],"names":[],"mappings":"AAuDA;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAChC,aAAa,EAAE,KAAK,EAAE,oCAAoC;IAC1D,gBAAgB,EAAE,IAAI,EAAE,4BAA4B;IACpD,iBAAiB,EAAE,IAAI,EAAE,4BAA4B;IACrD,OAAO,EAAE,CAAC,EAAE,sCAAsC;IAClD,eAAe,EAAE,EAAE,EAAE,4DAA4D;IACjF,eAAe,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,4CAA4C;IACzF,eAAe,EAAE,CAAC,EAAE,qDAAqD;IACzE,gBAAgB,EAAE,CAAC,EAAE,gBAAgB;IACrC,WAAW,EAAE,CAAC,EAAE,iHAAiH;IACjI,iBAAiB,EAAE,KAAK,EAAE,4DAA4D;CAC/C,CAAC"}
package/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export { AnimationConfiguration } from "./animationConfiguration.js";
2
+ export { Player } from "./player.js";
3
+ export { LocalPlayer } from "./localPlayer.js";
4
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../dev/lottiePlayer/src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
package/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { Player } from "./player.js";
2
+ export { LocalPlayer } from "./localPlayer.js";
3
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../dev/lottiePlayer/src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
package/license.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Babylon.js
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,38 @@
1
+ import type { AnimationConfiguration } from "./animationConfiguration.js";
2
+ /**
3
+ * Allows you to play Lottie animations using Babylon.js.
4
+ * It plays the animations in the main JS thread. Prefer to use Player instead if Offscreen canvas and worker threads are supported.
5
+ * Once instance of this class can only be used to play a single animation. If you want to play multiple animations, create a new instance for each animation.
6
+ */
7
+ export declare class LocalPlayer {
8
+ private readonly _container;
9
+ private readonly _animationFile;
10
+ private readonly _variables;
11
+ private readonly _configuration;
12
+ private _rawAnimation;
13
+ private _scaleFactor;
14
+ private _playing;
15
+ private _disposed;
16
+ private _canvas;
17
+ private _resizeObserver;
18
+ private _animationController;
19
+ /**
20
+ * Creates a new instance of the LottiePlayer.
21
+ * @param container The HTMLDivElement to create the canvas in and render the animation on.
22
+ * @param animationFile The URL of the Lottie animation file to be played.
23
+ * @param variables Optional map of variables to replace in the animation file.
24
+ * @param configuration Optional configuration object to customize the animation playback.
25
+ */
26
+ constructor(container: HTMLDivElement, animationFile: string, variables?: Map<string, string>, configuration?: Partial<AnimationConfiguration>);
27
+ /**
28
+ * Loads and plays a lottie animation.
29
+ * @returns True if the animation is successfully set up to play, false if the animation couldn't play.
30
+ */
31
+ playAnimationAsync(): Promise<boolean>;
32
+ /**
33
+ * Disposes the LottiePlayer instance, cleaning up resources and event listeners.
34
+ */
35
+ dispose(): void;
36
+ private _onWindowResize;
37
+ }
38
+ //# sourceMappingURL=localPlayer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localPlayer.d.ts","sourceRoot":"","sources":["../../../dev/lottiePlayer/src/localPlayer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAMvE;;;;GAIG;AACH,qBAAa,WAAW;IACpB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAkC;IAEjE,OAAO,CAAC,aAAa,CAA6C;IAClE,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,oBAAoB,CAAoC;IAEhE;;;;;;OAMG;gBACgB,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,CAAC,EAAE,OAAO,CAAC,sBAAsB,CAAC;IAOrJ;;;OAGG;IACU,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IAuDnD;;OAEG;IACI,OAAO,IAAI,IAAI;IAgBtB,OAAO,CAAC,eAAe,CAUrB;CACL"}
package/localPlayer.js ADDED
@@ -0,0 +1,100 @@
1
+ import { DefaultConfiguration } from "./animationConfiguration.js";
2
+ import { GetRawAnimationDataAsync } from "./parsing/parser.js";
3
+ import { AnimationController, CalculateScaleFactor } from "./rendering/animationController.js";
4
+ /**
5
+ * Allows you to play Lottie animations using Babylon.js.
6
+ * It plays the animations in the main JS thread. Prefer to use Player instead if Offscreen canvas and worker threads are supported.
7
+ * Once instance of this class can only be used to play a single animation. If you want to play multiple animations, create a new instance for each animation.
8
+ */
9
+ export class LocalPlayer {
10
+ /**
11
+ * Creates a new instance of the LottiePlayer.
12
+ * @param container The HTMLDivElement to create the canvas in and render the animation on.
13
+ * @param animationFile The URL of the Lottie animation file to be played.
14
+ * @param variables Optional map of variables to replace in the animation file.
15
+ * @param configuration Optional configuration object to customize the animation playback.
16
+ */
17
+ constructor(container, animationFile, variables, configuration) {
18
+ this._rawAnimation = undefined;
19
+ this._scaleFactor = 1;
20
+ this._playing = false;
21
+ this._disposed = false;
22
+ this._canvas = null;
23
+ this._resizeObserver = null;
24
+ this._animationController = null;
25
+ this._onWindowResize = () => {
26
+ if (this._disposed || !this._canvas || !this._rawAnimation || this._animationController === null) {
27
+ return;
28
+ }
29
+ this._scaleFactor = CalculateScaleFactor(this._rawAnimation.w, this._rawAnimation.h, this._container);
30
+ this._canvas.style.width = `${this._rawAnimation.w * this._scaleFactor}px`;
31
+ this._canvas.style.height = `${this._rawAnimation.h * this._scaleFactor}px`;
32
+ this._animationController.setScale(this._scaleFactor);
33
+ };
34
+ this._container = container;
35
+ this._animationFile = animationFile;
36
+ this._variables = variables ?? new Map();
37
+ this._configuration = configuration ?? {};
38
+ }
39
+ /**
40
+ * Loads and plays a lottie animation.
41
+ * @returns True if the animation is successfully set up to play, false if the animation couldn't play.
42
+ */
43
+ async playAnimationAsync() {
44
+ if (this._playing || this._disposed) {
45
+ return false;
46
+ }
47
+ this._rawAnimation = await GetRawAnimationDataAsync(this._animationFile);
48
+ // Create the canvas element
49
+ this._canvas = document.createElement("canvas");
50
+ // Center the canvas in the container
51
+ this._canvas.style.position = "absolute";
52
+ this._canvas.style.left = "50%";
53
+ this._canvas.style.top = "50%";
54
+ this._canvas.style.transform = "translate(-50%, -50%)";
55
+ this._canvas.style.display = "block";
56
+ // The size of the canvas is the relation between the size of the container div and the size of the animation
57
+ this._scaleFactor = CalculateScaleFactor(this._rawAnimation.w, this._rawAnimation.h, this._container);
58
+ this._canvas.style.width = `${this._rawAnimation.w * this._scaleFactor}px`;
59
+ this._canvas.style.height = `${this._rawAnimation.h * this._scaleFactor}px`;
60
+ // Append the canvas to the container
61
+ this._container.appendChild(this._canvas);
62
+ const finalConfig = {
63
+ ...DefaultConfiguration,
64
+ ...this._configuration,
65
+ };
66
+ this._animationController = new AnimationController(this._canvas, this._rawAnimation, this._scaleFactor, this._variables, finalConfig);
67
+ this._animationController.playAnimation();
68
+ this._playing = true;
69
+ window.addEventListener("resize", this._onWindowResize);
70
+ if ("ResizeObserver" in window) {
71
+ this._resizeObserver = new ResizeObserver(() => {
72
+ if (this._disposed || !this._canvas || !this._rawAnimation || this._animationController === null) {
73
+ return;
74
+ }
75
+ this._scaleFactor = CalculateScaleFactor(this._rawAnimation.w, this._rawAnimation.h, this._container);
76
+ this._canvas.style.width = `${this._rawAnimation.w * this._scaleFactor}px`;
77
+ this._canvas.style.height = `${this._rawAnimation.h * this._scaleFactor}px`;
78
+ this._animationController.setScale(this._scaleFactor);
79
+ });
80
+ this._resizeObserver.observe(this._container);
81
+ }
82
+ return true;
83
+ }
84
+ /**
85
+ * Disposes the LottiePlayer instance, cleaning up resources and event listeners.
86
+ */
87
+ dispose() {
88
+ window.removeEventListener("resize", this._onWindowResize);
89
+ if (this._resizeObserver) {
90
+ this._resizeObserver.disconnect();
91
+ this._resizeObserver = null;
92
+ }
93
+ if (this._canvas) {
94
+ this._container.removeChild(this._canvas);
95
+ this._canvas = null;
96
+ }
97
+ this._disposed = true;
98
+ }
99
+ }
100
+ //# sourceMappingURL=localPlayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localPlayer.js","sourceRoot":"","sources":["../../../dev/lottiePlayer/src/localPlayer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Represents a Babylon.js thin version of a cubic bezier curve
3
+ * We are only exposing what we truly need in the scope of
4
+ * the Lottie Renderer project preventing the dependency on the full
5
+ * Babylon.js animation system.
6
+ */
7
+ export declare class BezierCurve {
8
+ /**
9
+ * X of the first control point
10
+ */
11
+ readonly x1: number;
12
+ /**
13
+ * Y of the first control point
14
+ */
15
+ readonly y1: number;
16
+ /**
17
+ * X of the second control point
18
+ */
19
+ readonly x2: number;
20
+ /**
21
+ * Y of the second control point
22
+ */
23
+ readonly y2: number;
24
+ private readonly _easingSteps;
25
+ private readonly _f0;
26
+ private readonly _f1;
27
+ private readonly _f2;
28
+ /**
29
+ * Instantiates a bezier function
30
+ * @see http://cubic-bezier.com/#.17,.67,.83,.67
31
+ * @param x1 Defines the x component of the start tangent in the bezier curve
32
+ * @param y1 Defines the y component of the start tangent in the bezier curve
33
+ * @param x2 Defines the x component of the end tangent in the bezier curve
34
+ * @param y2 Defines the y component of the end tangent in the bezier curve
35
+ * @param easingSteps Number of steps to sample the bezier curve for easing
36
+ */
37
+ constructor(x1: number | undefined, y1: number | undefined, x2: number | undefined, y2: number | undefined, easingSteps: number);
38
+ /**
39
+ * Interpolates the bezier curve at a given time
40
+ * @param t Defines the time to evaluate the bezier curve at, between 0 and 1
41
+ * @returns The interpolated value at time t
42
+ */
43
+ interpolate(t: number): number;
44
+ }
45
+ //# sourceMappingURL=bezier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bezier.d.ts","sourceRoot":"","sources":["../../../../dev/lottiePlayer/src/maths/bezier.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,qBAAa,WAAW;IACpB;;OAEG;IACH,SAAgB,EAAE,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,SAAgB,EAAE,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,SAAgB,EAAE,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,SAAgB,EAAE,EAAE,MAAM,CAAC;IAE3B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAE7B;;;;;;;;OAQG;gBACS,EAAE,EAAE,MAAM,YAAI,EAAE,EAAE,EAAE,MAAM,YAAI,EAAE,EAAE,EAAE,MAAM,YAAI,EAAE,EAAE,EAAE,MAAM,YAAI,EAAE,WAAW,EAAE,MAAM;IAa/F;;;;OAIG;IACI,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CAuBxC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Represents a Babylon.js thin version of a cubic bezier curve
3
+ * We are only exposing what we truly need in the scope of
4
+ * the Lottie Renderer project preventing the dependency on the full
5
+ * Babylon.js animation system.
6
+ */
7
+ export class BezierCurve {
8
+ /**
9
+ * Instantiates a bezier function
10
+ * @see http://cubic-bezier.com/#.17,.67,.83,.67
11
+ * @param x1 Defines the x component of the start tangent in the bezier curve
12
+ * @param y1 Defines the y component of the start tangent in the bezier curve
13
+ * @param x2 Defines the x component of the end tangent in the bezier curve
14
+ * @param y2 Defines the y component of the end tangent in the bezier curve
15
+ * @param easingSteps Number of steps to sample the bezier curve for easing
16
+ */
17
+ constructor(x1 = 0, y1 = 0, x2 = 1, y2 = 1, easingSteps) {
18
+ this.x1 = x1;
19
+ this.y1 = y1;
20
+ this.x2 = x2;
21
+ this.y2 = y2;
22
+ this._easingSteps = easingSteps;
23
+ // Pre-calculate coefficients
24
+ this._f0 = 1 - 3 * this.x2 + 3 * this.x1;
25
+ this._f1 = 3 * this.x2 - 6 * this.x1;
26
+ this._f2 = 3 * this.x1;
27
+ }
28
+ /**
29
+ * Interpolates the bezier curve at a given time
30
+ * @param t Defines the time to evaluate the bezier curve at, between 0 and 1
31
+ * @returns The interpolated value at time t
32
+ */
33
+ interpolate(t) {
34
+ if (t === 0) {
35
+ return 0;
36
+ }
37
+ if (t === 1) {
38
+ return 1;
39
+ }
40
+ let refinedT = t;
41
+ for (let i = 0; i < this._easingSteps; i++) {
42
+ const refinedT2 = refinedT * refinedT;
43
+ const refinedT3 = refinedT2 * refinedT;
44
+ const x = this._f0 * refinedT3 + this._f1 * refinedT2 + this._f2 * refinedT;
45
+ const slope = 1.0 / (3.0 * this._f0 * refinedT2 + 2.0 * this._f1 * refinedT + this._f2);
46
+ refinedT -= (x - t) * slope;
47
+ refinedT = Math.min(1, Math.max(0, refinedT));
48
+ }
49
+ // Resolve cubic bezier for the given x
50
+ return 3 * (1 - refinedT) * (1 - refinedT) * refinedT * this.y1 + 3 * (1 - refinedT) * refinedT * refinedT * this.y2 + refinedT * refinedT * refinedT;
51
+ }
52
+ }
53
+ //# sourceMappingURL=bezier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bezier.js","sourceRoot":"","sources":["../../../../dev/lottiePlayer/src/maths/bezier.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,OAAO,WAAW;IAwBpB;;;;;;;;OAQG;IACH,YAAY,KAAa,CAAC,EAAE,KAAa,CAAC,EAAE,KAAa,CAAC,EAAE,KAAa,CAAC,EAAE,WAAmB;QAC3F,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;QAEhC,6BAA6B;QAC7B,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;QACrC,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACI,WAAW,CAAC,CAAS;QACxB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACV,OAAO,CAAC,CAAC;QACb,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACV,OAAO,CAAC,CAAC;QACb,CAAC;QAED,IAAI,QAAQ,GAAG,CAAC,CAAC;QAEjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;YACtC,MAAM,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;YACvC,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,GAAG,QAAQ,CAAC;YAC5E,MAAM,KAAK,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,SAAS,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;YACxF,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;YAC5B,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;QAClD,CAAC;QAED,uCAAuC;QACvC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,QAAQ,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,QAAQ,CAAC,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAC,EAAE,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC1J,CAAC;CACJ"}
@@ -0,0 +1,39 @@
1
+ import type { RawElement, RawFont, RawTextData } from "../parsing/rawTypes.js";
2
+ /**
3
+ * Represents a bounding box for a shape in the animation.
4
+ */
5
+ export type BoundingBox = {
6
+ /** Height of the bounding box */
7
+ height: number;
8
+ /** Width of the bounding box */
9
+ width: number;
10
+ /** X coordinate of the center of the bounding box */
11
+ centerX: number;
12
+ /** Y coordinate of the center of the bounding box */
13
+ centerY: number;
14
+ /** Inset for the stroke, if applicable. */
15
+ strokeInset: number;
16
+ /**
17
+ * Optional: Canvas2D text metrics for precise vertical alignment
18
+ */
19
+ actualBoundingBoxAscent?: number;
20
+ /**
21
+ * Optional: Canvas2D text metrics for precise vertical alignment
22
+ */
23
+ actualBoundingBoxDescent?: number;
24
+ };
25
+ /**
26
+ * Calculates the bounding box for a group of graphic elements in a Lottie animation.
27
+ * @param rawElements The elements to calculate the bounding box for
28
+ * @returns The bounding box for the elements
29
+ */
30
+ export declare function GetShapesBoundingBox(rawElements: RawElement[]): BoundingBox;
31
+ /**
32
+ * Calculates the bounding box for a group of graphic elements in a Lottie animation.
33
+ * @param spritesCanvasContext The OffscreenCanvasRenderingContext2D or CanvasRenderingContext2D to use for text measurement
34
+ * @param textData The text to calculate the bounding box for
35
+ * @param rawFonts A map of font names to their raw font data
36
+ * @returns The bounding box for the text
37
+ */
38
+ export declare function GetTextBoundingBox(spritesCanvasContext: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D, textData: RawTextData, rawFonts: Map<string, RawFont>): BoundingBox | undefined;
39
+ //# sourceMappingURL=boundingBox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundingBox.d.ts","sourceRoot":"","sources":["../../../../dev/lottiePlayer/src/maths/boundingBox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,UAAU,EAAE,OAAO,EAAmD,WAAW,EAAmB,MAAM,qBAAqB,CAAC;AAEzJ;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACtB,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACrC,CAAC;AAUF;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,WAAW,CA0B3E;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAC9B,oBAAoB,EAAE,iCAAiC,GAAG,wBAAwB,EAClF,QAAQ,EAAE,WAAW,EACrB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,WAAW,GAAG,SAAS,CA0CzB"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Calculates the bounding box for a group of graphic elements in a Lottie animation.
3
+ * @param rawElements The elements to calculate the bounding box for
4
+ * @returns The bounding box for the elements
5
+ */
6
+ export function GetShapesBoundingBox(rawElements) {
7
+ const boxCorners = {
8
+ minX: Infinity,
9
+ minY: Infinity,
10
+ maxX: -Infinity,
11
+ maxY: -Infinity,
12
+ };
13
+ let extraPadding = 0;
14
+ for (let i = 0; i < rawElements.length; i++) {
15
+ if (rawElements[i].ty === "rc") {
16
+ GetRectangleVertices(boxCorners, rawElements[i]);
17
+ }
18
+ else if (rawElements[i].ty === "sh") {
19
+ GetPathVertices(boxCorners, rawElements[i]);
20
+ }
21
+ else if (rawElements[i].ty === "st") {
22
+ extraPadding = Math.max(extraPadding, GetStrokeInset(rawElements[i]));
23
+ }
24
+ }
25
+ return {
26
+ width: Math.ceil(boxCorners.maxX - boxCorners.minX) + extraPadding,
27
+ height: Math.ceil(boxCorners.maxY - boxCorners.minY) + extraPadding,
28
+ centerX: Math.ceil((boxCorners.maxX + boxCorners.minX) / 2),
29
+ centerY: Math.ceil((boxCorners.maxY + boxCorners.minY) / 2),
30
+ strokeInset: 0,
31
+ };
32
+ }
33
+ /**
34
+ * Calculates the bounding box for a group of graphic elements in a Lottie animation.
35
+ * @param spritesCanvasContext The OffscreenCanvasRenderingContext2D or CanvasRenderingContext2D to use for text measurement
36
+ * @param textData The text to calculate the bounding box for
37
+ * @param rawFonts A map of font names to their raw font data
38
+ * @returns The bounding box for the text
39
+ */
40
+ export function GetTextBoundingBox(spritesCanvasContext, textData, rawFonts) {
41
+ spritesCanvasContext.save();
42
+ let textInfo = undefined;
43
+ if (textData.d && textData.d.k && textData.d.k.length > 0) {
44
+ textInfo = textData.d.k[0].s;
45
+ }
46
+ if (!textInfo) {
47
+ spritesCanvasContext.restore();
48
+ return undefined;
49
+ }
50
+ const fontSize = textInfo.s;
51
+ const fontFamily = textInfo.f;
52
+ const finalFont = rawFonts.get(fontFamily);
53
+ if (!finalFont) {
54
+ spritesCanvasContext.restore();
55
+ return undefined;
56
+ }
57
+ const weight = finalFont.fWeight || "400"; // Default to normal weight if not specified
58
+ spritesCanvasContext.font = `${weight} ${fontSize}px ${finalFont.fFamily}`;
59
+ if (textInfo.sc !== undefined && textInfo.sc.length >= 3 && textInfo.sw !== undefined && textInfo.sw > 0) {
60
+ spritesCanvasContext.lineWidth = textInfo.sw;
61
+ }
62
+ const text = textInfo.t;
63
+ const metrics = spritesCanvasContext.measureText(text);
64
+ const widthPx = Math.ceil(metrics.width);
65
+ const heightPx = Math.ceil(metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent);
66
+ return {
67
+ width: widthPx,
68
+ height: heightPx,
69
+ centerX: Math.ceil(widthPx / 2),
70
+ centerY: Math.ceil(heightPx / 2),
71
+ strokeInset: 0, // Text bounding box ignores stroke padding here
72
+ actualBoundingBoxAscent: metrics.actualBoundingBoxAscent,
73
+ actualBoundingBoxDescent: metrics.actualBoundingBoxDescent,
74
+ };
75
+ }
76
+ function GetRectangleVertices(boxCorners, rect) {
77
+ const size = rect.s.k;
78
+ const position = rect.p.k;
79
+ // Calculate the four corners of the rectangle
80
+ UpdateBoxCorners(boxCorners, position[0] - size[0] / 2, position[1] - size[1] / 2);
81
+ UpdateBoxCorners(boxCorners, position[0] + size[0] / 2, position[1] - size[1] / 2);
82
+ UpdateBoxCorners(boxCorners, position[0] + size[0] / 2, position[1] + size[1] / 2);
83
+ UpdateBoxCorners(boxCorners, position[0] - size[0] / 2, position[1] + size[1] / 2);
84
+ }
85
+ function GetPathVertices(boxCorners, path) {
86
+ const bezier = path.ks.k;
87
+ const vertices = bezier.v;
88
+ const inTangents = bezier.i;
89
+ const outTangents = bezier.o;
90
+ // Check the control points of the path
91
+ for (let i = 0; i < vertices.length; i++) {
92
+ UpdateBoxCorners(boxCorners, vertices[i][0], vertices[i][1]);
93
+ }
94
+ for (let i = 0; i < vertices.length; i++) {
95
+ // Skip last point if the path is not closed
96
+ if (!bezier.c && i === vertices.length - 1) {
97
+ continue;
98
+ }
99
+ const start = vertices[i];
100
+ const end = i === vertices.length - 1 ? vertices[0] : vertices[i + 1];
101
+ const outTangent = outTangents[i];
102
+ const inTangent = i === vertices.length - 1 ? inTangents[0] : inTangents[i + 1];
103
+ // Calculate the points where the tangent is zero
104
+ CalculatePointsWithTangentZero(boxCorners, start[0], start[1], end[0], end[1], start[0] + outTangent[0], start[1] + outTangent[1], end[0] + inTangent[0], end[1] + inTangent[1]);
105
+ }
106
+ }
107
+ function GetStrokeInset(stroke) {
108
+ return Math.ceil(stroke.w?.k) ?? 1;
109
+ }
110
+ function CalculatePointsWithTangentZero(boxCorners, startX, startY, endX, endY, controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y) {
111
+ // Calculate the derivative of the bezier formula for X and Y components
112
+ // For X component:
113
+ const ax = 3 * (endX - 3 * controlPoint2X + 3 * controlPoint1X - startX);
114
+ const bx = 6 * (controlPoint2X - 2 * controlPoint1X + startX);
115
+ const cx = 3 * (controlPoint1X - startX);
116
+ // For Y component:
117
+ const ay = 3 * (endY - 3 * controlPoint2Y + 3 * controlPoint1Y - startY);
118
+ const by = 6 * (controlPoint2Y - 2 * controlPoint1Y + startY);
119
+ const cy = 3 * (controlPoint1Y - startY);
120
+ // Solve the quadratic equation where dt/dt = 0 (tangent is zero)
121
+ const rootsX = SolveQuadratic(ax, bx, cx);
122
+ const rootsY = SolveQuadratic(ay, by, cy);
123
+ // Merge + dedupe (roots arrays are tiny: <=2 each)
124
+ const candidateTs = rootsX.slice(); // copy
125
+ for (let i = 0; i < rootsY.length; i++) {
126
+ const ty = rootsY[i];
127
+ let exists = false;
128
+ for (let j = 0; j < candidateTs.length; j++) {
129
+ if (candidateTs[j] === ty) {
130
+ exists = true;
131
+ break;
132
+ }
133
+ }
134
+ if (!exists) {
135
+ candidateTs.push(ty);
136
+ }
137
+ }
138
+ // Evaluate the bezier at the calculated t values to find the points of the curve where the tangent is zero
139
+ for (let i = 0; i < candidateTs.length; i++) {
140
+ const t = candidateTs[i];
141
+ if (t >= 0 && t <= 1) {
142
+ const x = BezierPoint(t, startX, controlPoint1X, controlPoint2X, endX);
143
+ const y = BezierPoint(t, startY, controlPoint1Y, controlPoint2Y, endY);
144
+ UpdateBoxCorners(boxCorners, x, y);
145
+ }
146
+ }
147
+ }
148
+ // Alternative implementation for bounding box calculation using sampling of the bezier curve instead of finding points where the tangent is zero.
149
+ // function bezierBoundingBoxSampled(boxCorners: Corners, start:IVector2Like, outTangent:IVector2Like, inTangent:IVector2Like, end:IVector2Like) {
150
+ // for (let i = 0; i <= SamplingSteps; i++) {
151
+ // const t = i / SamplingSteps;
152
+ // const x = bezierPoint(t, start.x, outTangent.x, inTangent.x, end.x);
153
+ // const y = bezierPoint(t, start.y, outTangent.y, inTangent.y, end.y);
154
+ // updateBoxCorners(boxCorners, x, y);
155
+ // }
156
+ // }
157
+ function SolveQuadratic(a, b, c) {
158
+ const roots = [];
159
+ // Handle the case where a is zero (linear equation)
160
+ // Linear equation: bx + c = 0 => x = -c / b
161
+ if (Math.abs(a) < 1e-10) {
162
+ if (Math.abs(b) > 1e-10) {
163
+ const root = -c / b;
164
+ roots.push(root);
165
+ }
166
+ return roots;
167
+ }
168
+ // Solve the quadratic equation ax^2 + bx + c = 0
169
+ const discriminant = b * b - 4 * a * c;
170
+ if (discriminant < 0) {
171
+ return roots; // No real roots
172
+ }
173
+ if (Math.abs(discriminant) < 1e-10) {
174
+ const root = -b / (2 * a);
175
+ roots.push(root);
176
+ }
177
+ else {
178
+ const sqrtD = Math.sqrt(discriminant);
179
+ const root1 = (-b + sqrtD) / (2 * a);
180
+ const root2 = (-b - sqrtD) / (2 * a);
181
+ roots.push(root1);
182
+ roots.push(root2);
183
+ }
184
+ return roots;
185
+ }
186
+ function BezierPoint(t, p0, p1, p2, p3) {
187
+ const mt = 1 - t;
188
+ return mt * mt * mt * p0 + 3 * mt * mt * t * p1 + 3 * mt * t * t * p2 + t * t * t * p3;
189
+ }
190
+ function UpdateBoxCorners(boxCorners, x, y) {
191
+ if (x < boxCorners.minX) {
192
+ boxCorners.minX = x;
193
+ }
194
+ if (x > boxCorners.maxX) {
195
+ boxCorners.maxX = x;
196
+ }
197
+ if (y < boxCorners.minY) {
198
+ boxCorners.minY = y;
199
+ }
200
+ if (y > boxCorners.maxY) {
201
+ boxCorners.maxY = y;
202
+ }
203
+ }
204
+ //# sourceMappingURL=boundingBox.js.map