Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Transforms & morphing

Each block is the whole file — copy it into x.manic and run manic x.manic (live) or --record out (video).

transforms

Apply a 2x2 matrix (ApplyMatrix) to a group.

// Transforms — the "animate anything" showcase.
// Named verbs (rotate, spin, scale, move) plus the general `to(id, prop, value)`
// escape hatch, composed with par / seq / stagger.
//
//   manic examples/transforms.manic
//   manic examples/transforms.manic --record out --fps 60 --crt

title("Transforms");
canvas(1280, 720);

// cast
rect(box, (330, 400), 150, 150);   outline(box, cyan);
label(box, "rotate");
rect(dia, (650, 400), 140, 140);   outline(dia, magenta);
label(dia, "to");
circle(orb, (980, 400), 62);       outline(orb, lime);
label(orb, "spin");

dot(p, (150, 620), 12);
text(cap, (640, 662), "");  color(cap, dim);  size(cap, 22);
text(head, (640, 120), "animate anything");
display(head);  color(head, cyan);  size(head, 40);  hidden(head);

// script
show(head, 0.5);

section("Named verbs");
say(cap, "rotate to an absolute angle");
rotate(box, 45, 0.7, overshoot);
say(cap, "spin by a relative angle, twice");
seq {
  spin(orb, 180, 0.6);
  spin(orb, 180, 0.6);
}
wait(0.4);

section("Animate anything");
say(cap, "to(id, property, value) reaches any property");
par {
  to(dia, angle, 45, 0.6, smooth);
  to(dia, scale, 1.4, 0.6);
  to(dia, color, lime, 0.6);
}
wait(0.4);

say(cap, "compose freely with par / seq / stagger");
stagger(0.12) {
  to(box, opacity, 0.4, 0.4);
  to(dia, opacity, 0.4, 0.4);
  to(orb, opacity, 0.4, 0.4);
}
to(p, x, 1130, 1.0, overshoot);
to(p, color, magenta, 0.4);
wait(1.0);

transform_copy

Duplicate an entity, then transform the copy.

// Copy + Winding Morph — two of the Transform family niceties. `copy(c, a)`
// duplicates a shape so the original stays while the copy transforms; `morph`
// with a spin angle winds the blend (Manim's Clockwise / Counterclockwise
// Transform). Left copy morphs clockwise, right copy counter-clockwise.
//
//   manic examples/transform_copy.manic

title("Copy + Winding Morph");
canvas("16:9");

text(head, (cx, 96), "a copy morphs while the original stays -- one CW, one CCW");
color(head, cyan);  size(head, 23);  hidden(head);

// left: original circle (dim) + a cyan copy that morphs into a square, clockwise
circle(o1, (400, 380), 120);  color(o1, dim);  stroke(o1, 3);  hidden(o1);
rect(t1, (400, 380), 220, 220);  hidden(t1);
copy(c1, o1);  color(c1, cyan);  stroke(c1, 5);  glow(c1, 1.6);  hidden(c1);
morph(c1, t1, 200);          // +200 deg = clockwise wind

// right: same idea, counter-clockwise into a triangle-ish (use another square)
circle(o2, (900, 380), 120);  color(o2, dim);  stroke(o2, 3);  hidden(o2);
rect(t2, (900, 380), 220, 220);  hidden(t2);
copy(c2, o2);  color(c2, magenta);  stroke(c2, 5);  glow(c2, 1.6);  hidden(c2);
morph(c2, t2, -200);         // -200 deg = counter-clockwise

// --- script ---
show(head, 0.5);
par { show(o1, 0.4);  show(o2, 0.4);  show(c1, 0.4);  show(c2, 0.4); }
wait(0.5);

section("Morph the copies");
par { to(c1, morph, 1, 1.8, smooth);  to(c2, morph, 1, 1.8, smooth); }
wait(0.9);
par { to(c1, morph, 0, 1.8, smooth);  to(c2, morph, 0, 1.8, smooth); }
wait(1.2);

morph

A sampled-point shape morph from A to B.

// Shape Morph — a circle's outline blends smoothly into a square's and back
// (Manim's Transform). `morph(a, b)` samples both outlines to the same number
// of points; `to(a, morph, t)` interpolates between them (t = 0 is `a`'s shape,
// 1 is `b`'s).
//
//   manic examples/morph.manic

title("Shape Morph");
canvas("16:9");

text(head, (cx, 110), "a circle becomes a square -- and back");
display(head);  color(head, cyan);  size(head, 26);  hidden(head);

circle(sh, (cx, cy), 150);  color(sh, cyan);  stroke(sh, 5);  glow(sh, 1.6);  hidden(sh);
rect(target, (cx, cy), 290, 290);  hidden(target);   // defines the square outline
morph(sh, target);                                    // set sh up to morph into it

// --- script ---
show(head, 0.5);
show(sh, 0.6);
wait(0.5);

section("Morph");
to(sh, morph, 1, 1.6, smooth);      // circle -> square
wait(0.7);
to(sh, morph, 0, 1.6, smooth);      // square -> circle
wait(0.7);
to(sh, morph, 1, 1.1, overshoot);   // and back, with a bounce
wait(1.4);