@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.
- package/dist/cli/SceneLoader.d.ts +22 -0
- package/dist/cli/SceneLoader.js +47 -0
- package/dist/cli/commands/export-frame.d.ts +13 -0
- package/dist/cli/commands/export-frame.js +60 -0
- package/dist/cli/commands/list-scenes.d.ts +5 -0
- package/dist/cli/commands/list-scenes.js +22 -0
- package/dist/cli/commands/preview.d.ts +5 -0
- package/dist/cli/commands/preview.js +11 -0
- package/dist/cli/commands/render.d.ts +16 -0
- package/dist/cli/commands/render.js +76 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +63 -0
- package/dist/core/animations/Animation.d.ts +41 -0
- package/dist/core/animations/Animation.js +76 -0
- package/dist/core/animations/camera/Follow.d.ts +70 -0
- package/dist/core/animations/camera/Follow.js +69 -0
- package/dist/core/animations/camera/Shake.d.ts +90 -0
- package/dist/core/animations/camera/Shake.js +87 -0
- package/dist/core/animations/camera/index.d.ts +2 -0
- package/dist/core/animations/camera/index.js +2 -0
- package/dist/core/animations/categories/ExitAnimation.d.ts +17 -0
- package/dist/core/animations/categories/ExitAnimation.js +15 -0
- package/dist/core/animations/categories/IntroductoryAnimation.d.ts +16 -0
- package/dist/core/animations/categories/IntroductoryAnimation.js +14 -0
- package/dist/core/animations/categories/TransformativeAnimation.d.ts +25 -0
- package/dist/core/animations/categories/TransformativeAnimation.js +25 -0
- package/dist/core/animations/categories/index.d.ts +3 -0
- package/dist/core/animations/categories/index.js +3 -0
- package/dist/core/animations/composition/Parallel.d.ts +37 -0
- package/dist/core/animations/composition/Parallel.js +79 -0
- package/dist/core/animations/composition/Sequence.d.ts +41 -0
- package/dist/core/animations/composition/Sequence.js +95 -0
- package/dist/core/animations/composition/index.d.ts +2 -0
- package/dist/core/animations/composition/index.js +3 -0
- package/dist/core/animations/draw/Draw.d.ts +30 -0
- package/dist/core/animations/draw/Draw.js +122 -0
- package/dist/core/animations/draw/Unwrite.d.ts +30 -0
- package/dist/core/animations/draw/Unwrite.js +120 -0
- package/dist/core/animations/draw/Write.d.ts +35 -0
- package/dist/core/animations/draw/Write.js +119 -0
- package/dist/core/animations/draw/index.d.ts +3 -0
- package/dist/core/animations/draw/index.js +3 -0
- package/dist/core/animations/draw/partialPath.d.ts +6 -0
- package/dist/core/animations/draw/partialPath.js +138 -0
- package/dist/core/animations/easing/bounce.d.ts +13 -0
- package/dist/core/animations/easing/bounce.js +37 -0
- package/dist/core/animations/easing/index.d.ts +7 -0
- package/dist/core/animations/easing/index.js +11 -0
- package/dist/core/animations/easing/manim.d.ts +46 -0
- package/dist/core/animations/easing/manim.js +102 -0
- package/dist/core/animations/easing/registry.d.ts +8 -0
- package/dist/core/animations/easing/registry.js +25 -0
- package/dist/core/animations/easing/standard.d.ts +113 -0
- package/dist/core/animations/easing/standard.js +151 -0
- package/dist/core/animations/easing/types.d.ts +6 -0
- package/dist/core/animations/easing/types.js +0 -0
- package/dist/core/animations/fade/FadeIn.d.ts +17 -0
- package/dist/core/animations/fade/FadeIn.js +22 -0
- package/dist/core/animations/fade/FadeOut.d.ts +17 -0
- package/dist/core/animations/fade/FadeOut.js +23 -0
- package/dist/core/animations/fade/index.d.ts +2 -0
- package/dist/core/animations/fade/index.js +2 -0
- package/dist/core/animations/index.d.ts +11 -0
- package/dist/core/animations/index.js +17 -0
- package/dist/core/animations/keyframes/KeyframeAnimation.d.ts +33 -0
- package/dist/core/animations/keyframes/KeyframeAnimation.js +40 -0
- package/dist/core/animations/keyframes/KeyframeTrack.d.ts +31 -0
- package/dist/core/animations/keyframes/KeyframeTrack.js +83 -0
- package/dist/core/animations/keyframes/index.d.ts +4 -0
- package/dist/core/animations/keyframes/index.js +5 -0
- package/dist/core/animations/keyframes/types.d.ts +25 -0
- package/dist/core/animations/keyframes/types.js +6 -0
- package/dist/core/animations/morph/MorphTo.d.ts +22 -0
- package/dist/core/animations/morph/MorphTo.js +42 -0
- package/dist/core/animations/morph/index.d.ts +1 -0
- package/dist/core/animations/morph/index.js +1 -0
- package/dist/core/animations/transform/MoveTo.d.ts +24 -0
- package/dist/core/animations/transform/MoveTo.js +38 -0
- package/dist/core/animations/transform/Rotate.d.ts +23 -0
- package/dist/core/animations/transform/Rotate.js +34 -0
- package/dist/core/animations/transform/Scale.d.ts +23 -0
- package/dist/core/animations/transform/Scale.js +35 -0
- package/dist/core/animations/transform/index.d.ts +3 -0
- package/dist/core/animations/transform/index.js +3 -0
- package/dist/core/animations/types.d.ts +52 -0
- package/dist/core/animations/types.js +6 -0
- package/dist/core/camera/Camera.d.ts +87 -0
- package/dist/core/camera/Camera.js +175 -0
- package/dist/core/camera/CameraFrame.d.ts +242 -0
- package/dist/core/camera/CameraFrame.js +322 -0
- package/dist/core/camera/index.d.ts +4 -0
- package/dist/core/camera/index.js +3 -0
- package/dist/core/camera/types.d.ts +17 -0
- package/dist/core/camera/types.js +1 -0
- package/dist/core/errors/AnimationErrors.d.ts +12 -0
- package/dist/core/errors/AnimationErrors.js +37 -0
- package/dist/core/errors/index.d.ts +1 -0
- package/dist/core/errors/index.js +1 -0
- package/dist/core/math/Vector2/Vector2.d.ts +23 -0
- package/dist/core/math/Vector2/Vector2.js +46 -0
- package/dist/core/math/Vector2/index.d.ts +1 -0
- package/dist/core/math/Vector2/index.js +1 -0
- package/dist/core/math/bezier/BezierPath.d.ts +38 -0
- package/dist/core/math/bezier/BezierPath.js +264 -0
- package/dist/core/math/bezier/evaluators.d.ts +9 -0
- package/dist/core/math/bezier/evaluators.js +36 -0
- package/dist/core/math/bezier/index.d.ts +8 -0
- package/dist/core/math/bezier/index.js +6 -0
- package/dist/core/math/bezier/length.d.ts +5 -0
- package/dist/core/math/bezier/length.js +27 -0
- package/dist/core/math/bezier/morphing.d.ts +16 -0
- package/dist/core/math/bezier/morphing.js +151 -0
- package/dist/core/math/bezier/sampling.d.ts +7 -0
- package/dist/core/math/bezier/sampling.js +153 -0
- package/dist/core/math/bezier/split.d.ts +19 -0
- package/dist/core/math/bezier/split.js +44 -0
- package/dist/core/math/bezier/types.d.ts +8 -0
- package/dist/core/math/bezier/types.js +0 -0
- package/dist/core/math/color/Color.d.ts +28 -0
- package/dist/core/math/color/Color.js +60 -0
- package/dist/core/math/color/conversions.d.ts +17 -0
- package/dist/core/math/color/conversions.js +100 -0
- package/dist/core/math/color/index.d.ts +2 -0
- package/dist/core/math/color/index.js +2 -0
- package/dist/core/math/index.d.ts +4 -0
- package/dist/core/math/index.js +5 -0
- package/dist/core/math/matrix/Matrix3x3.d.ts +23 -0
- package/dist/core/math/matrix/Matrix3x3.js +91 -0
- package/dist/core/math/matrix/factories.d.ts +12 -0
- package/dist/core/math/matrix/factories.js +44 -0
- package/dist/core/math/matrix/index.d.ts +2 -0
- package/dist/core/math/matrix/index.js +2 -0
- package/dist/core/renderer/FrameRenderer.d.ts +37 -0
- package/dist/core/renderer/FrameRenderer.js +75 -0
- package/dist/core/renderer/ProgressReporter.d.ts +19 -0
- package/dist/core/renderer/ProgressReporter.js +58 -0
- package/dist/core/renderer/Renderer.d.ts +36 -0
- package/dist/core/renderer/Renderer.js +102 -0
- package/dist/core/renderer/drawMobject.d.ts +8 -0
- package/dist/core/renderer/drawMobject.js +109 -0
- package/dist/core/renderer/formats/index.d.ts +3 -0
- package/dist/core/renderer/formats/index.js +3 -0
- package/dist/core/renderer/formats/png.d.ts +5 -0
- package/dist/core/renderer/formats/png.js +7 -0
- package/dist/core/renderer/formats/sprite.d.ts +6 -0
- package/dist/core/renderer/formats/sprite.js +24 -0
- package/dist/core/renderer/formats/video.d.ts +8 -0
- package/dist/core/renderer/formats/video.js +51 -0
- package/dist/core/renderer/index.d.ts +7 -0
- package/dist/core/renderer/index.js +9 -0
- package/dist/core/renderer/types.d.ts +87 -0
- package/dist/core/renderer/types.js +13 -0
- package/dist/core/scene/Scene.d.ts +104 -0
- package/dist/core/scene/Scene.js +225 -0
- package/dist/core/scene/index.d.ts +2 -0
- package/dist/core/scene/index.js +1 -0
- package/dist/core/scene/types.d.ts +23 -0
- package/dist/core/scene/types.js +0 -0
- package/dist/core/serialization/animation.d.ts +23 -0
- package/dist/core/serialization/animation.js +176 -0
- package/dist/core/serialization/easingLookup.d.ts +13 -0
- package/dist/core/serialization/easingLookup.js +65 -0
- package/dist/core/serialization/index.d.ts +23 -0
- package/dist/core/serialization/index.js +29 -0
- package/dist/core/serialization/mobject.d.ts +23 -0
- package/dist/core/serialization/mobject.js +248 -0
- package/dist/core/serialization/prettyPrint.d.ts +12 -0
- package/dist/core/serialization/prettyPrint.js +16 -0
- package/dist/core/serialization/primitives.d.ts +24 -0
- package/dist/core/serialization/primitives.js +98 -0
- package/dist/core/serialization/registry.d.ts +29 -0
- package/dist/core/serialization/registry.js +39 -0
- package/dist/core/serialization/scene.d.ts +28 -0
- package/dist/core/serialization/scene.js +114 -0
- package/dist/core/serialization/types.d.ts +152 -0
- package/dist/core/serialization/types.js +6 -0
- package/dist/core/timeline/Timeline.d.ts +70 -0
- package/dist/core/timeline/Timeline.js +144 -0
- package/dist/core/timeline/index.d.ts +5 -0
- package/dist/core/timeline/index.js +4 -0
- package/dist/core/timeline/types.d.ts +29 -0
- package/dist/core/timeline/types.js +0 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +22 -0
- package/dist/mobjects/Mobject.d.ts +98 -0
- package/dist/mobjects/Mobject.js +343 -0
- package/dist/mobjects/VGroup/VGroup.d.ts +51 -0
- package/dist/mobjects/VGroup/VGroup.js +142 -0
- package/dist/mobjects/VGroup/index.d.ts +3 -0
- package/dist/mobjects/VGroup/index.js +2 -0
- package/dist/mobjects/VGroup/layout.d.ts +20 -0
- package/dist/mobjects/VGroup/layout.js +139 -0
- package/dist/mobjects/VMobject.d.ts +106 -0
- package/dist/mobjects/VMobject.js +216 -0
- package/dist/mobjects/geometry/Arc.d.ts +8 -0
- package/dist/mobjects/geometry/Arc.js +46 -0
- package/dist/mobjects/geometry/Arrow.d.ts +7 -0
- package/dist/mobjects/geometry/Arrow.js +34 -0
- package/dist/mobjects/geometry/Circle.d.ts +4 -0
- package/dist/mobjects/geometry/Circle.js +10 -0
- package/dist/mobjects/geometry/Line.d.ts +8 -0
- package/dist/mobjects/geometry/Line.js +19 -0
- package/dist/mobjects/geometry/Point.d.ts +5 -0
- package/dist/mobjects/geometry/Point.js +11 -0
- package/dist/mobjects/geometry/Polygon.d.ts +7 -0
- package/dist/mobjects/geometry/Polygon.js +21 -0
- package/dist/mobjects/geometry/Rectangle.d.ts +6 -0
- package/dist/mobjects/geometry/Rectangle.js +18 -0
- package/dist/mobjects/geometry/index.d.ts +7 -0
- package/dist/mobjects/geometry/index.js +7 -0
- package/dist/mobjects/graph/Graph.d.ts +28 -0
- package/dist/mobjects/graph/Graph.js +119 -0
- package/dist/mobjects/graph/GraphEdge.d.ts +26 -0
- package/dist/mobjects/graph/GraphEdge.js +64 -0
- package/dist/mobjects/graph/GraphNode.d.ts +19 -0
- package/dist/mobjects/graph/GraphNode.js +63 -0
- package/dist/mobjects/graph/index.d.ts +5 -0
- package/dist/mobjects/graph/index.js +5 -0
- package/dist/mobjects/graph/layouts/circular.d.ts +8 -0
- package/dist/mobjects/graph/layouts/circular.js +23 -0
- package/dist/mobjects/graph/layouts/forceDirected.d.ts +9 -0
- package/dist/mobjects/graph/layouts/forceDirected.js +102 -0
- package/dist/mobjects/graph/layouts/index.d.ts +3 -0
- package/dist/mobjects/graph/layouts/index.js +3 -0
- package/dist/mobjects/graph/layouts/tree.d.ts +9 -0
- package/dist/mobjects/graph/layouts/tree.js +99 -0
- package/dist/mobjects/graph/types.d.ts +35 -0
- package/dist/mobjects/graph/types.js +0 -0
- package/dist/mobjects/index.d.ts +6 -0
- package/dist/mobjects/index.js +6 -0
- package/dist/mobjects/text/Glyph.d.ts +11 -0
- package/dist/mobjects/text/Glyph.js +72 -0
- package/dist/mobjects/text/Text.d.ts +19 -0
- package/dist/mobjects/text/Text.js +76 -0
- package/dist/mobjects/text/index.d.ts +4 -0
- package/dist/mobjects/text/index.js +3 -0
- package/dist/mobjects/text/types.d.ts +12 -0
- package/dist/mobjects/text/types.js +8 -0
- package/package.json +51 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { EasingFunction } from '../easing';
|
|
2
|
+
import type { Keyframe, KeyframeValue, InterpolatorFn } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Manages a sequence of keyframes for animating a single property.
|
|
5
|
+
* Keyframes are stored sorted by time and interpolated on demand.
|
|
6
|
+
*/
|
|
7
|
+
export declare class KeyframeTrack<T extends KeyframeValue = number> {
|
|
8
|
+
private keyframes;
|
|
9
|
+
private readonly interpolator;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new KeyframeTrack with the specified interpolator.
|
|
12
|
+
* Defaults to linear number interpolation.
|
|
13
|
+
*/
|
|
14
|
+
constructor(interpolator?: InterpolatorFn<T>);
|
|
15
|
+
/**
|
|
16
|
+
* Adds a keyframe at the specified normalized time.
|
|
17
|
+
* Time must be in [0, 1]. Replaces existing keyframe at same time.
|
|
18
|
+
*/
|
|
19
|
+
addKeyframe(time: number, value: T, easing?: EasingFunction): this;
|
|
20
|
+
removeKeyframe(time: number): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Gets the keyframe at the specified time.
|
|
23
|
+
* Returns undefined if no keyframe exists at that time.
|
|
24
|
+
*/
|
|
25
|
+
getKeyframe(time: number): Keyframe<T> | undefined;
|
|
26
|
+
/** All keyframes sorted by time. */
|
|
27
|
+
getKeyframes(): ReadonlyArray<Keyframe<T>>;
|
|
28
|
+
/** Interpolated value at normalized time (uses target keyframe easing). */
|
|
29
|
+
getValueAt(time: number): T;
|
|
30
|
+
getKeyframeCount(): number;
|
|
31
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { linear } from '../easing';
|
|
2
|
+
import { lerpNumber } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Manages a sequence of keyframes for animating a single property.
|
|
5
|
+
* Keyframes are stored sorted by time and interpolated on demand.
|
|
6
|
+
*/
|
|
7
|
+
export class KeyframeTrack {
|
|
8
|
+
keyframes = [];
|
|
9
|
+
interpolator;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new KeyframeTrack with the specified interpolator.
|
|
12
|
+
* Defaults to linear number interpolation.
|
|
13
|
+
*/
|
|
14
|
+
constructor(interpolator) {
|
|
15
|
+
this.interpolator = interpolator ?? lerpNumber;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Adds a keyframe at the specified normalized time.
|
|
19
|
+
* Time must be in [0, 1]. Replaces existing keyframe at same time.
|
|
20
|
+
*/
|
|
21
|
+
addKeyframe(time, value, easing) {
|
|
22
|
+
if (time < 0 || time > 1) {
|
|
23
|
+
throw new Error('Keyframe time must be in [0, 1]');
|
|
24
|
+
}
|
|
25
|
+
// Remove existing keyframe at same time
|
|
26
|
+
this.keyframes = this.keyframes.filter((kf) => kf.time !== time);
|
|
27
|
+
const keyframe = { time, value, easing };
|
|
28
|
+
this.keyframes.push(keyframe);
|
|
29
|
+
this.keyframes.sort((a, b) => a.time - b.time);
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
removeKeyframe(time) {
|
|
33
|
+
const initialLength = this.keyframes.length;
|
|
34
|
+
this.keyframes = this.keyframes.filter((kf) => kf.time !== time);
|
|
35
|
+
return this.keyframes.length < initialLength;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Gets the keyframe at the specified time.
|
|
39
|
+
* Returns undefined if no keyframe exists at that time.
|
|
40
|
+
*/
|
|
41
|
+
getKeyframe(time) {
|
|
42
|
+
return this.keyframes.find((kf) => kf.time === time);
|
|
43
|
+
}
|
|
44
|
+
/** All keyframes sorted by time. */
|
|
45
|
+
getKeyframes() {
|
|
46
|
+
return this.keyframes;
|
|
47
|
+
}
|
|
48
|
+
/** Interpolated value at normalized time (uses target keyframe easing). */
|
|
49
|
+
getValueAt(time) {
|
|
50
|
+
if (this.keyframes.length === 0) {
|
|
51
|
+
throw new Error('KeyframeTrack has no keyframes');
|
|
52
|
+
}
|
|
53
|
+
const clampedTime = Math.max(0, Math.min(1, time));
|
|
54
|
+
// Find keyframes before and after the requested time
|
|
55
|
+
let prevKeyframe;
|
|
56
|
+
let nextKeyframe;
|
|
57
|
+
for (const kf of this.keyframes) {
|
|
58
|
+
if (kf.time <= clampedTime) {
|
|
59
|
+
prevKeyframe = kf;
|
|
60
|
+
}
|
|
61
|
+
if (kf.time >= clampedTime && nextKeyframe === undefined) {
|
|
62
|
+
nextKeyframe = kf;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (prevKeyframe === undefined) {
|
|
66
|
+
return this.keyframes[0].value;
|
|
67
|
+
}
|
|
68
|
+
if (nextKeyframe === undefined) {
|
|
69
|
+
return prevKeyframe.value;
|
|
70
|
+
}
|
|
71
|
+
if (prevKeyframe === nextKeyframe) {
|
|
72
|
+
return prevKeyframe.value;
|
|
73
|
+
}
|
|
74
|
+
const span = nextKeyframe.time - prevKeyframe.time;
|
|
75
|
+
const localProgress = (clampedTime - prevKeyframe.time) / span;
|
|
76
|
+
const easing = nextKeyframe.easing ?? linear;
|
|
77
|
+
const easedProgress = easing(localProgress);
|
|
78
|
+
return this.interpolator(prevKeyframe.value, nextKeyframe.value, easedProgress);
|
|
79
|
+
}
|
|
80
|
+
getKeyframeCount() {
|
|
81
|
+
return this.keyframes.length;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { EasingFunction } from '../easing';
|
|
2
|
+
/**
|
|
3
|
+
* Supported value types for keyframe interpolation.
|
|
4
|
+
*/
|
|
5
|
+
export type KeyframeValue = number;
|
|
6
|
+
/**
|
|
7
|
+
* A single keyframe with a normalized time position [0,1] and value.
|
|
8
|
+
*/
|
|
9
|
+
export interface Keyframe<T extends KeyframeValue = KeyframeValue> {
|
|
10
|
+
/** Normalized time position in [0, 1]. */
|
|
11
|
+
readonly time: number;
|
|
12
|
+
/** The value at this keyframe. */
|
|
13
|
+
readonly value: T;
|
|
14
|
+
/** Optional easing function for interpolation TO this keyframe. */
|
|
15
|
+
readonly easing?: EasingFunction;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Interpolation function for a specific value type.
|
|
19
|
+
* Takes start value, end value, and progress [0,1], returns interpolated value.
|
|
20
|
+
*/
|
|
21
|
+
export type InterpolatorFn<T> = (start: T, end: T, progress: number) => T;
|
|
22
|
+
/**
|
|
23
|
+
* Default numeric interpolation (linear).
|
|
24
|
+
*/
|
|
25
|
+
export declare function lerpNumber(a: number, b: number, t: number): number;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { TransformativeAnimation } from '../categories';
|
|
2
|
+
import { VMobject } from '../../../mobjects/VMobject';
|
|
3
|
+
/**
|
|
4
|
+
* Animation that morphs a VMobject from its current shape to a target shape.
|
|
5
|
+
* Uses BezierPath interpolation for smooth path transitions.
|
|
6
|
+
*
|
|
7
|
+
* This is a transformative animation - the source must already be in the scene.
|
|
8
|
+
* The target VMobject is used only as a shape template and is NOT added to the scene.
|
|
9
|
+
* Source paths are captured lazily when animation becomes active.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* scene.add(circle);
|
|
13
|
+
* scene.play(new MorphTo(circle, square)); // circle morphs into square's shape
|
|
14
|
+
*/
|
|
15
|
+
export declare class MorphTo<T extends VMobject = VMobject> extends TransformativeAnimation<T> {
|
|
16
|
+
private sourcePaths;
|
|
17
|
+
private readonly targetPaths;
|
|
18
|
+
constructor(source: T, target: VMobject);
|
|
19
|
+
protected captureStartState(): void;
|
|
20
|
+
interpolate(progress: number): void;
|
|
21
|
+
private getEmptyPath;
|
|
22
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { TransformativeAnimation } from '../categories';
|
|
2
|
+
import { BezierPath } from '../../math/bezier/BezierPath';
|
|
3
|
+
/**
|
|
4
|
+
* Animation that morphs a VMobject from its current shape to a target shape.
|
|
5
|
+
* Uses BezierPath interpolation for smooth path transitions.
|
|
6
|
+
*
|
|
7
|
+
* This is a transformative animation - the source must already be in the scene.
|
|
8
|
+
* The target VMobject is used only as a shape template and is NOT added to the scene.
|
|
9
|
+
* Source paths are captured lazily when animation becomes active.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* scene.add(circle);
|
|
13
|
+
* scene.play(new MorphTo(circle, square)); // circle morphs into square's shape
|
|
14
|
+
*/
|
|
15
|
+
export class MorphTo extends TransformativeAnimation {
|
|
16
|
+
sourcePaths;
|
|
17
|
+
targetPaths;
|
|
18
|
+
constructor(source, target) {
|
|
19
|
+
super(source);
|
|
20
|
+
this.targetPaths = target.paths.map(p => p.clone());
|
|
21
|
+
}
|
|
22
|
+
captureStartState() {
|
|
23
|
+
this.sourcePaths = this.target.paths.map(p => p.clone());
|
|
24
|
+
}
|
|
25
|
+
interpolate(progress) {
|
|
26
|
+
this.ensureInitialized();
|
|
27
|
+
const maxPaths = Math.max(this.sourcePaths.length, this.targetPaths.length);
|
|
28
|
+
const newPaths = [];
|
|
29
|
+
for (let i = 0; i < maxPaths; i++) {
|
|
30
|
+
const sourcePath = this.sourcePaths[i] ?? this.getEmptyPath();
|
|
31
|
+
const targetPath = this.targetPaths[i] ?? this.getEmptyPath();
|
|
32
|
+
const interpolated = BezierPath.interpolate(sourcePath, targetPath, progress);
|
|
33
|
+
newPaths.push(interpolated);
|
|
34
|
+
}
|
|
35
|
+
this.target.paths = newPaths;
|
|
36
|
+
}
|
|
37
|
+
getEmptyPath() {
|
|
38
|
+
const path = new BezierPath();
|
|
39
|
+
path.moveTo(this.target.position);
|
|
40
|
+
return path;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { MorphTo } from './MorphTo';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { MorphTo } from './MorphTo';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { TransformativeAnimation } from '../categories';
|
|
2
|
+
import { Mobject } from '../../../mobjects/Mobject';
|
|
3
|
+
import { Vector2 } from '../../math/Vector2/Vector2';
|
|
4
|
+
/**
|
|
5
|
+
* Animation that moves a Mobject from its current position to a destination.
|
|
6
|
+
* Uses linear interpolation between start and end positions.
|
|
7
|
+
*
|
|
8
|
+
* This is a transformative animation - the target must already be in the scene.
|
|
9
|
+
* Start position is captured lazily when animation becomes active.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* scene.add(circle); // or use FadeIn first
|
|
13
|
+
* scene.play(new MoveTo(circle, 2, 0)); // Move to (2, 0)
|
|
14
|
+
*/
|
|
15
|
+
export declare class MoveTo<T extends Mobject = Mobject> extends TransformativeAnimation<T> {
|
|
16
|
+
private startPosition;
|
|
17
|
+
private readonly endPosition;
|
|
18
|
+
constructor(target: T, destination: Vector2);
|
|
19
|
+
constructor(target: T, x: number, y: number);
|
|
20
|
+
protected captureStartState(): void;
|
|
21
|
+
interpolate(progress: number): void;
|
|
22
|
+
/** Returns the target position of the move animation. */
|
|
23
|
+
getDestination(): Vector2;
|
|
24
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { TransformativeAnimation } from '../categories';
|
|
2
|
+
import { Vector2 } from '../../math/Vector2/Vector2';
|
|
3
|
+
/**
|
|
4
|
+
* Animation that moves a Mobject from its current position to a destination.
|
|
5
|
+
* Uses linear interpolation between start and end positions.
|
|
6
|
+
*
|
|
7
|
+
* This is a transformative animation - the target must already be in the scene.
|
|
8
|
+
* Start position is captured lazily when animation becomes active.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* scene.add(circle); // or use FadeIn first
|
|
12
|
+
* scene.play(new MoveTo(circle, 2, 0)); // Move to (2, 0)
|
|
13
|
+
*/
|
|
14
|
+
export class MoveTo extends TransformativeAnimation {
|
|
15
|
+
startPosition;
|
|
16
|
+
endPosition;
|
|
17
|
+
constructor(target, xOrDestination, y) {
|
|
18
|
+
super(target);
|
|
19
|
+
if (xOrDestination instanceof Vector2) {
|
|
20
|
+
this.endPosition = xOrDestination;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
this.endPosition = new Vector2(xOrDestination, y ?? 0);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
captureStartState() {
|
|
27
|
+
this.startPosition = this.target.position;
|
|
28
|
+
}
|
|
29
|
+
interpolate(progress) {
|
|
30
|
+
this.ensureInitialized();
|
|
31
|
+
const newPosition = this.startPosition.lerp(this.endPosition, progress);
|
|
32
|
+
this.target.pos(newPosition.x, newPosition.y);
|
|
33
|
+
}
|
|
34
|
+
/** Returns the target position of the move animation. */
|
|
35
|
+
getDestination() {
|
|
36
|
+
return this.endPosition;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TransformativeAnimation } from '../categories';
|
|
2
|
+
import type { Mobject } from '../../../mobjects/Mobject';
|
|
3
|
+
/**
|
|
4
|
+
* Animation that rotates a Mobject by a specified angle.
|
|
5
|
+
* Uses linear interpolation between start and end rotation.
|
|
6
|
+
*
|
|
7
|
+
* This is a transformative animation - the target must already be in the scene.
|
|
8
|
+
* Start rotation is captured lazily when animation becomes active.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* scene.add(square);
|
|
12
|
+
* scene.play(new Rotate(square, Math.PI / 4)); // Rotate 45 degrees
|
|
13
|
+
*/
|
|
14
|
+
export declare class Rotate<T extends Mobject = Mobject> extends TransformativeAnimation<T> {
|
|
15
|
+
private startRotation;
|
|
16
|
+
private endRotation;
|
|
17
|
+
private readonly angle;
|
|
18
|
+
constructor(target: T, angle: number);
|
|
19
|
+
protected captureStartState(): void;
|
|
20
|
+
interpolate(progress: number): void;
|
|
21
|
+
/** Returns the total rotation angle in radians. */
|
|
22
|
+
getAngle(): number;
|
|
23
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { TransformativeAnimation } from '../categories';
|
|
2
|
+
/**
|
|
3
|
+
* Animation that rotates a Mobject by a specified angle.
|
|
4
|
+
* Uses linear interpolation between start and end rotation.
|
|
5
|
+
*
|
|
6
|
+
* This is a transformative animation - the target must already be in the scene.
|
|
7
|
+
* Start rotation is captured lazily when animation becomes active.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* scene.add(square);
|
|
11
|
+
* scene.play(new Rotate(square, Math.PI / 4)); // Rotate 45 degrees
|
|
12
|
+
*/
|
|
13
|
+
export class Rotate extends TransformativeAnimation {
|
|
14
|
+
startRotation;
|
|
15
|
+
endRotation;
|
|
16
|
+
angle;
|
|
17
|
+
constructor(target, angle) {
|
|
18
|
+
super(target);
|
|
19
|
+
this.angle = angle;
|
|
20
|
+
}
|
|
21
|
+
captureStartState() {
|
|
22
|
+
this.startRotation = this.target.rotation;
|
|
23
|
+
this.endRotation = this.startRotation + this.angle;
|
|
24
|
+
}
|
|
25
|
+
interpolate(progress) {
|
|
26
|
+
this.ensureInitialized();
|
|
27
|
+
const newRotation = this.startRotation + (this.endRotation - this.startRotation) * progress;
|
|
28
|
+
this.target.setRotation(newRotation);
|
|
29
|
+
}
|
|
30
|
+
/** Returns the total rotation angle in radians. */
|
|
31
|
+
getAngle() {
|
|
32
|
+
return this.angle;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TransformativeAnimation } from '../categories';
|
|
2
|
+
import { Mobject } from '../../../mobjects/Mobject';
|
|
3
|
+
/**
|
|
4
|
+
* Animation that scales a Mobject to a target scale factor.
|
|
5
|
+
* Uses linear interpolation between start and end scale.
|
|
6
|
+
*
|
|
7
|
+
* This is a transformative animation - the target must already be in the scene.
|
|
8
|
+
* Start scale is captured lazily when animation becomes active.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* scene.add(circle);
|
|
12
|
+
* scene.play(new Scale(circle, 2)); // Scale to 2x
|
|
13
|
+
*/
|
|
14
|
+
export declare class Scale<T extends Mobject = Mobject> extends TransformativeAnimation<T> {
|
|
15
|
+
private startScale;
|
|
16
|
+
private readonly endScale;
|
|
17
|
+
constructor(target: T, factor: number);
|
|
18
|
+
constructor(target: T, factorX: number, factorY: number);
|
|
19
|
+
protected captureStartState(): void;
|
|
20
|
+
interpolate(progress: number): void;
|
|
21
|
+
/** Returns the scale factor. */
|
|
22
|
+
getFactor(): number;
|
|
23
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { TransformativeAnimation } from '../categories';
|
|
2
|
+
import { Vector2 } from '../../math/Vector2/Vector2';
|
|
3
|
+
/**
|
|
4
|
+
* Animation that scales a Mobject to a target scale factor.
|
|
5
|
+
* Uses linear interpolation between start and end scale.
|
|
6
|
+
*
|
|
7
|
+
* This is a transformative animation - the target must already be in the scene.
|
|
8
|
+
* Start scale is captured lazily when animation becomes active.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* scene.add(circle);
|
|
12
|
+
* scene.play(new Scale(circle, 2)); // Scale to 2x
|
|
13
|
+
*/
|
|
14
|
+
export class Scale extends TransformativeAnimation {
|
|
15
|
+
startScale;
|
|
16
|
+
endScale;
|
|
17
|
+
constructor(target, factorX, factorY) {
|
|
18
|
+
super(target);
|
|
19
|
+
const endX = factorX;
|
|
20
|
+
const endY = factorY ?? factorX;
|
|
21
|
+
this.endScale = new Vector2(endX, endY);
|
|
22
|
+
}
|
|
23
|
+
captureStartState() {
|
|
24
|
+
this.startScale = this.target.scale;
|
|
25
|
+
}
|
|
26
|
+
interpolate(progress) {
|
|
27
|
+
this.ensureInitialized();
|
|
28
|
+
const newScale = this.startScale.lerp(this.endScale, progress);
|
|
29
|
+
this.target.setScale(newScale.x, newScale.y);
|
|
30
|
+
}
|
|
31
|
+
/** Returns the scale factor. */
|
|
32
|
+
getFactor() {
|
|
33
|
+
return this.endScale.x;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { EasingFunction } from './easing';
|
|
2
|
+
import type { Animation } from './Animation';
|
|
3
|
+
import type { Mobject } from '../../mobjects/Mobject';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for animations.
|
|
6
|
+
*/
|
|
7
|
+
export interface AnimationConfig {
|
|
8
|
+
/** Duration of the animation in seconds. Default: 1 */
|
|
9
|
+
readonly durationSeconds: number;
|
|
10
|
+
/** Easing function to apply. Default: smooth */
|
|
11
|
+
readonly easing: EasingFunction;
|
|
12
|
+
/** Delay before animation starts in seconds. Default: 0 */
|
|
13
|
+
readonly delaySeconds: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Animation lifecycle category determines how Scene.play() handles the target.
|
|
17
|
+
* - 'introductory': Auto-registers target with scene (FadeIn, Create, Draw, Write)
|
|
18
|
+
* - 'transformative': Requires target to already be in scene (MoveTo, Rotate, Scale)
|
|
19
|
+
* - 'exit': Requires target in scene, may auto-remove after (FadeOut)
|
|
20
|
+
*/
|
|
21
|
+
export type AnimationLifecycle = 'introductory' | 'transformative' | 'exit';
|
|
22
|
+
/**
|
|
23
|
+
* Configuration for a queued animation in the fluent API.
|
|
24
|
+
*/
|
|
25
|
+
export interface FluentConfig {
|
|
26
|
+
durationSeconds: number;
|
|
27
|
+
easing?: EasingFunction;
|
|
28
|
+
delaySeconds?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Factory function that creates an Animation for a given target.
|
|
32
|
+
*/
|
|
33
|
+
export type AnimationFactory = (target: Mobject) => Animation<Mobject>;
|
|
34
|
+
/**
|
|
35
|
+
* A queued animation descriptor storing the factory and configuration.
|
|
36
|
+
*/
|
|
37
|
+
export interface QueuedAnimation {
|
|
38
|
+
factory: AnimationFactory;
|
|
39
|
+
config: FluentConfig;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A pre-built animation that's already configured (e.g., from parallel()).
|
|
43
|
+
*/
|
|
44
|
+
export interface QueuedPrebuilt {
|
|
45
|
+
animation: Animation<Mobject>;
|
|
46
|
+
}
|
|
47
|
+
/** Union type for queue entries */
|
|
48
|
+
export type QueueEntry = QueuedAnimation | QueuedPrebuilt;
|
|
49
|
+
/** Type guard to check if entry is a pre-built animation */
|
|
50
|
+
export declare function isPrebuilt(entry: QueueEntry): entry is QueuedPrebuilt;
|
|
51
|
+
/** Default animation duration in seconds. */
|
|
52
|
+
export declare const DEFAULT_DURATION = 1;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Vector2 } from '../math/Vector2/Vector2';
|
|
2
|
+
import { Matrix3x3 } from '../math/matrix/Matrix3x3';
|
|
3
|
+
import { CameraFrame } from './CameraFrame';
|
|
4
|
+
import { type CameraConfig } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Camera manages the view into the scene.
|
|
7
|
+
* Uses CameraFrame (a Mobject) to store transform state, enabling camera animations.
|
|
8
|
+
*
|
|
9
|
+
* The Camera provides both instant manipulation methods (panTo, zoomTo) and
|
|
10
|
+
* access to the CameraFrame for fluent animation APIs.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Instant camera manipulation
|
|
14
|
+
* camera.zoomTo(2);
|
|
15
|
+
* camera.panTo(new Vector2(5, 3));
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Animated camera movement via frame
|
|
19
|
+
* this.play(this.frame.zoomIn(2).duration(1));
|
|
20
|
+
* this.play(this.frame.centerOn(circle).duration(0.5));
|
|
21
|
+
*/
|
|
22
|
+
export declare class Camera {
|
|
23
|
+
private readonly config;
|
|
24
|
+
/** The CameraFrame that stores the camera's transform state. Use this for animations. */
|
|
25
|
+
readonly frame: CameraFrame;
|
|
26
|
+
/**
|
|
27
|
+
* Creates a new Camera with the specified viewport dimensions.
|
|
28
|
+
*
|
|
29
|
+
* @param config - Configuration options
|
|
30
|
+
* @param config.pixelWidth - Width of the viewport in pixels (default: 1920)
|
|
31
|
+
* @param config.pixelHeight - Height of the viewport in pixels (default: 1080)
|
|
32
|
+
*/
|
|
33
|
+
constructor(config?: CameraConfig);
|
|
34
|
+
get frameHeight(): number;
|
|
35
|
+
get frameWidth(): number;
|
|
36
|
+
get frameYRadius(): number;
|
|
37
|
+
get frameXRadius(): number;
|
|
38
|
+
get pixelWidth(): number;
|
|
39
|
+
get pixelHeight(): number;
|
|
40
|
+
get position(): Vector2;
|
|
41
|
+
get zoom(): number;
|
|
42
|
+
get rotation(): number;
|
|
43
|
+
pan(delta: Vector2): this;
|
|
44
|
+
panTo(position: Vector2): this;
|
|
45
|
+
zoomTo(level: number): this;
|
|
46
|
+
rotateTo(angle: number): this;
|
|
47
|
+
getViewMatrix(): Matrix3x3;
|
|
48
|
+
/**
|
|
49
|
+
* Transforms a world-space position to screen-space (pixel) coordinates.
|
|
50
|
+
*
|
|
51
|
+
* Screen coordinates have origin at top-left, with x increasing right
|
|
52
|
+
* and y increasing downward.
|
|
53
|
+
*
|
|
54
|
+
* @param pos - Position in world coordinates
|
|
55
|
+
* @returns Position in screen coordinates (pixels)
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* const screenPos = camera.worldToScreen(circle.position);
|
|
59
|
+
* console.log(`Circle is at pixel (${screenPos.x}, ${screenPos.y})`);
|
|
60
|
+
*/
|
|
61
|
+
worldToScreen(pos: Vector2): Vector2;
|
|
62
|
+
/**
|
|
63
|
+
* Transforms a screen-space (pixel) position to world coordinates.
|
|
64
|
+
* This is the inverse of worldToScreen.
|
|
65
|
+
*
|
|
66
|
+
* @param pos - Position in screen coordinates (pixels, origin at top-left)
|
|
67
|
+
* @returns Position in world coordinates
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* // Convert a mouse click position to world coordinates
|
|
71
|
+
* const worldPos = camera.screenToWorld(new Vector2(mouseX, mouseY));
|
|
72
|
+
*/
|
|
73
|
+
screenToWorld(pos: Vector2): Vector2;
|
|
74
|
+
/**
|
|
75
|
+
* Checks if a world-space position is currently visible within the camera frame.
|
|
76
|
+
*
|
|
77
|
+
* @param pos - Position in world coordinates to check
|
|
78
|
+
* @returns True if the position is within the visible frame bounds
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* if (camera.isInView(object.position)) {
|
|
82
|
+
* console.log('Object is visible');
|
|
83
|
+
* }
|
|
84
|
+
*/
|
|
85
|
+
isInView(pos: Vector2): boolean;
|
|
86
|
+
reset(): this;
|
|
87
|
+
}
|