@redwilly/anima 0.1.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 (239) hide show
  1. package/dist/cli/SceneLoader.d.ts +22 -0
  2. package/dist/cli/SceneLoader.js +47 -0
  3. package/dist/cli/commands/export-frame.d.ts +13 -0
  4. package/dist/cli/commands/export-frame.js +60 -0
  5. package/dist/cli/commands/list-scenes.d.ts +5 -0
  6. package/dist/cli/commands/list-scenes.js +22 -0
  7. package/dist/cli/commands/preview.d.ts +5 -0
  8. package/dist/cli/commands/preview.js +11 -0
  9. package/dist/cli/commands/render.d.ts +16 -0
  10. package/dist/cli/commands/render.js +76 -0
  11. package/dist/cli/index.d.ts +2 -0
  12. package/dist/cli/index.js +63 -0
  13. package/dist/core/animations/Animation.d.ts +41 -0
  14. package/dist/core/animations/Animation.js +76 -0
  15. package/dist/core/animations/camera/Follow.d.ts +70 -0
  16. package/dist/core/animations/camera/Follow.js +69 -0
  17. package/dist/core/animations/camera/Shake.d.ts +90 -0
  18. package/dist/core/animations/camera/Shake.js +87 -0
  19. package/dist/core/animations/camera/index.d.ts +2 -0
  20. package/dist/core/animations/camera/index.js +2 -0
  21. package/dist/core/animations/categories/ExitAnimation.d.ts +17 -0
  22. package/dist/core/animations/categories/ExitAnimation.js +15 -0
  23. package/dist/core/animations/categories/IntroductoryAnimation.d.ts +16 -0
  24. package/dist/core/animations/categories/IntroductoryAnimation.js +14 -0
  25. package/dist/core/animations/categories/TransformativeAnimation.d.ts +25 -0
  26. package/dist/core/animations/categories/TransformativeAnimation.js +25 -0
  27. package/dist/core/animations/categories/index.d.ts +3 -0
  28. package/dist/core/animations/categories/index.js +3 -0
  29. package/dist/core/animations/composition/Parallel.d.ts +37 -0
  30. package/dist/core/animations/composition/Parallel.js +79 -0
  31. package/dist/core/animations/composition/Sequence.d.ts +41 -0
  32. package/dist/core/animations/composition/Sequence.js +95 -0
  33. package/dist/core/animations/composition/index.d.ts +2 -0
  34. package/dist/core/animations/composition/index.js +3 -0
  35. package/dist/core/animations/draw/Draw.d.ts +30 -0
  36. package/dist/core/animations/draw/Draw.js +122 -0
  37. package/dist/core/animations/draw/Unwrite.d.ts +30 -0
  38. package/dist/core/animations/draw/Unwrite.js +120 -0
  39. package/dist/core/animations/draw/Write.d.ts +35 -0
  40. package/dist/core/animations/draw/Write.js +119 -0
  41. package/dist/core/animations/draw/index.d.ts +3 -0
  42. package/dist/core/animations/draw/index.js +3 -0
  43. package/dist/core/animations/draw/partialPath.d.ts +6 -0
  44. package/dist/core/animations/draw/partialPath.js +138 -0
  45. package/dist/core/animations/easing/bounce.d.ts +13 -0
  46. package/dist/core/animations/easing/bounce.js +37 -0
  47. package/dist/core/animations/easing/index.d.ts +7 -0
  48. package/dist/core/animations/easing/index.js +11 -0
  49. package/dist/core/animations/easing/manim.d.ts +46 -0
  50. package/dist/core/animations/easing/manim.js +102 -0
  51. package/dist/core/animations/easing/registry.d.ts +8 -0
  52. package/dist/core/animations/easing/registry.js +25 -0
  53. package/dist/core/animations/easing/standard.d.ts +113 -0
  54. package/dist/core/animations/easing/standard.js +151 -0
  55. package/dist/core/animations/easing/types.d.ts +6 -0
  56. package/dist/core/animations/easing/types.js +0 -0
  57. package/dist/core/animations/fade/FadeIn.d.ts +17 -0
  58. package/dist/core/animations/fade/FadeIn.js +22 -0
  59. package/dist/core/animations/fade/FadeOut.d.ts +17 -0
  60. package/dist/core/animations/fade/FadeOut.js +23 -0
  61. package/dist/core/animations/fade/index.d.ts +2 -0
  62. package/dist/core/animations/fade/index.js +2 -0
  63. package/dist/core/animations/index.d.ts +11 -0
  64. package/dist/core/animations/index.js +17 -0
  65. package/dist/core/animations/keyframes/KeyframeAnimation.d.ts +33 -0
  66. package/dist/core/animations/keyframes/KeyframeAnimation.js +40 -0
  67. package/dist/core/animations/keyframes/KeyframeTrack.d.ts +31 -0
  68. package/dist/core/animations/keyframes/KeyframeTrack.js +83 -0
  69. package/dist/core/animations/keyframes/index.d.ts +4 -0
  70. package/dist/core/animations/keyframes/index.js +5 -0
  71. package/dist/core/animations/keyframes/types.d.ts +25 -0
  72. package/dist/core/animations/keyframes/types.js +6 -0
  73. package/dist/core/animations/morph/MorphTo.d.ts +22 -0
  74. package/dist/core/animations/morph/MorphTo.js +42 -0
  75. package/dist/core/animations/morph/index.d.ts +1 -0
  76. package/dist/core/animations/morph/index.js +1 -0
  77. package/dist/core/animations/transform/MoveTo.d.ts +24 -0
  78. package/dist/core/animations/transform/MoveTo.js +38 -0
  79. package/dist/core/animations/transform/Rotate.d.ts +23 -0
  80. package/dist/core/animations/transform/Rotate.js +34 -0
  81. package/dist/core/animations/transform/Scale.d.ts +23 -0
  82. package/dist/core/animations/transform/Scale.js +35 -0
  83. package/dist/core/animations/transform/index.d.ts +3 -0
  84. package/dist/core/animations/transform/index.js +3 -0
  85. package/dist/core/animations/types.d.ts +52 -0
  86. package/dist/core/animations/types.js +6 -0
  87. package/dist/core/camera/Camera.d.ts +87 -0
  88. package/dist/core/camera/Camera.js +175 -0
  89. package/dist/core/camera/CameraFrame.d.ts +242 -0
  90. package/dist/core/camera/CameraFrame.js +322 -0
  91. package/dist/core/camera/index.d.ts +4 -0
  92. package/dist/core/camera/index.js +3 -0
  93. package/dist/core/camera/types.d.ts +17 -0
  94. package/dist/core/camera/types.js +1 -0
  95. package/dist/core/errors/AnimationErrors.d.ts +12 -0
  96. package/dist/core/errors/AnimationErrors.js +37 -0
  97. package/dist/core/errors/index.d.ts +1 -0
  98. package/dist/core/errors/index.js +1 -0
  99. package/dist/core/math/Vector2/Vector2.d.ts +23 -0
  100. package/dist/core/math/Vector2/Vector2.js +46 -0
  101. package/dist/core/math/Vector2/index.d.ts +1 -0
  102. package/dist/core/math/Vector2/index.js +1 -0
  103. package/dist/core/math/bezier/BezierPath.d.ts +38 -0
  104. package/dist/core/math/bezier/BezierPath.js +264 -0
  105. package/dist/core/math/bezier/evaluators.d.ts +9 -0
  106. package/dist/core/math/bezier/evaluators.js +36 -0
  107. package/dist/core/math/bezier/index.d.ts +8 -0
  108. package/dist/core/math/bezier/index.js +6 -0
  109. package/dist/core/math/bezier/length.d.ts +5 -0
  110. package/dist/core/math/bezier/length.js +27 -0
  111. package/dist/core/math/bezier/morphing.d.ts +16 -0
  112. package/dist/core/math/bezier/morphing.js +151 -0
  113. package/dist/core/math/bezier/sampling.d.ts +7 -0
  114. package/dist/core/math/bezier/sampling.js +153 -0
  115. package/dist/core/math/bezier/split.d.ts +19 -0
  116. package/dist/core/math/bezier/split.js +44 -0
  117. package/dist/core/math/bezier/types.d.ts +8 -0
  118. package/dist/core/math/bezier/types.js +0 -0
  119. package/dist/core/math/color/Color.d.ts +28 -0
  120. package/dist/core/math/color/Color.js +60 -0
  121. package/dist/core/math/color/conversions.d.ts +17 -0
  122. package/dist/core/math/color/conversions.js +100 -0
  123. package/dist/core/math/color/index.d.ts +2 -0
  124. package/dist/core/math/color/index.js +2 -0
  125. package/dist/core/math/index.d.ts +4 -0
  126. package/dist/core/math/index.js +5 -0
  127. package/dist/core/math/matrix/Matrix3x3.d.ts +23 -0
  128. package/dist/core/math/matrix/Matrix3x3.js +91 -0
  129. package/dist/core/math/matrix/factories.d.ts +12 -0
  130. package/dist/core/math/matrix/factories.js +44 -0
  131. package/dist/core/math/matrix/index.d.ts +2 -0
  132. package/dist/core/math/matrix/index.js +2 -0
  133. package/dist/core/renderer/FrameRenderer.d.ts +37 -0
  134. package/dist/core/renderer/FrameRenderer.js +75 -0
  135. package/dist/core/renderer/ProgressReporter.d.ts +19 -0
  136. package/dist/core/renderer/ProgressReporter.js +58 -0
  137. package/dist/core/renderer/Renderer.d.ts +36 -0
  138. package/dist/core/renderer/Renderer.js +102 -0
  139. package/dist/core/renderer/drawMobject.d.ts +8 -0
  140. package/dist/core/renderer/drawMobject.js +109 -0
  141. package/dist/core/renderer/formats/index.d.ts +3 -0
  142. package/dist/core/renderer/formats/index.js +3 -0
  143. package/dist/core/renderer/formats/png.d.ts +5 -0
  144. package/dist/core/renderer/formats/png.js +7 -0
  145. package/dist/core/renderer/formats/sprite.d.ts +6 -0
  146. package/dist/core/renderer/formats/sprite.js +24 -0
  147. package/dist/core/renderer/formats/video.d.ts +8 -0
  148. package/dist/core/renderer/formats/video.js +51 -0
  149. package/dist/core/renderer/index.d.ts +7 -0
  150. package/dist/core/renderer/index.js +9 -0
  151. package/dist/core/renderer/types.d.ts +87 -0
  152. package/dist/core/renderer/types.js +13 -0
  153. package/dist/core/scene/Scene.d.ts +104 -0
  154. package/dist/core/scene/Scene.js +225 -0
  155. package/dist/core/scene/index.d.ts +2 -0
  156. package/dist/core/scene/index.js +1 -0
  157. package/dist/core/scene/types.d.ts +23 -0
  158. package/dist/core/scene/types.js +0 -0
  159. package/dist/core/serialization/animation.d.ts +23 -0
  160. package/dist/core/serialization/animation.js +176 -0
  161. package/dist/core/serialization/easingLookup.d.ts +13 -0
  162. package/dist/core/serialization/easingLookup.js +65 -0
  163. package/dist/core/serialization/index.d.ts +23 -0
  164. package/dist/core/serialization/index.js +29 -0
  165. package/dist/core/serialization/mobject.d.ts +23 -0
  166. package/dist/core/serialization/mobject.js +248 -0
  167. package/dist/core/serialization/prettyPrint.d.ts +12 -0
  168. package/dist/core/serialization/prettyPrint.js +16 -0
  169. package/dist/core/serialization/primitives.d.ts +24 -0
  170. package/dist/core/serialization/primitives.js +98 -0
  171. package/dist/core/serialization/registry.d.ts +29 -0
  172. package/dist/core/serialization/registry.js +39 -0
  173. package/dist/core/serialization/scene.d.ts +28 -0
  174. package/dist/core/serialization/scene.js +114 -0
  175. package/dist/core/serialization/types.d.ts +152 -0
  176. package/dist/core/serialization/types.js +6 -0
  177. package/dist/core/timeline/Timeline.d.ts +70 -0
  178. package/dist/core/timeline/Timeline.js +144 -0
  179. package/dist/core/timeline/index.d.ts +5 -0
  180. package/dist/core/timeline/index.js +4 -0
  181. package/dist/core/timeline/types.d.ts +29 -0
  182. package/dist/core/timeline/types.js +0 -0
  183. package/dist/index.d.ts +18 -0
  184. package/dist/index.js +22 -0
  185. package/dist/mobjects/Mobject.d.ts +98 -0
  186. package/dist/mobjects/Mobject.js +343 -0
  187. package/dist/mobjects/VGroup/VGroup.d.ts +51 -0
  188. package/dist/mobjects/VGroup/VGroup.js +142 -0
  189. package/dist/mobjects/VGroup/index.d.ts +3 -0
  190. package/dist/mobjects/VGroup/index.js +2 -0
  191. package/dist/mobjects/VGroup/layout.d.ts +20 -0
  192. package/dist/mobjects/VGroup/layout.js +139 -0
  193. package/dist/mobjects/VMobject.d.ts +106 -0
  194. package/dist/mobjects/VMobject.js +216 -0
  195. package/dist/mobjects/geometry/Arc.d.ts +8 -0
  196. package/dist/mobjects/geometry/Arc.js +46 -0
  197. package/dist/mobjects/geometry/Arrow.d.ts +7 -0
  198. package/dist/mobjects/geometry/Arrow.js +34 -0
  199. package/dist/mobjects/geometry/Circle.d.ts +4 -0
  200. package/dist/mobjects/geometry/Circle.js +10 -0
  201. package/dist/mobjects/geometry/Line.d.ts +8 -0
  202. package/dist/mobjects/geometry/Line.js +19 -0
  203. package/dist/mobjects/geometry/Point.d.ts +5 -0
  204. package/dist/mobjects/geometry/Point.js +11 -0
  205. package/dist/mobjects/geometry/Polygon.d.ts +7 -0
  206. package/dist/mobjects/geometry/Polygon.js +21 -0
  207. package/dist/mobjects/geometry/Rectangle.d.ts +6 -0
  208. package/dist/mobjects/geometry/Rectangle.js +18 -0
  209. package/dist/mobjects/geometry/index.d.ts +7 -0
  210. package/dist/mobjects/geometry/index.js +7 -0
  211. package/dist/mobjects/graph/Graph.d.ts +28 -0
  212. package/dist/mobjects/graph/Graph.js +119 -0
  213. package/dist/mobjects/graph/GraphEdge.d.ts +26 -0
  214. package/dist/mobjects/graph/GraphEdge.js +64 -0
  215. package/dist/mobjects/graph/GraphNode.d.ts +19 -0
  216. package/dist/mobjects/graph/GraphNode.js +63 -0
  217. package/dist/mobjects/graph/index.d.ts +5 -0
  218. package/dist/mobjects/graph/index.js +5 -0
  219. package/dist/mobjects/graph/layouts/circular.d.ts +8 -0
  220. package/dist/mobjects/graph/layouts/circular.js +23 -0
  221. package/dist/mobjects/graph/layouts/forceDirected.d.ts +9 -0
  222. package/dist/mobjects/graph/layouts/forceDirected.js +102 -0
  223. package/dist/mobjects/graph/layouts/index.d.ts +3 -0
  224. package/dist/mobjects/graph/layouts/index.js +3 -0
  225. package/dist/mobjects/graph/layouts/tree.d.ts +9 -0
  226. package/dist/mobjects/graph/layouts/tree.js +99 -0
  227. package/dist/mobjects/graph/types.d.ts +35 -0
  228. package/dist/mobjects/graph/types.js +0 -0
  229. package/dist/mobjects/index.d.ts +6 -0
  230. package/dist/mobjects/index.js +6 -0
  231. package/dist/mobjects/text/Glyph.d.ts +11 -0
  232. package/dist/mobjects/text/Glyph.js +72 -0
  233. package/dist/mobjects/text/Text.d.ts +19 -0
  234. package/dist/mobjects/text/Text.js +76 -0
  235. package/dist/mobjects/text/index.d.ts +4 -0
  236. package/dist/mobjects/text/index.js +3 -0
  237. package/dist/mobjects/text/types.d.ts +12 -0
  238. package/dist/mobjects/text/types.js +8 -0
  239. package/package.json +51 -0
