skills/creative/manim-video/references/animation-design-thinking.md
How to decide WHAT to animate and HOW to structure it — before writing any code.
Not everything benefits from animation. Motion adds cognitive load. Bad animation is worse than a good static diagram.
Animate when:
Show static when:
Rule of thumb: If you'd explain it with "first X, then Y, then Z" — animate it. If you'd explain it by pointing at parts of one picture — show it static.
Before any code, write what the narrator would say. This determines:
A scene where the narration says "the gradient points uphill" must show a gradient arrow at that moment. If the visual doesn't match the audio, the viewer's brain splits attention and both tracks are lost.
A "beat" is a moment where something changes on screen. Mark each beat in your narration:
"Consider a function f of x." → [BEAT: axes + curve appear]
"At this point..." → [BEAT: dot appears on curve]
"...the slope is positive." → [BEAT: tangent line drawn]
"So the gradient tells us to go left." → [BEAT: arrow points left, dot moves]
Each beat is one self.play() call or a small group of simultaneous animations.
| Visual need | Manim approach |
|---|---|
| Object appears for first time | Create, Write, FadeIn, GrowFromCenter |
| Object transforms into another | Transform, ReplacementTransform, FadeTransform |
| Attention drawn to existing object | Indicate, Circumscribe, Flash, ShowPassingFlash |
| Continuous relationship maintained | add_updater, always_redraw, ValueTracker |
| Object leaves the scene | FadeOut, Uncreate, ShrinkToCenter |
| Static context that stays visible | self.add() (no animation) |
| Content type | Minimum on-screen time |
|---|---|
| New equation appearing | 2.0s animation + 2.0s pause |
| New concept label | 1.0s animation + 1.0s pause |
| Key insight ("aha moment") | 2.5s animation + 3.0s pause |
| Supporting annotation | 0.8s animation + 0.5s pause |
| Scene transition (FadeOut all) | 0.5s animation + 0.3s pause |
After every reveal, add self.wait(). The viewer needs time to:
No wait = the viewer is always behind you. They're still reading the equation when you've already started transforming it.
Monotonous pacing feels like a lecture. Vary the tempo:
self.wait(2.0) before the "aha")LaggedStart with tight lag_ratio)The visual should appear slightly BEFORE the narration describes it. When the viewer sees a circle appear and THEN hears "consider a circle," the visual primes their brain for the concept. The reverse — hearing first, seeing second — creates confusion because they're searching the screen for something that isn't there yet.
# Scene duration should match narration duration.
# If narration for this scene is 8 seconds:
# Total animation run_times + total self.wait() times = ~8 seconds.
# Use manim-voiceover for automatic sync:
with self.voiceover(text="The gradient points downhill") as tracker:
self.play(GrowArrow(gradient_arrow), run_time=tracker.duration)
When building a complex equation step by step:
opacity=0.2 (sets expectation for where you're going)0.5 (it's now context)This is better than building left-to-right because the viewer always sees the destination.
Animate terms in the order the viewer needs to understand them, not in the order they appear in the equation. For E = mc²:
E (the thing we want to know)m (the input)c² (the constant that makes it work)= (connecting them)The most common mistake: too many boxes. Each box is a concept the viewer must track. Five boxes with clear labels beats twelve boxes with abbreviations.
Rule: If two consecutive boxes could be labeled "X" and "process X output," merge them into one box.
Build pipelines left-to-right (or top-to-bottom) with arrows connecting them:
Then show data flowing through: ShowPassingFlash along the arrows, or a colored dot traversing the path.
For complex systems:
MovingCameraScene.camera.frame.animate)