Text & UI
Each block is the whole file — copy it into x.manic and run manic x.manic (live) or --record out (video).
typewriter
Text revealed character by character.
// Typewriter — text revealed letter by letter (Manim's AddTextLetterByLetter),
// then removed letter by letter (RemoveTextLetterByLetter). `type` animates the
// text's `trace` 0->1 (a fraction of characters shown); `erase` runs it back.
// Declare the text `untraced` so it starts hidden, then `type` reveals it.
//
// manic examples/typewriter.manic
title("Typewriter");
canvas("16:9");
text(head, (cx, 150), "text, one letter at a time");
display(head); color(head, cyan); size(head, 26); hidden(head);
// untraced = trace 0 = no characters shown yet
text(line1, (cx, 320), "the quick brown fox"); color(line1, lime); size(line1, 44); untraced(line1);
text(line2, (cx, 400), "jumps over the lazy dog"); color(line2, cyan); size(line2, 44); untraced(line2);
cursor(line2); // this line types with a trailing cursor
// --- script ---
show(head, 0.5);
type(line1, 1.6); // AddTextLetterByLetter
type(line2, 1.6); // AddTextLetterByLetter, with a cursor
wait(1.0);
section("...and back");
erase(line2, 1.0); // RemoveTextLetterByLetter
erase(line1, 1.0);
wait(0.8);
captions
Karaoke / word-pop caption modes.
// Captions — karaoke word highlighting and TikTok-style word pop-in. `caption`
// lays out a phrase's words in a centred row (as {id}.w0, {id}.w1, ... tagged
// {id}.words); `karaoke` highlights them in sequence; `wordpop` pops them in one
// at a time.
//
// manic examples/captions.manic
// manic examples/captions.manic --record out --fps 60
title("Captions");
canvas("16:9");
text(head, (cx, 110), "word-by-word: karaoke + pop-in");
display(head); color(head, cyan); size(head, 26); hidden(head);
// karaoke: starts dim, words light up in sequence
caption(kara, "follow the bouncing highlight", (cx, 280), 46, dim);
// word-pop: hidden first, then each word pops in
caption(pop, "each word pops right in", (cx, 440), 50, lime);
hidden(pop.words);
// --- script ---
show(head, 0.5);
section("Karaoke");
karaoke(kara, 0.34, cyan);
wait(0.8);
section("Word pop");
wordpop(pop, 0.14);
wait(1.6);
terminal_boot
The neon terminal template booting up.
// Terminal Boot — a fake boot sequence typed out line by line, ending at a live
// prompt with a blinking-style cursor. Shows off the `cursor` modifier, `type`
// typewriter reveal, an author-set `masthead`, and the `terminal` template.
//
// manic examples/terminal_boot.manic
// manic examples/terminal_boot.manic --record out --fps 60
title("manic");
canvas("16:9");
template("terminal");
masthead("manic ~ %", "READY"); // your own header text (no engine branding)
text(l1, (cx, 210), ""); color(l1, lime); size(l1, 24);
text(l2, (cx, 260), ""); color(l2, cyan); size(l2, 24); hidden(l2);
text(l3, (cx, 310), ""); color(l3, cyan); size(l3, 24); hidden(l3);
text(l4, (cx, 360), ""); color(l4, lime); size(l4, 24); hidden(l4);
text(prompt, (cx, 440), ""); color(prompt, fg); size(prompt, 28); display(prompt);
hidden(prompt); cursor(prompt); // only the live prompt gets the cursor
// --- boot log ---
say(l1, "> initializing manic engine", 0.1);
type(l1, 1.0);
show(l2, 0.2);
say(l2, " loaded kits: std math geo algo brand", 0.1);
type(l2, 1.3);
show(l3, 0.2);
say(l3, " timeline: deterministic @ 60fps", 0.1);
type(l3, 1.0);
show(l4, 0.2);
say(l4, " ready.", 0.1);
type(l4, 0.5);
// --- the prompt, awaiting input ---
show(prompt, 0.2);
say(prompt, "manic ~ % render my_idea", 0.1);
type(prompt, 1.2);
wait(1.6);
brace
The curly-brace family.
// Braces — label spans and parts with curly braces, manic's Brace / BraceLabel
// / BraceBetweenPoints. A length is split into two parts a and b; a brace under
// each names it, and a brace over the whole names the sum. Every brace here is
// a BraceBetweenPoints (two points + a depth); bracelabel adds the text.
//
// manic examples/brace.manic
// manic examples/brace.manic --record out --fps 60
title("Braces");
canvas(1280, 720);
text(head, (640, 120), "label a span, or its parts");
display(head); color(head, cyan); size(head, 28); hidden(head);
text(cap, (640, 620), ""); color(cap, dim); size(cap, 24);
// the length, split at x = 680
line(seg, (300, 360), (980, 360)); color(seg, fg); stroke(seg, 3); untraced(seg);
dot(dl, (300, 360)); dot(dm, (680, 360)); dot(dr, (980, 360));
color(dl, magenta); color(dm, lime); color(dr, cyan);
hidden(dl); hidden(dm); hidden(dr);
// braces under the two parts, and over the whole (bulges up: points go R->L)
bracelabel(ba, (300, 392), (680, 392), "a", 30); color(ba, magenta);
bracelabel(bb, (680, 392), (980, 392), "b", 30); color(bb, cyan);
bracelabel(bt, (980, 320), (300, 320), "a + b", 34); color(bt, lime);
hidden(ba); hidden(bb); hidden(bt);
// --- reveal ---
show(head, 0.5);
say(cap, "here is a length");
draw(seg, 0.7);
par { show(dl, 0.3); show(dr, 0.3); }
wait(0.3);
section("Two parts");
say(cap, "split it at a point into parts a and b");
show(dm, 0.3);
show(ba, 0.5);
show(bb, 0.5);
wait(0.5);
section("The whole");
say(cap, "the whole span is a + b");
show(bt, 0.6);
par { pulse(ba.label); pulse(bb.label); pulse(bt.label); }
wait(1.4);
banner
The manic logo / banner reveal.
// The manic banner & watermark (à la ManimBanner). "create" draws the icon
// trio on; "expand" reveals the wordmark; the watermark persists in the corner.
//
// manic examples/banner.manic
// manic examples/banner.manic --record out --fps 60
title("manic");
canvas(1280, 720);
banner(logo, (600, 360), 1.1);
untraced(logo.icon); // icon shapes drawn on
hidden(logo.word); // wordmark revealed on "expand"
// a persistent, screen-fixed watermark, bottom-right
watermark(wm, (1120, 690), "manic // synthwave");
text(cap, (640, 560), ""); color(cap, dim); size(cap, 22);
// --- create: trace the icon trio on (staggered) ---
say(cap, "create");
stagger(0.2) {
draw(logo.dot, 0.6);
draw(logo.sq, 0.6);
draw(logo.tri, 0.6);
}
par { pulse(logo.dot); pulse(logo.sq); pulse(logo.tri); }
wait(0.4);
// --- expand: reveal the wordmark ---
say(cap, "expand");
show(logo.word, 0.6);
wait(1.2);
// --- unwrite: fade the whole banner ---
say(cap, "");
par { fade(logo.icon, 0.5); fade(logo.word, 0.5); }
wait(0.8);