@@ -0,0 +1,122 @@
1
+ import { IntroductoryAnimation } from '../categories';
2
+ import { getPartialPath } from './partialPath';
3
+ /**
4
+ * Checks if a VMobject is a VGroup (has getChildren method).
5
+ * Uses duck-typing to avoid circular dependency with VGroup import.
6
+ */
7
+ function isVGroup(target) {
8
+ return typeof target.getChildren === 'function';
9
+ }
10
+ /**
11
+ * Animation that first draws the border progressively, then fills the shape.
12
+ * The first 50% of the animation draws the stroke, the second 50% fades in the fill.
13
+ *
14
+ * Supports VGroup (including Text): animates each child's paths progressively.
15
+ *
16
+ * This is an introductory animation - it auto-registers the target with the scene.
17
+ *
18
+ * @example
19
+ * const rect = new Rectangle(2, 1);
20
+ * scene.play(new Draw(rect)); // Border draws, then fill fades in
21
+ */
22
+ export class Draw extends IntroductoryAnimation {
23
+ isVGroup;
24
+ /** For non-VGroup targets: original paths on the target itself. */
25
+ originalPaths;
26
+ originalFillOpacity;
27
+ originalOpacity;
28
+ /** For VGroup targets: original state of each child. */
29
+ childStates;
30
+ constructor(target) {
31
+ super(target);
32
+ this.isVGroup = isVGroup(target);
33
+ this.originalOpacity = target.opacity;
34
+ this.originalFillOpacity = target.getFillOpacity();
35
+ if (this.isVGroup && isVGroup(target)) {
36
+ // Store original state for each child
37
+ this.originalPaths = [];
38
+ this.childStates = [];
39
+ for (const child of target.getChildren()) {
40
+ this.childStates.push({
41
+ child,
42
+ originalPaths: child.paths.map((p) => p.clone()),
43
+ originalOpacity: child.opacity,
44
+ originalFillOpacity: child.getFillOpacity(),
45
+ });
46
+ }
47
+ }
48
+ else {
49
+ // Store original paths on the target itself
50
+ this.originalPaths = target.paths.map(p => p.clone());
51
+ this.childStates = [];
52
+ }
53
+ }
54
+ /** Interpolates stroke drawing (0-0.5) and then fill fade (0.5-1). */
55
+ interpolate(progress) {
56
+ if (this.isVGroup) {
57
+ this.interpolateVGroup(progress);
58
+ }
59
+ else {
60
+ this.interpolateVMobject(progress);
61
+ }
62
+ }
63
+ /** Interpolates a single VMobject (non-VGroup). */
64
+ interpolateVMobject(progress) {
65
+ const targetOpacity = this.originalOpacity === 0 ? 1 : this.originalOpacity;
66
+ if (progress <= 0) {
67
+ this.target.paths = [];
68
+ this.target.setOpacity(0);
69
+ this.target.fill(this.target.getFillColor(), 0);
70
+ return;
71
+ }
72
+ this.target.setOpacity(targetOpacity);
73
+ if (progress < 0.5) {
74
+ // First half: draw stroke progressively, no fill
75
+ const strokeProgress = progress * 2;
76
+ const partialPaths = [];
77
+ for (const originalPath of this.originalPaths) {
78
+ partialPaths.push(getPartialPath(originalPath, strokeProgress));
79
+ }
80
+ this.target.paths = partialPaths;
81
+ this.target.fill(this.target.getFillColor(), 0);
82
+ }
83
+ else {
84
+ // Second half: full stroke, fade in fill
85
+ this.target.paths = this.originalPaths.map(p => p.clone());
86
+ const fillProgress = (progress - 0.5) * 2;
87
+ this.target.fill(this.target.getFillColor(), this.originalFillOpacity * fillProgress);
88
+ }
89
+ }
90
+ /** Interpolates a VGroup by animating each child's paths. */
91
+ interpolateVGroup(progress) {
92
+ const targetOpacity = this.originalOpacity === 0 ? 1 : this.originalOpacity;
93
+ this.target.setOpacity(progress <= 0 ? 0 : targetOpacity);
94
+ for (const state of this.childStates) {
95
+ const { child, originalPaths, originalOpacity, originalFillOpacity } = state;
96
+ const childOpacity = originalOpacity === 0 ? 1 : originalOpacity;
97
+ if (progress <= 0) {
98
+ child.paths = [];
99
+ child.setOpacity(0);
100
+ child.fill(child.getFillColor(), 0);
101
+ continue;
102
+ }
103
+ child.setOpacity(childOpacity);
104
+ if (progress < 0.5) {
105
+ // First half: draw stroke progressively, no fill
106
+ const strokeProgress = progress * 2;
107
+ const partialPaths = [];
108
+ for (const originalPath of originalPaths) {
109
+ partialPaths.push(getPartialPath(originalPath, strokeProgress));
110
+ }
111
+ child.paths = partialPaths;
112
+ child.fill(child.getFillColor(), 0);
113
+ }
114
+ else {
115
+ // Second half: full stroke, fade in fill
116
+ child.paths = originalPaths.map(p => p.clone());
117
+ const fillProgress = (progress - 0.5) * 2;
118
+ child.fill(child.getFillColor(), originalFillOpacity * fillProgress);
119
+ }
120
+ }
121
+ }
122
+ }
@@ -0,0 +1,30 @@
1
+ import { ExitAnimation } from '../categories';
2
+ import { VMobject } from '../../../mobjects/VMobject';
3
+ /**
4
+ * Animation that progressively removes a VMobject by erasing the path.
5
+ * Reverse of Write animation - at progress 0, full object is visible;
6
+ * at progress 1, nothing is visible.
7
+ *
8
+ * Supports VGroup (including Text): animates each child's paths progressively.
9
+ *
10
+ * This is an exit animation - the target must already be in the scene.
11
+ *
12
+ * @example
13
+ * scene.play(new Write(text));
14
+ * scene.play(new Unwrite(text)); // Text is erased progressively
15
+ */
16
+ export declare class Unwrite<T extends VMobject = VMobject> extends ExitAnimation<T> {
17
+ private readonly isVGroup;
18
+ /** For non-VGroup targets: original paths on the target itself. */
19
+ private readonly originalPaths;
20
+ private readonly originalOpacity;
21
+ private readonly originalFillOpacity;
22
+ /** For VGroup targets: original state of each child. */
23
+ private readonly childStates;
24
+ constructor(target: T);
25
+ interpolate(progress: number): void;
26
+ /** Interpolates a single VMobject (non-VGroup). */
27
+ private interpolateVMobject;
28
+ /** Interpolates a VGroup by animating each child's paths. */
29
+ private interpolateVGroup;
30
+ }
@@ -0,0 +1,120 @@
1
+ import { ExitAnimation } from '../categories';
2
+ import { getPartialPath } from './partialPath';
3
+ /**
4
+ * Checks if a VMobject is a VGroup (has getChildren method).
5
+ * Uses duck-typing to avoid circular dependency with VGroup import.
6
+ */
7
+ function isVGroup(target) {
8
+ return typeof target.getChildren === 'function';
9
+ }
10
+ /**
11
+ * Animation that progressively removes a VMobject by erasing the path.
12
+ * Reverse of Write animation - at progress 0, full object is visible;
13
+ * at progress 1, nothing is visible.
14
+ *
15
+ * Supports VGroup (including Text): animates each child's paths progressively.
16
+ *
17
+ * This is an exit animation - the target must already be in the scene.
18
+ *
19
+ * @example
20
+ * scene.play(new Write(text));
21
+ * scene.play(new Unwrite(text)); // Text is erased progressively
22
+ */
23
+ export class Unwrite extends ExitAnimation {
24
+ isVGroup;
25
+ /** For non-VGroup targets: original paths on the target itself. */
26
+ originalPaths;
27
+ originalOpacity;
28
+ originalFillOpacity;
29
+ /** For VGroup targets: original state of each child. */
30
+ childStates;
31
+ constructor(target) {
32
+ super(target);
33
+ this.isVGroup = isVGroup(target);
34
+ this.originalOpacity = target.opacity;
35
+ this.originalFillOpacity = target.getFillOpacity();
36
+ if (this.isVGroup && isVGroup(target)) {
37
+ // Store original state for each child
38
+ this.originalPaths = [];
39
+ this.childStates = [];
40
+ for (const child of target.getChildren()) {
41
+ this.childStates.push({
42
+ child,
43
+ originalPaths: child.paths.map((p) => p.clone()),
44
+ originalOpacity: child.opacity,
45
+ originalFillOpacity: child.getFillOpacity(),
46
+ });
47
+ }
48
+ }
49
+ else {
50
+ // Store original paths on the target itself
51
+ this.originalPaths = target.paths.map(p => p.clone());
52
+ this.childStates = [];
53
+ }
54
+ }
55
+ interpolate(progress) {
56
+ if (this.isVGroup) {
57
+ this.interpolateVGroup(progress);
58
+ }
59
+ else {
60
+ this.interpolateVMobject(progress);
61
+ }
62
+ }
63
+ /** Interpolates a single VMobject (non-VGroup). */
64
+ interpolateVMobject(progress) {
65
+ if (progress >= 1) {
66
+ this.target.paths = [];
67
+ this.target.setOpacity(0);
68
+ return;
69
+ }
70
+ if (progress <= 0) {
71
+ this.target.paths = this.originalPaths.map(p => p.clone());
72
+ const targetOpacity = this.originalOpacity === 0 ? 1 : this.originalOpacity;
73
+ this.target.setOpacity(targetOpacity);
74
+ this.target.fill(this.target.getFillColor(), this.originalFillOpacity);
75
+ return;
76
+ }
77
+ // Show partial paths (reverse progress)
78
+ const reverseProgress = 1 - progress;
79
+ const targetOpacity = this.originalOpacity === 0 ? 1 : this.originalOpacity;
80
+ this.target.setOpacity(targetOpacity);
81
+ this.target.fill(this.target.getFillColor(), this.originalFillOpacity);
82
+ const partialPaths = [];
83
+ for (const originalPath of this.originalPaths) {
84
+ partialPaths.push(getPartialPath(originalPath, reverseProgress));
85
+ }
86
+ this.target.paths = partialPaths;
87
+ }
88
+ /** Interpolates a VGroup by animating each child's paths. */
89
+ interpolateVGroup(progress) {
90
+ if (progress >= 1) {
91
+ this.target.setOpacity(0);
92
+ for (const state of this.childStates) {
93
+ state.child.paths = [];
94
+ state.child.setOpacity(0);
95
+ }
96
+ return;
97
+ }
98
+ const targetOpacity = this.originalOpacity === 0 ? 1 : this.originalOpacity;
99
+ this.target.setOpacity(targetOpacity);
100
+ for (const state of this.childStates) {
101
+ const { child, originalPaths, originalOpacity, originalFillOpacity } = state;
102
+ const childOpacity = originalOpacity === 0 ? 1 : originalOpacity;
103
+ if (progress <= 0) {
104
+ child.paths = originalPaths.map(p => p.clone());
105
+ child.setOpacity(childOpacity);
106
+ child.fill(child.getFillColor(), originalFillOpacity);
107
+ continue;
108
+ }
109
+ // Show partial paths (reverse progress)
110
+ const reverseProgress = 1 - progress;
111
+ child.setOpacity(childOpacity);
112
+ child.fill(child.getFillColor(), originalFillOpacity);
113
+ const partialPaths = [];
114
+ for (const originalPath of originalPaths) {
115
+ partialPaths.push(getPartialPath(originalPath, reverseProgress));
116
+ }
117
+ child.paths = partialPaths;
118
+ }
119
+ }
120
+ }
@@ -0,0 +1,35 @@
1
+ import { IntroductoryAnimation } from '../categories';
2
+ import { VMobject } from '../../../mobjects/VMobject';
3
+ /**
4
+ * Animation that progressively draws a VMobject's paths from start to end.
5
+ * Preserves both stroke and fill properties - the complete object is visible at the end.
6
+ *
7
+ * This is the canonical animation for progressive path drawing.
8
+ * At progress 0, nothing is shown. At progress 1, the complete path is shown.
9
+ *
10
+ * Supports VGroup (including Text): animates each child's paths progressively.
11
+ *
12
+ * This is an introductory animation - it auto-registers the target with the scene.
13
+ *
14
+ * @example
15
+ * const circle = new Circle(1);
16
+ * scene.play(new Write(circle)); // Circle is drawn progressively
17
+ *
18
+ * const text = new Text('Hello');
19
+ * scene.play(new Write(text)); // Text is written progressively
20
+ */
21
+ export declare class Write<T extends VMobject = VMobject> extends IntroductoryAnimation<T> {
22
+ private readonly isVGroup;
23
+ /** For non-VGroup targets: original paths on the target itself. */
24
+ private readonly originalPaths;
25
+ private readonly originalOpacity;
26
+ private readonly originalFillOpacity;
27
+ /** For VGroup targets: original state of each child. */
28
+ private readonly childStates;
29
+ constructor(target: T);
30
+ interpolate(progress: number): void;
31
+ /** Interpolates a single VMobject (non-VGroup). */
32
+ private interpolateVMobject;
33
+ /** Interpolates a VGroup by animating each child's paths. */
34
+ private interpolateVGroup;
35
+ }
@@ -0,0 +1,119 @@
1
+ import { IntroductoryAnimation } from '../categories';
2
+ import { getPartialPath } from './partialPath';
3
+ /**
4
+ * Checks if a VMobject is a VGroup (has getChildren method).
5
+ * Uses duck-typing to avoid circular dependency with VGroup import.
6
+ */
7
+ function isVGroup(target) {
8
+ return typeof target.getChildren === 'function';
9
+ }
10
+ /**
11
+ * Animation that progressively draws a VMobject's paths from start to end.
12
+ * Preserves both stroke and fill properties - the complete object is visible at the end.
13
+ *
14
+ * This is the canonical animation for progressive path drawing.
15
+ * At progress 0, nothing is shown. At progress 1, the complete path is shown.
16
+ *
17
+ * Supports VGroup (including Text): animates each child's paths progressively.
18
+ *
19
+ * This is an introductory animation - it auto-registers the target with the scene.
20
+ *
21
+ * @example
22
+ * const circle = new Circle(1);
23
+ * scene.play(new Write(circle)); // Circle is drawn progressively
24
+ *
25
+ * const text = new Text('Hello');
26
+ * scene.play(new Write(text)); // Text is written progressively
27
+ */
28
+ export class Write extends IntroductoryAnimation {
29
+ isVGroup;
30
+ /** For non-VGroup targets: original paths on the target itself. */
31
+ originalPaths;
32
+ originalOpacity;
33
+ originalFillOpacity;
34
+ /** For VGroup targets: original state of each child. */
35
+ childStates;
36
+ constructor(target) {
37
+ super(target);
38
+ this.isVGroup = isVGroup(target);
39
+ this.originalOpacity = target.opacity;
40
+ this.originalFillOpacity = target.getFillOpacity();
41
+ if (this.isVGroup && isVGroup(target)) {
42
+ // Store original state for each child
43
+ this.originalPaths = [];
44
+ this.childStates = [];
45
+ for (const child of target.getChildren()) {
46
+ this.childStates.push({
47
+ child,
48
+ originalPaths: child.paths.map((p) => p.clone()),
49
+ originalOpacity: child.opacity,
50
+ originalFillOpacity: child.getFillOpacity(),
51
+ });
52
+ }
53
+ }
54
+ else {
55
+ // Store original paths on the target itself
56
+ this.originalPaths = target.paths.map(p => p.clone());
57
+ this.childStates = [];
58
+ }
59
+ }
60
+ interpolate(progress) {
61
+ if (this.isVGroup) {
62
+ this.interpolateVGroup(progress);
63
+ }
64
+ else {
65
+ this.interpolateVMobject(progress);
66
+ }
67
+ }
68
+ /** Interpolates a single VMobject (non-VGroup). */
69
+ interpolateVMobject(progress) {
70
+ if (progress <= 0) {
71
+ this.target.paths = [];
72
+ this.target.setOpacity(0);
73
+ return;
74
+ }
75
+ // Make visible and preserve original fill opacity
76
+ const targetOpacity = this.originalOpacity === 0 ? 1 : this.originalOpacity;
77
+ this.target.setOpacity(targetOpacity);
78
+ this.target.fill(this.target.getFillColor(), this.originalFillOpacity);
79
+ if (progress >= 1) {
80
+ this.target.paths = this.originalPaths.map(p => p.clone());
81
+ return;
82
+ }
83
+ // Show partial paths
84
+ const partialPaths = [];
85
+ for (const originalPath of this.originalPaths) {
86
+ partialPaths.push(getPartialPath(originalPath, progress));
87
+ }
88
+ this.target.paths = partialPaths;
89
+ }
90
+ /** Interpolates a VGroup by animating each child's paths. */
91
+ interpolateVGroup(progress) {
92
+ // Set parent VGroup opacity
93
+ const targetOpacity = this.originalOpacity === 0 ? 1 : this.originalOpacity;
94
+ this.target.setOpacity(progress <= 0 ? 0 : targetOpacity);
95
+ // Animate each child
96
+ for (const state of this.childStates) {
97
+ const { child, originalPaths, originalOpacity, originalFillOpacity } = state;
98
+ if (progress <= 0) {
99
+ child.paths = [];
100
+ child.setOpacity(0);
101
+ continue;
102
+ }
103
+ // Make child visible
104
+ const childOpacity = originalOpacity === 0 ? 1 : originalOpacity;
105
+ child.setOpacity(childOpacity);
106
+ child.fill(child.getFillColor(), originalFillOpacity);
107
+ if (progress >= 1) {
108
+ child.paths = originalPaths.map(p => p.clone());
109
+ continue;
110
+ }
111
+ // Show partial paths for this child
112
+ const partialPaths = [];
113
+ for (const originalPath of originalPaths) {
114
+ partialPaths.push(getPartialPath(originalPath, progress));
115
+ }
116
+ child.paths = partialPaths;
117
+ }
118
+ }
119
+ }
@@ -0,0 +1,3 @@
1
+ export { Draw } from './Draw';
2
+ export { Write } from './Write';
3
+ export { Unwrite } from './Unwrite';
@@ -0,0 +1,3 @@
1
+ export { Draw } from './Draw';
2
+ export { Write } from './Write';
3
+ export { Unwrite } from './Unwrite';
@@ -0,0 +1,6 @@
1
+ import { BezierPath } from '../../math/bezier/BezierPath';
2
+ /**
3
+ * Returns a partial BezierPath from the start up to a given normalized t (0–1).
4
+ * The path is truncated at the exact point corresponding to t * totalLength.
5
+ */
6
+ export declare function getPartialPath(path: BezierPath, t: number): BezierPath;
@@ -0,0 +1,138 @@
1
+ import { BezierPath } from '../../math/bezier/BezierPath';
2
+ import { Vector2 } from '../../math/Vector2/Vector2';
3
+ import { getQuadraticLength, getCubicLength } from '../../math/bezier/length';
4
+ import { evaluateQuadratic } from '../../math/bezier/evaluators';
5
+ import { splitCubicAt } from '../../math/bezier/split';
6
+ /**
7
+ * Returns a partial BezierPath from the start up to a given normalized t (0–1).
8
+ * The path is truncated at the exact point corresponding to t * totalLength.
9
+ */
10
+ export function getPartialPath(path, t) {
11
+ if (t <= 0) {
12
+ return new BezierPath();
13
+ }
14
+ if (t >= 1) {
15
+ return path.clone();
16
+ }
17
+ const totalLength = path.getLength();
18
+ if (totalLength === 0) {
19
+ return path.clone();
20
+ }
21
+ const targetLength = t * totalLength;
22
+ const commands = path.getCommands();
23
+ const result = new BezierPath();
24
+ let accumulatedLength = 0;
25
+ let cursor = Vector2.ZERO;
26
+ let subpathStart = Vector2.ZERO;
27
+ for (const cmd of commands) {
28
+ const segmentLength = getSegmentLength(cmd, cursor, subpathStart);
29
+ const newAccumulated = accumulatedLength + segmentLength;
30
+ if (newAccumulated <= targetLength) {
31
+ // Include entire segment
32
+ appendCommand(result, cmd, cursor, subpathStart);
33
+ updateCursor(cmd, cursor, subpathStart, (c, s) => {
34
+ cursor = c;
35
+ subpathStart = s;
36
+ });
37
+ accumulatedLength = newAccumulated;
38
+ }
39
+ else {
40
+ // Partial segment needed
41
+ const remaining = targetLength - accumulatedLength;
42
+ const localT = segmentLength > 0 ? remaining / segmentLength : 0;
43
+ appendPartialCommand(result, cmd, cursor, subpathStart, localT);
44
+ break;
45
+ }
46
+ }
47
+ return result;
48
+ }
49
+ function getSegmentLength(cmd, cursor, subpathStart) {
50
+ switch (cmd.type) {
51
+ case 'Move':
52
+ return 0;
53
+ case 'Line':
54
+ return cursor.subtract(cmd.end).length();
55
+ case 'Quadratic':
56
+ if (cmd.control1) {
57
+ return getQuadraticLength(cursor, cmd.control1, cmd.end);
58
+ }
59
+ return 0;
60
+ case 'Cubic':
61
+ if (cmd.control1 && cmd.control2) {
62
+ return getCubicLength(cursor, cmd.control1, cmd.control2, cmd.end);
63
+ }
64
+ return 0;
65
+ case 'Close':
66
+ return cursor.subtract(subpathStart).length();
67
+ default:
68
+ return 0;
69
+ }
70
+ }
71
+ function updateCursor(cmd, _cursor, subpathStart, update) {
72
+ switch (cmd.type) {
73
+ case 'Move':
74
+ update(cmd.end, cmd.end);
75
+ break;
76
+ case 'Close':
77
+ update(subpathStart, subpathStart);
78
+ break;
79
+ default:
80
+ update(cmd.end, subpathStart);
81
+ break;
82
+ }
83
+ }
84
+ function appendCommand(result, cmd, _cursor, _subpathStart) {
85
+ switch (cmd.type) {
86
+ case 'Move':
87
+ result.moveTo(cmd.end);
88
+ break;
89
+ case 'Line':
90
+ result.lineTo(cmd.end);
91
+ break;
92
+ case 'Quadratic':
93
+ if (cmd.control1) {
94
+ result.quadraticTo(cmd.control1, cmd.end);
95
+ }
96
+ break;
97
+ case 'Cubic':
98
+ if (cmd.control1 && cmd.control2) {
99
+ result.cubicTo(cmd.control1, cmd.control2, cmd.end);
100
+ }
101
+ break;
102
+ case 'Close':
103
+ result.closePath();
104
+ break;
105
+ }
106
+ }
107
+ function appendPartialCommand(result, cmd, cursor, subpathStart, localT) {
108
+ switch (cmd.type) {
109
+ case 'Move':
110
+ result.moveTo(cmd.end);
111
+ break;
112
+ case 'Line': {
113
+ const point = cursor.lerp(cmd.end, localT);
114
+ result.lineTo(point);
115
+ break;
116
+ }
117
+ case 'Quadratic': {
118
+ if (cmd.control1) {
119
+ const point = evaluateQuadratic(cursor, cmd.control1, cmd.end, localT);
120
+ // Approximate with line for partial quadratic
121
+ result.lineTo(point);
122
+ }
123
+ break;
124
+ }
125
+ case 'Cubic': {
126
+ if (cmd.control1 && cmd.control2) {
127
+ const [first] = splitCubicAt(cursor, cmd.control1, cmd.control2, cmd.end, localT);
128
+ result.cubicTo(first.control1, first.control2, first.end);
129
+ }
130
+ break;
131
+ }
132
+ case 'Close': {
133
+ const point = cursor.lerp(subpathStart, localT);
134
+ result.lineTo(point);
135
+ break;
136
+ }
137
+ }
138
+ }
@@ -0,0 +1,13 @@
1
+ import type { EasingFunction } from './types';
2
+ /**
3
+ * Bounce ease-in: bounces before settling.
4
+ */
5
+ export declare const easeInBounce: EasingFunction;
6
+ /**
7
+ * Bounce ease-out: bounces at the end.
8
+ */
9
+ export declare const easeOutBounce: EasingFunction;
10
+ /**
11
+ * Bounce ease-in-out: bounces at both ends.
12
+ */
13
+ export declare const easeInOutBounce: EasingFunction;
@@ -0,0 +1,37 @@
1
+ // --- Bounce helpers ---
2
+ /**
3
+ * Bounce ease-out helper calculation.
4
+ */
5
+ function bounceOut(t) {
6
+ const n1 = 7.5625;
7
+ const d1 = 2.75;
8
+ if (t < 1 / d1) {
9
+ return n1 * t * t;
10
+ }
11
+ else if (t < 2 / d1) {
12
+ const adjusted = t - 1.5 / d1;
13
+ return n1 * adjusted * adjusted + 0.75;
14
+ }
15
+ else if (t < 2.5 / d1) {
16
+ const adjusted = t - 2.25 / d1;
17
+ return n1 * adjusted * adjusted + 0.9375;
18
+ }
19
+ else {
20
+ const adjusted = t - 2.625 / d1;
21
+ return n1 * adjusted * adjusted + 0.984375;
22
+ }
23
+ }
24
+ /**
25
+ * Bounce ease-in: bounces before settling.
26
+ */
27
+ export const easeInBounce = (t) => 1 - bounceOut(1 - t);
28
+ /**
29
+ * Bounce ease-out: bounces at the end.
30
+ */
31
+ export const easeOutBounce = bounceOut;
32
+ /**
33
+ * Bounce ease-in-out: bounces at both ends.
34
+ */
35
+ export const easeInOutBounce = (t) => t < 0.5
36
+ ? (1 - bounceOut(1 - 2 * t)) / 2
37
+ : (1 + bounceOut(2 * t - 1)) / 2;
@@ -0,0 +1,7 @@
1
+ export type { EasingFunction } from './types';
2
+ export { linear, easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, easeInQuint, easeOutQuint, easeInOutQuint, easeInSine, easeOutSine, easeInOutSine, easeInExpo, easeOutExpo, easeInOutExpo, easeInCirc, easeOutCirc, easeInOutCirc, easeInBack, easeOutBack, easeInOutBack, easeInElastic, easeOutElastic, easeInOutElastic, } from './standard';
3
+ export { easeInBounce, easeOutBounce, easeInOutBounce, } from './bounce';
4
+ export { smooth, doubleSmooth, rushInto, rushFrom, slowInto, thereAndBack, thereAndBackWithPause, runningStart, wiggle, notQuiteThere, lingering, exponentialDecay, } from './manim';
5
+ export { registerEasing, getEasing, hasEasing, unregisterEasing, clearRegistry, } from './registry';
6
+ import { smooth } from './manim';
7
+ export { smooth as defaultEasing };
@@ -0,0 +1,11 @@
1
+ // Standard easing functions
2
+ export { linear, easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, easeInQuint, easeOutQuint, easeInOutQuint, easeInSine, easeOutSine, easeInOutSine, easeInExpo, easeOutExpo, easeInOutExpo, easeInCirc, easeOutCirc, easeInOutCirc, easeInBack, easeOutBack, easeInOutBack, easeInElastic, easeOutElastic, easeInOutElastic, } from './standard';
3
+ // Bounce functions
4
+ export { easeInBounce, easeOutBounce, easeInOutBounce, } from './bounce';
5
+ // Manim-style rate functions
6
+ export { smooth, doubleSmooth, rushInto, rushFrom, slowInto, thereAndBack, thereAndBackWithPause, runningStart, wiggle, notQuiteThere, lingering, exponentialDecay, } from './manim';
7
+ // Custom easing registry
8
+ export { registerEasing, getEasing, hasEasing, unregisterEasing, clearRegistry, } from './registry';
9
+ // Re-export smooth as the default easing
10
+ import { smooth } from './manim';
11
+ export { smooth as defaultEasing };