@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,153 @@
|
|
|
1
|
+
import { Vector2 } from '../Vector2/Vector2';
|
|
2
|
+
import { evaluateQuadratic, evaluateCubic } from './evaluators';
|
|
3
|
+
import { evaluateQuadraticDerivative, evaluateCubicDerivative } from './evaluators';
|
|
4
|
+
import { getQuadraticLength, getCubicLength } from './length';
|
|
5
|
+
export function getPathLength(commands) {
|
|
6
|
+
let length = 0;
|
|
7
|
+
let cursor = new Vector2(0, 0);
|
|
8
|
+
let subpathStart = new Vector2(0, 0);
|
|
9
|
+
for (const cmd of commands) {
|
|
10
|
+
switch (cmd.type) {
|
|
11
|
+
case 'Move':
|
|
12
|
+
cursor = cmd.end;
|
|
13
|
+
subpathStart = cmd.end;
|
|
14
|
+
break;
|
|
15
|
+
case 'Line':
|
|
16
|
+
length += cursor.subtract(cmd.end).length();
|
|
17
|
+
cursor = cmd.end;
|
|
18
|
+
break;
|
|
19
|
+
case 'Quadratic':
|
|
20
|
+
if (cmd.control1) {
|
|
21
|
+
length += getQuadraticLength(cursor, cmd.control1, cmd.end);
|
|
22
|
+
}
|
|
23
|
+
cursor = cmd.end;
|
|
24
|
+
break;
|
|
25
|
+
case 'Cubic':
|
|
26
|
+
if (cmd.control1 && cmd.control2) {
|
|
27
|
+
length += getCubicLength(cursor, cmd.control1, cmd.control2, cmd.end);
|
|
28
|
+
}
|
|
29
|
+
cursor = cmd.end;
|
|
30
|
+
break;
|
|
31
|
+
case 'Close':
|
|
32
|
+
length += cursor.subtract(subpathStart).length();
|
|
33
|
+
cursor = subpathStart;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return length;
|
|
38
|
+
}
|
|
39
|
+
/** Point on the path at normalized position t (0-1). */
|
|
40
|
+
export function getPointAtPath(commands, t) {
|
|
41
|
+
const totalLength = getPathLength(commands);
|
|
42
|
+
if (totalLength === 0) {
|
|
43
|
+
return commands.length > 0 ? commands[commands.length - 1].end : Vector2.ZERO;
|
|
44
|
+
}
|
|
45
|
+
t = Math.max(0, Math.min(1, t));
|
|
46
|
+
const targetDistance = t * totalLength;
|
|
47
|
+
let currentDistance = 0;
|
|
48
|
+
let cursor = new Vector2(0, 0);
|
|
49
|
+
let subpathStart = new Vector2(0, 0);
|
|
50
|
+
for (const cmd of commands) {
|
|
51
|
+
let segmentLength = 0;
|
|
52
|
+
switch (cmd.type) {
|
|
53
|
+
case 'Move':
|
|
54
|
+
cursor = cmd.end;
|
|
55
|
+
subpathStart = cmd.end;
|
|
56
|
+
break;
|
|
57
|
+
case 'Line':
|
|
58
|
+
segmentLength = cursor.subtract(cmd.end).length();
|
|
59
|
+
if (currentDistance + segmentLength >= targetDistance) {
|
|
60
|
+
const localT = (targetDistance - currentDistance) / segmentLength;
|
|
61
|
+
return cursor.lerp(cmd.end, localT);
|
|
62
|
+
}
|
|
63
|
+
cursor = cmd.end;
|
|
64
|
+
break;
|
|
65
|
+
case 'Quadratic':
|
|
66
|
+
if (cmd.control1) {
|
|
67
|
+
segmentLength = getQuadraticLength(cursor, cmd.control1, cmd.end);
|
|
68
|
+
if (currentDistance + segmentLength >= targetDistance) {
|
|
69
|
+
const localT = (targetDistance - currentDistance) / segmentLength;
|
|
70
|
+
return evaluateQuadratic(cursor, cmd.control1, cmd.end, localT);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
cursor = cmd.end;
|
|
74
|
+
break;
|
|
75
|
+
case 'Cubic':
|
|
76
|
+
if (cmd.control1 && cmd.control2) {
|
|
77
|
+
segmentLength = getCubicLength(cursor, cmd.control1, cmd.control2, cmd.end);
|
|
78
|
+
if (currentDistance + segmentLength >= targetDistance) {
|
|
79
|
+
const localT = (targetDistance - currentDistance) / segmentLength;
|
|
80
|
+
return evaluateCubic(cursor, cmd.control1, cmd.control2, cmd.end, localT);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
cursor = cmd.end;
|
|
84
|
+
break;
|
|
85
|
+
case 'Close':
|
|
86
|
+
segmentLength = cursor.subtract(subpathStart).length();
|
|
87
|
+
if (currentDistance + segmentLength >= targetDistance) {
|
|
88
|
+
const localT = (targetDistance - currentDistance) / segmentLength;
|
|
89
|
+
return cursor.lerp(subpathStart, localT);
|
|
90
|
+
}
|
|
91
|
+
cursor = subpathStart;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
currentDistance += segmentLength;
|
|
95
|
+
}
|
|
96
|
+
return cursor;
|
|
97
|
+
}
|
|
98
|
+
/** Tangent vector on the path at normalized position t (0-1). */
|
|
99
|
+
export function getTangentAtPath(commands, t) {
|
|
100
|
+
const totalLength = getPathLength(commands);
|
|
101
|
+
if (totalLength === 0)
|
|
102
|
+
return Vector2.RIGHT;
|
|
103
|
+
t = Math.max(0, Math.min(1, t));
|
|
104
|
+
const targetDistance = t * totalLength;
|
|
105
|
+
let currentDistance = 0;
|
|
106
|
+
let cursor = new Vector2(0, 0);
|
|
107
|
+
let subpathStart = new Vector2(0, 0);
|
|
108
|
+
for (const cmd of commands) {
|
|
109
|
+
let segmentLength = 0;
|
|
110
|
+
switch (cmd.type) {
|
|
111
|
+
case 'Move':
|
|
112
|
+
cursor = cmd.end;
|
|
113
|
+
subpathStart = cmd.end;
|
|
114
|
+
break;
|
|
115
|
+
case 'Line':
|
|
116
|
+
segmentLength = cursor.subtract(cmd.end).length();
|
|
117
|
+
if (currentDistance + segmentLength >= targetDistance) {
|
|
118
|
+
return cmd.end.subtract(cursor).normalize();
|
|
119
|
+
}
|
|
120
|
+
cursor = cmd.end;
|
|
121
|
+
break;
|
|
122
|
+
case 'Quadratic':
|
|
123
|
+
if (cmd.control1) {
|
|
124
|
+
segmentLength = getQuadraticLength(cursor, cmd.control1, cmd.end);
|
|
125
|
+
if (currentDistance + segmentLength >= targetDistance) {
|
|
126
|
+
const localT = (targetDistance - currentDistance) / segmentLength;
|
|
127
|
+
return evaluateQuadraticDerivative(cursor, cmd.control1, cmd.end, localT).normalize();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
cursor = cmd.end;
|
|
131
|
+
break;
|
|
132
|
+
case 'Cubic':
|
|
133
|
+
if (cmd.control1 && cmd.control2) {
|
|
134
|
+
segmentLength = getCubicLength(cursor, cmd.control1, cmd.control2, cmd.end);
|
|
135
|
+
if (currentDistance + segmentLength >= targetDistance) {
|
|
136
|
+
const localT = (targetDistance - currentDistance) / segmentLength;
|
|
137
|
+
return evaluateCubicDerivative(cursor, cmd.control1, cmd.control2, cmd.end, localT).normalize();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
cursor = cmd.end;
|
|
141
|
+
break;
|
|
142
|
+
case 'Close':
|
|
143
|
+
segmentLength = cursor.subtract(subpathStart).length();
|
|
144
|
+
if (currentDistance + segmentLength >= targetDistance) {
|
|
145
|
+
return subpathStart.subtract(cursor).normalize();
|
|
146
|
+
}
|
|
147
|
+
cursor = subpathStart;
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
currentDistance += segmentLength;
|
|
151
|
+
}
|
|
152
|
+
return Vector2.RIGHT;
|
|
153
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Vector2 } from '../Vector2/Vector2';
|
|
2
|
+
/**
|
|
3
|
+
* Result of splitting a cubic Bezier curve at parameter t.
|
|
4
|
+
*/
|
|
5
|
+
export interface CubicSegment {
|
|
6
|
+
start: Vector2;
|
|
7
|
+
control1: Vector2;
|
|
8
|
+
control2: Vector2;
|
|
9
|
+
end: Vector2;
|
|
10
|
+
}
|
|
11
|
+
/** Splits a cubic Bezier curve at t using de Casteljau's algorithm into two segments. */
|
|
12
|
+
export declare function splitCubicAt(p0: Vector2, p1: Vector2, p2: Vector2, p3: Vector2, t: number): [CubicSegment, CubicSegment];
|
|
13
|
+
/** Splits a quadratic Bezier curve at t into two segments. */
|
|
14
|
+
export interface QuadraticSegment {
|
|
15
|
+
start: Vector2;
|
|
16
|
+
control: Vector2;
|
|
17
|
+
end: Vector2;
|
|
18
|
+
}
|
|
19
|
+
export declare function splitQuadraticAt(p0: Vector2, p1: Vector2, p2: Vector2, t: number): [QuadraticSegment, QuadraticSegment];
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Splits a cubic Bezier curve at t using de Casteljau's algorithm into two segments. */
|
|
2
|
+
export function splitCubicAt(p0, p1, p2, p3, t) {
|
|
3
|
+
// de Casteljau's algorithm - first level
|
|
4
|
+
const p01 = p0.lerp(p1, t);
|
|
5
|
+
const p12 = p1.lerp(p2, t);
|
|
6
|
+
const p23 = p2.lerp(p3, t);
|
|
7
|
+
// Second level
|
|
8
|
+
const p012 = p01.lerp(p12, t);
|
|
9
|
+
const p123 = p12.lerp(p23, t);
|
|
10
|
+
// Third level - the split point
|
|
11
|
+
const p0123 = p012.lerp(p123, t);
|
|
12
|
+
// First segment: [0, t]
|
|
13
|
+
const first = {
|
|
14
|
+
start: p0,
|
|
15
|
+
control1: p01,
|
|
16
|
+
control2: p012,
|
|
17
|
+
end: p0123,
|
|
18
|
+
};
|
|
19
|
+
// Second segment: [t, 1]
|
|
20
|
+
const second = {
|
|
21
|
+
start: p0123,
|
|
22
|
+
control1: p123,
|
|
23
|
+
control2: p23,
|
|
24
|
+
end: p3,
|
|
25
|
+
};
|
|
26
|
+
return [first, second];
|
|
27
|
+
}
|
|
28
|
+
export function splitQuadraticAt(p0, p1, p2, t) {
|
|
29
|
+
// de Casteljau for quadratic
|
|
30
|
+
const p01 = p0.lerp(p1, t);
|
|
31
|
+
const p12 = p1.lerp(p2, t);
|
|
32
|
+
const p012 = p01.lerp(p12, t);
|
|
33
|
+
const first = {
|
|
34
|
+
start: p0,
|
|
35
|
+
control: p01,
|
|
36
|
+
end: p012,
|
|
37
|
+
};
|
|
38
|
+
const second = {
|
|
39
|
+
start: p012,
|
|
40
|
+
control: p12,
|
|
41
|
+
end: p2,
|
|
42
|
+
};
|
|
43
|
+
return [first, second];
|
|
44
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A class representing a color with Red, Green, Blue, and Alpha components.
|
|
3
|
+
* RGB values are in the range [0, 255].
|
|
4
|
+
* Alpha value is in the range [0, 1].
|
|
5
|
+
*/
|
|
6
|
+
export declare class Color {
|
|
7
|
+
readonly r: number;
|
|
8
|
+
readonly g: number;
|
|
9
|
+
readonly b: number;
|
|
10
|
+
readonly a: number;
|
|
11
|
+
constructor(r: number, g: number, b: number, a?: number);
|
|
12
|
+
/**
|
|
13
|
+
* Creates a Color from a hex string.
|
|
14
|
+
* Supports formats: #RRGGBB, #RGB, #RRGGBBAA, #RGBA.
|
|
15
|
+
*/
|
|
16
|
+
static fromHex(hex: string): Color;
|
|
17
|
+
static fromHSL(h: number, s: number, l: number, a?: number): Color;
|
|
18
|
+
toHex(): string;
|
|
19
|
+
toRGBA(): string;
|
|
20
|
+
lerp(other: Color, t: number): Color;
|
|
21
|
+
static readonly WHITE: Color;
|
|
22
|
+
static readonly BLACK: Color;
|
|
23
|
+
static readonly RED: Color;
|
|
24
|
+
static readonly GREEN: Color;
|
|
25
|
+
static readonly BLUE: Color;
|
|
26
|
+
static readonly YELLOW: Color;
|
|
27
|
+
static readonly TRANSPARENT: Color;
|
|
28
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { parseHex, hslToRgb } from './conversions';
|
|
2
|
+
/**
|
|
3
|
+
* A class representing a color with Red, Green, Blue, and Alpha components.
|
|
4
|
+
* RGB values are in the range [0, 255].
|
|
5
|
+
* Alpha value is in the range [0, 1].
|
|
6
|
+
*/
|
|
7
|
+
export class Color {
|
|
8
|
+
r;
|
|
9
|
+
g;
|
|
10
|
+
b;
|
|
11
|
+
a;
|
|
12
|
+
constructor(r, g, b, a = 1.0) {
|
|
13
|
+
this.r = Math.max(0, Math.min(255, r));
|
|
14
|
+
this.g = Math.max(0, Math.min(255, g));
|
|
15
|
+
this.b = Math.max(0, Math.min(255, b));
|
|
16
|
+
this.a = Math.max(0, Math.min(1, a));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Creates a Color from a hex string.
|
|
20
|
+
* Supports formats: #RRGGBB, #RGB, #RRGGBBAA, #RGBA.
|
|
21
|
+
*/
|
|
22
|
+
static fromHex(hex) {
|
|
23
|
+
const { r, g, b, a } = parseHex(hex);
|
|
24
|
+
return new Color(r, g, b, a);
|
|
25
|
+
}
|
|
26
|
+
static fromHSL(h, s, l, a = 1.0) {
|
|
27
|
+
const rgb = hslToRgb(h, s, l, a);
|
|
28
|
+
return new Color(rgb.r, rgb.g, rgb.b, rgb.a);
|
|
29
|
+
}
|
|
30
|
+
toHex() {
|
|
31
|
+
const r = Math.round(this.r).toString(16).padStart(2, '0');
|
|
32
|
+
const g = Math.round(this.g).toString(16).padStart(2, '0');
|
|
33
|
+
const b = Math.round(this.b).toString(16).padStart(2, '0');
|
|
34
|
+
if (this.a >= 0.999) {
|
|
35
|
+
return `#${r}${g}${b}`;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const a = Math.round(this.a * 255).toString(16).padStart(2, '0');
|
|
39
|
+
return `#${r}${g}${b}${a}`;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
toRGBA() {
|
|
43
|
+
return `rgba(${Math.round(this.r)}, ${Math.round(this.g)}, ${Math.round(this.b)}, ${this.a})`;
|
|
44
|
+
}
|
|
45
|
+
lerp(other, t) {
|
|
46
|
+
t = Math.max(0, Math.min(1, t));
|
|
47
|
+
const r = this.r + (other.r - this.r) * t;
|
|
48
|
+
const g = this.g + (other.g - this.g) * t;
|
|
49
|
+
const b = this.b + (other.b - this.b) * t;
|
|
50
|
+
const a = this.a + (other.a - this.a) * t;
|
|
51
|
+
return new Color(r, g, b, a);
|
|
52
|
+
}
|
|
53
|
+
static WHITE = new Color(255, 255, 255);
|
|
54
|
+
static BLACK = new Color(0, 0, 0);
|
|
55
|
+
static RED = new Color(255, 0, 0);
|
|
56
|
+
static GREEN = new Color(0, 255, 0);
|
|
57
|
+
static BLUE = new Color(0, 0, 255);
|
|
58
|
+
static YELLOW = new Color(255, 255, 0);
|
|
59
|
+
static TRANSPARENT = new Color(0, 0, 0, 0);
|
|
60
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a Color from a hex string.
|
|
3
|
+
* Supports formats: #RRGGBB, #RGB, #RRGGBBAA, #RGBA.
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseHex(hex: string): {
|
|
6
|
+
r: number;
|
|
7
|
+
g: number;
|
|
8
|
+
b: number;
|
|
9
|
+
a: number;
|
|
10
|
+
};
|
|
11
|
+
/** Converts HSL values to RGB. */
|
|
12
|
+
export declare function hslToRgb(h: number, s: number, l: number, a?: number): {
|
|
13
|
+
r: number;
|
|
14
|
+
g: number;
|
|
15
|
+
b: number;
|
|
16
|
+
a: number;
|
|
17
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a Color from a hex string.
|
|
3
|
+
* Supports formats: #RRGGBB, #RGB, #RRGGBBAA, #RGBA.
|
|
4
|
+
*/
|
|
5
|
+
export function parseHex(hex) {
|
|
6
|
+
hex = hex.replace(/^#/, '');
|
|
7
|
+
let r = 0;
|
|
8
|
+
let g = 0;
|
|
9
|
+
let b = 0;
|
|
10
|
+
let a = 1;
|
|
11
|
+
if (hex.length === 3) {
|
|
12
|
+
// #RGB
|
|
13
|
+
const rHex = hex[0] || '';
|
|
14
|
+
const gHex = hex[1] || '';
|
|
15
|
+
const bHex = hex[2] || '';
|
|
16
|
+
r = parseInt(rHex + rHex, 16);
|
|
17
|
+
g = parseInt(gHex + gHex, 16);
|
|
18
|
+
b = parseInt(bHex + bHex, 16);
|
|
19
|
+
}
|
|
20
|
+
else if (hex.length === 4) {
|
|
21
|
+
// #RGBA
|
|
22
|
+
const rHex = hex[0] || '';
|
|
23
|
+
const gHex = hex[1] || '';
|
|
24
|
+
const bHex = hex[2] || '';
|
|
25
|
+
const aHex = hex[3] || '';
|
|
26
|
+
r = parseInt(rHex + rHex, 16);
|
|
27
|
+
g = parseInt(gHex + gHex, 16);
|
|
28
|
+
b = parseInt(bHex + bHex, 16);
|
|
29
|
+
a = parseInt(aHex + aHex, 16) / 255;
|
|
30
|
+
}
|
|
31
|
+
else if (hex.length === 6) {
|
|
32
|
+
// #RRGGBB
|
|
33
|
+
r = parseInt(hex.substring(0, 2), 16);
|
|
34
|
+
g = parseInt(hex.substring(2, 4), 16);
|
|
35
|
+
b = parseInt(hex.substring(4, 6), 16);
|
|
36
|
+
}
|
|
37
|
+
else if (hex.length === 8) {
|
|
38
|
+
// #RRGGBBAA
|
|
39
|
+
r = parseInt(hex.substring(0, 2), 16);
|
|
40
|
+
g = parseInt(hex.substring(2, 4), 16);
|
|
41
|
+
b = parseInt(hex.substring(4, 6), 16);
|
|
42
|
+
a = parseInt(hex.substring(6, 8), 16) / 255;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
throw new Error(`Invalid hex string: ${hex}`);
|
|
46
|
+
}
|
|
47
|
+
if (isNaN(r) || isNaN(g) || isNaN(b) || isNaN(a)) {
|
|
48
|
+
throw new Error(`Invalid hex string: ${hex}`);
|
|
49
|
+
}
|
|
50
|
+
return { r, g, b, a };
|
|
51
|
+
}
|
|
52
|
+
/** Converts HSL values to RGB. */
|
|
53
|
+
export function hslToRgb(h, s, l, a = 1.0) {
|
|
54
|
+
h = h % 360;
|
|
55
|
+
if (h < 0)
|
|
56
|
+
h += 360;
|
|
57
|
+
s = Math.max(0, Math.min(1, s));
|
|
58
|
+
l = Math.max(0, Math.min(1, l));
|
|
59
|
+
a = Math.max(0, Math.min(1, a));
|
|
60
|
+
const c = (1 - Math.abs(2 * l - 1)) * s;
|
|
61
|
+
const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
|
|
62
|
+
const m = l - c / 2;
|
|
63
|
+
let rPrime = 0;
|
|
64
|
+
let gPrime = 0;
|
|
65
|
+
let bPrime = 0;
|
|
66
|
+
if (0 <= h && h < 60) {
|
|
67
|
+
rPrime = c;
|
|
68
|
+
gPrime = x;
|
|
69
|
+
bPrime = 0;
|
|
70
|
+
}
|
|
71
|
+
else if (60 <= h && h < 120) {
|
|
72
|
+
rPrime = x;
|
|
73
|
+
gPrime = c;
|
|
74
|
+
bPrime = 0;
|
|
75
|
+
}
|
|
76
|
+
else if (120 <= h && h < 180) {
|
|
77
|
+
rPrime = 0;
|
|
78
|
+
gPrime = c;
|
|
79
|
+
bPrime = x;
|
|
80
|
+
}
|
|
81
|
+
else if (180 <= h && h < 240) {
|
|
82
|
+
rPrime = 0;
|
|
83
|
+
gPrime = x;
|
|
84
|
+
bPrime = c;
|
|
85
|
+
}
|
|
86
|
+
else if (240 <= h && h < 300) {
|
|
87
|
+
rPrime = x;
|
|
88
|
+
gPrime = 0;
|
|
89
|
+
bPrime = c;
|
|
90
|
+
}
|
|
91
|
+
else if (300 <= h && h < 360) {
|
|
92
|
+
rPrime = c;
|
|
93
|
+
gPrime = 0;
|
|
94
|
+
bPrime = x;
|
|
95
|
+
}
|
|
96
|
+
const r = Math.round((rPrime + m) * 255);
|
|
97
|
+
const g = Math.round((gPrime + m) * 255);
|
|
98
|
+
const b = Math.round((bPrime + m) * 255);
|
|
99
|
+
return { r, g, b, a };
|
|
100
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Vector2 } from '../Vector2/Vector2';
|
|
2
|
+
/**
|
|
3
|
+
* A 3x3 matrix class for 2D affine transformations.
|
|
4
|
+
* Stored in row-major order:
|
|
5
|
+
* [ 0 1 2 ]
|
|
6
|
+
* [ 3 4 5 ]
|
|
7
|
+
* [ 6 7 8 ]
|
|
8
|
+
*/
|
|
9
|
+
export declare class Matrix3x3 {
|
|
10
|
+
readonly values: Float32Array;
|
|
11
|
+
constructor(values: number[] | Float32Array);
|
|
12
|
+
multiply(other: Matrix3x3): Matrix3x3;
|
|
13
|
+
/** Transforms a Vector2 point (assumes z=1). */
|
|
14
|
+
transformPoint(point: Vector2): Vector2;
|
|
15
|
+
/** @throws Error if the matrix is not invertible. */
|
|
16
|
+
inverse(): Matrix3x3;
|
|
17
|
+
static identity(): Matrix3x3;
|
|
18
|
+
static translation(tx: number, ty: number): Matrix3x3;
|
|
19
|
+
static rotation(angle: number): Matrix3x3;
|
|
20
|
+
static scale(sx: number, sy: number): Matrix3x3;
|
|
21
|
+
static shear(shx: number, shy: number): Matrix3x3;
|
|
22
|
+
static readonly IDENTITY: Matrix3x3;
|
|
23
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Vector2 } from '../Vector2/Vector2';
|
|
2
|
+
import { createIdentity, createTranslation, createRotation, createScale, createShear } from './factories';
|
|
3
|
+
/**
|
|
4
|
+
* A 3x3 matrix class for 2D affine transformations.
|
|
5
|
+
* Stored in row-major order:
|
|
6
|
+
* [ 0 1 2 ]
|
|
7
|
+
* [ 3 4 5 ]
|
|
8
|
+
* [ 6 7 8 ]
|
|
9
|
+
*/
|
|
10
|
+
export class Matrix3x3 {
|
|
11
|
+
values;
|
|
12
|
+
constructor(values) {
|
|
13
|
+
if (values.length !== 9) {
|
|
14
|
+
throw new Error('Matrix3x3 requires 9 values');
|
|
15
|
+
}
|
|
16
|
+
this.values = new Float32Array(values);
|
|
17
|
+
}
|
|
18
|
+
multiply(other) {
|
|
19
|
+
const a = this.values;
|
|
20
|
+
const b = other.values;
|
|
21
|
+
const out = new Float32Array(9);
|
|
22
|
+
const a00 = a[0], a01 = a[1], a02 = a[2];
|
|
23
|
+
const a10 = a[3], a11 = a[4], a12 = a[5];
|
|
24
|
+
const a20 = a[6], a21 = a[7], a22 = a[8];
|
|
25
|
+
const b00 = b[0], b01 = b[1], b02 = b[2];
|
|
26
|
+
const b10 = b[3], b11 = b[4], b12 = b[5];
|
|
27
|
+
const b20 = b[6], b21 = b[7], b22 = b[8];
|
|
28
|
+
out[0] = a00 * b00 + a01 * b10 + a02 * b20;
|
|
29
|
+
out[1] = a00 * b01 + a01 * b11 + a02 * b21;
|
|
30
|
+
out[2] = a00 * b02 + a01 * b12 + a02 * b22;
|
|
31
|
+
out[3] = a10 * b00 + a11 * b10 + a12 * b20;
|
|
32
|
+
out[4] = a10 * b01 + a11 * b11 + a12 * b21;
|
|
33
|
+
out[5] = a10 * b02 + a11 * b12 + a12 * b22;
|
|
34
|
+
out[6] = a20 * b00 + a21 * b10 + a22 * b20;
|
|
35
|
+
out[7] = a20 * b01 + a21 * b11 + a22 * b21;
|
|
36
|
+
out[8] = a20 * b02 + a21 * b12 + a22 * b22;
|
|
37
|
+
return new Matrix3x3(out);
|
|
38
|
+
}
|
|
39
|
+
/** Transforms a Vector2 point (assumes z=1). */
|
|
40
|
+
transformPoint(point) {
|
|
41
|
+
const m = this.values;
|
|
42
|
+
const x = point.x;
|
|
43
|
+
const y = point.y;
|
|
44
|
+
const m00 = m[0], m01 = m[1], m02 = m[2];
|
|
45
|
+
const m10 = m[3], m11 = m[4], m12 = m[5];
|
|
46
|
+
const tx = m00 * x + m01 * y + m02;
|
|
47
|
+
const ty = m10 * x + m11 * y + m12;
|
|
48
|
+
return new Vector2(tx, ty);
|
|
49
|
+
}
|
|
50
|
+
/** @throws Error if the matrix is not invertible. */
|
|
51
|
+
inverse() {
|
|
52
|
+
const m = this.values;
|
|
53
|
+
const m00 = m[0], m01 = m[1], m02 = m[2];
|
|
54
|
+
const m10 = m[3], m11 = m[4], m12 = m[5];
|
|
55
|
+
const m20 = m[6], m21 = m[7], m22 = m[8];
|
|
56
|
+
const det = m00 * (m11 * m22 - m12 * m21) -
|
|
57
|
+
m01 * (m10 * m22 - m12 * m20) +
|
|
58
|
+
m02 * (m10 * m21 - m11 * m20);
|
|
59
|
+
if (Math.abs(det) < 1e-10) {
|
|
60
|
+
throw new Error('Matrix is not invertible');
|
|
61
|
+
}
|
|
62
|
+
const invDet = 1.0 / det;
|
|
63
|
+
const out = new Float32Array(9);
|
|
64
|
+
out[0] = (m11 * m22 - m12 * m21) * invDet;
|
|
65
|
+
out[1] = (m02 * m21 - m01 * m22) * invDet;
|
|
66
|
+
out[2] = (m01 * m12 - m02 * m11) * invDet;
|
|
67
|
+
out[3] = (m12 * m20 - m10 * m22) * invDet;
|
|
68
|
+
out[4] = (m00 * m22 - m02 * m20) * invDet;
|
|
69
|
+
out[5] = (m02 * m10 - m00 * m12) * invDet;
|
|
70
|
+
out[6] = (m10 * m21 - m11 * m20) * invDet;
|
|
71
|
+
out[7] = (m01 * m20 - m00 * m21) * invDet;
|
|
72
|
+
out[8] = (m00 * m11 - m01 * m10) * invDet;
|
|
73
|
+
return new Matrix3x3(out);
|
|
74
|
+
}
|
|
75
|
+
static identity() {
|
|
76
|
+
return Matrix3x3.IDENTITY;
|
|
77
|
+
}
|
|
78
|
+
static translation(tx, ty) {
|
|
79
|
+
return new Matrix3x3(createTranslation(tx, ty));
|
|
80
|
+
}
|
|
81
|
+
static rotation(angle) {
|
|
82
|
+
return new Matrix3x3(createRotation(angle));
|
|
83
|
+
}
|
|
84
|
+
static scale(sx, sy) {
|
|
85
|
+
return new Matrix3x3(createScale(sx, sy));
|
|
86
|
+
}
|
|
87
|
+
static shear(shx, shy) {
|
|
88
|
+
return new Matrix3x3(createShear(shx, shy));
|
|
89
|
+
}
|
|
90
|
+
static IDENTITY = new Matrix3x3(createIdentity());
|
|
91
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates an identity matrix.
|
|
3
|
+
*/
|
|
4
|
+
export declare function createIdentity(): Float32Array;
|
|
5
|
+
/** Creates a translation matrix. */
|
|
6
|
+
export declare function createTranslation(tx: number, ty: number): Float32Array;
|
|
7
|
+
/** Creates a rotation matrix (angle in radians). */
|
|
8
|
+
export declare function createRotation(angle: number): Float32Array;
|
|
9
|
+
/** Creates a scaling matrix. */
|
|
10
|
+
export declare function createScale(sx: number, sy: number): Float32Array;
|
|
11
|
+
/** Creates a shear matrix. */
|
|
12
|
+
export declare function createShear(shx: number, shy: number): Float32Array;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates an identity matrix.
|
|
3
|
+
*/
|
|
4
|
+
export function createIdentity() {
|
|
5
|
+
return new Float32Array([
|
|
6
|
+
1, 0, 0,
|
|
7
|
+
0, 1, 0,
|
|
8
|
+
0, 0, 1
|
|
9
|
+
]);
|
|
10
|
+
}
|
|
11
|
+
/** Creates a translation matrix. */
|
|
12
|
+
export function createTranslation(tx, ty) {
|
|
13
|
+
return new Float32Array([
|
|
14
|
+
1, 0, tx,
|
|
15
|
+
0, 1, ty,
|
|
16
|
+
0, 0, 1
|
|
17
|
+
]);
|
|
18
|
+
}
|
|
19
|
+
/** Creates a rotation matrix (angle in radians). */
|
|
20
|
+
export function createRotation(angle) {
|
|
21
|
+
const c = Math.cos(angle);
|
|
22
|
+
const s = Math.sin(angle);
|
|
23
|
+
return new Float32Array([
|
|
24
|
+
c, -s, 0,
|
|
25
|
+
s, c, 0,
|
|
26
|
+
0, 0, 1
|
|
27
|
+
]);
|
|
28
|
+
}
|
|
29
|
+
/** Creates a scaling matrix. */
|
|
30
|
+
export function createScale(sx, sy) {
|
|
31
|
+
return new Float32Array([
|
|
32
|
+
sx, 0, 0,
|
|
33
|
+
0, sy, 0,
|
|
34
|
+
0, 0, 1
|
|
35
|
+
]);
|
|
36
|
+
}
|
|
37
|
+
/** Creates a shear matrix. */
|
|
38
|
+
export function createShear(shx, shy) {
|
|
39
|
+
return new Float32Array([
|
|
40
|
+
1, shx, 0,
|
|
41
|
+
shy, 1, 0,
|
|
42
|
+
0, 0, 1
|
|
43
|
+
]);
|
|
44
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type Canvas } from '@napi-rs/canvas';
|
|
2
|
+
import type { Scene } from '../scene';
|
|
3
|
+
/**
|
|
4
|
+
* Renders individual frames from a Scene.
|
|
5
|
+
* Responsible for drawing mobjects to a canvas at a specific point in time.
|
|
6
|
+
*/
|
|
7
|
+
export declare class FrameRenderer {
|
|
8
|
+
private readonly scene;
|
|
9
|
+
private readonly width;
|
|
10
|
+
private readonly height;
|
|
11
|
+
constructor(scene: Scene, width: number, height: number);
|
|
12
|
+
/**
|
|
13
|
+
* Calculates the matrix that transforms Manim world coordinates to screen pixels.
|
|
14
|
+
*
|
|
15
|
+
* Manim coordinate system:
|
|
16
|
+
* - Origin at center of screen
|
|
17
|
+
* - Y-axis points up
|
|
18
|
+
* - frameHeight = 8.0 units
|
|
19
|
+
*
|
|
20
|
+
* Screen coordinate system:
|
|
21
|
+
* - Origin at top-left
|
|
22
|
+
* - Y-axis points down
|
|
23
|
+
* - Width x Height pixels
|
|
24
|
+
*/
|
|
25
|
+
private calculateWorldToScreenMatrix;
|
|
26
|
+
/**
|
|
27
|
+
* Renders a single frame at the specified time.
|
|
28
|
+
*/
|
|
29
|
+
renderFrame(time: number): Canvas;
|
|
30
|
+
/**
|
|
31
|
+
* Gets the canvas dimensions.
|
|
32
|
+
*/
|
|
33
|
+
getDimensions(): {
|
|
34
|
+
width: number;
|
|
35
|
+
height: number;
|
|
36
|
+
};
|
|
37
|
+
}
|