Text and Mathematics¶
Explanatory animations are mostly labels and formulae, so Algan gives text and LaTeX first-class treatment. Both are cubic Bezier circuits underneath – real outlines, not bitmaps – so they stay crisp at any zoom and morph into other shapes like anything else.
Text– a string rendered with a font.Tex– LaTeX.DecimalNumber– a number you can animate.
Plain Text¶
Example: TextBasic ¶
from algan import *
title = Text("Euler's identity", font_size=64).move(UP * 1.5).spawn()
formula = Tex(r"e^{i\pi} + 1 = 0", font_size=80).spawn()
with Seq(runtime=3):
formula.color = YELLOW
title.move(UP * 0.5)
Scene.save_video()
Text accepts the styling arguments you would expect:
Example: TextStyles ¶
from algan import *
lines = Group([
Text("plain", font_size=44),
Text("bold", font_size=44, weight="BOLD"),
Text("italic", font_size=44, slant="ITALIC"),
Text("colored words", font_size=44, color_map={"colored": YELLOW}),
])
lines.arrange_in_line(DOWN, buffer=0.35).move_to(ORIGIN).spawn()
lines.wait()
Scene.save_video()
Argument |
Meaning |
|---|---|
|
Point size. |
|
Color of the whole string. Defaults to
|
|
Font family name, e.g. |
|
|
|
|
|
Text-to-color: |
|
Gap between lines of a multi-line string. |
|
A color gradient across the string. |
Because font_size and scale() both change apparent size, pick
one and stay with it. font_size is usually clearer for a fixed label;
scale is what you animate.
LaTeX¶
Tex compiles LaTeX in math mode, so you never have to wrap
anything in $:
Example: TextMathTex ¶
from algan import *
formula = Tex(r"\frac{d}{dx}\left(x^2\right) = 2x", font_size=60).spawn()
with Seq(runtime=2):
formula.color = YELLOW
formula.scale(1.3)
Scene.save_video()
For a run of ordinary prose inside a formula, wrap it in \text{...} as you
would anywhere else in LaTeX.
Important
LaTeX requires a working TeX installation on your machine (any of TeX Live, MiKTeX or MacTeX). Algan caches the compiled glyph geometry, so only the first render of a given string pays the LaTeX cost.
Always use raw strings (r"...") for LaTeX, so Python does not eat the
backslashes.
Animating parts of a formula¶
Pass several strings to Tex and each becomes a separate segment,
retrieved with get_segment() and animated
independently:
Example: TextTexParts ¶
from algan import *
formula = Tex("e^{i\\pi}", "+ 1", "= 0", font_size=90).spawn()
with Lag(0.5):
for i in range(len(formula.tex_strings)):
formula.get_segment(i).color = YELLOW
Scene.save_video()
This is the standard way to draw attention to one term of an equation: split the formula where you want the seams, then animate that segment.
Note
Segments are not children. A multi-part Tex keeps every glyph
in one packed batch, so formula.children has a single entry – looping
over it colors the whole formula at once and any surrounding
Lag has nothing to stagger. Reach for
get_segment() whenever you want the pieces you
passed in, and index the Mob directly (formula[3]) for individual glyphs.
Per-glyph animation¶
Every Text and Tex exposes its individual glyphs as
character_mobs, a list of Mobs you can animate one at a time:
Example: TextGlyphs ¶
from algan import *
word = Text("ALGAN", font_size=90).spawn()
with Lag(0.3):
for glyph in word.character_mobs:
glyph.color = YELLOW
Scene.save_video()
Combined with Lag, this gives you cascading effects across a string
for free. Note that character_mobs contains only visible glyphs – spaces are
not included.
The hand-writing effect¶
write() traces each glyph’s outline and then fills it, one glyph after
another, for the classic “written by hand” look:
Example: TextWrite ¶
from algan import *
Text("Hand written", font_size=64).spawn(False).write(runtime=3)
Scene.save_video()
Note the spawn(False) before write(). Without False the text would
first play its ordinary fade-in and then be written. write() deliberately
does not change the text’s spawned state; Algan keeps lifespan management
separate from animations.
write() takes runtime for the whole sequence and lag_ratio for how
much each glyph overlaps the next (0 writes them all at once). It is shorthand
for DrawBorderThenFill() applied to the glyphs – that function works
on any iterable of Mobs, so you can use it on shapes too. See
Built-in Animations for that.
Animated Numbers¶
DecimalNumber renders a number and animates through the values
in between when you change it:
Example: TextDecimalNumber ¶
from algan import *
counter = DecimalNumber(0.0, decimal_places=2).scale(2).spawn()
with Seq(runtime=3):
counter.value = 100.0
Scene.save_video()
decimal_places fixes the digits after the point and
integer_places sets an initial minimum width before it. If the value later
needs more integer digits, the display grows automatically; the extra slots remain
available so its width stays stable afterwards.
See Also¶
Positioning and Layout – placing labels next to what they label.
Built-in Animations – drawing attention to a term you just introduced.
Audio and Speech – syncing text with narration.
Images and Textures – painting a gradient or an image across glyphs.
Importing From Manim –
MathTex,Titleand the rest of Manim’s text mobjects.Combining Animations – the
Lagcontext that makes the per-glyph effects above cascade.