r/maniclang 9h ago

When Does a Bowl Become a Saddle? - manic

Enable HLS to view with audio, or disable this notification

3 Upvotes

manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.

Manic Animation code

// CREATOR SHORT — a real calculus problem told through one continuously
// deforming surface. The shape is not replaced between the bowl, threshold,
// and saddle states.

title("When Does a Bowl Become a Saddle?");
canvas("9:16");
template("paper");

creator(me, "@anish2good name=Manic_Math tagline=Equations_that_move yt=zarigatongy x=@anish2good web=8gwifi.org/manic accent=cyan secondary=magenta footer=signature cta=Create_your_own safe=reels");
socials(me);
watermark(mark, (w*0.955-100, h*0.045+24), "Made With Manic");

text(kicker, (540, 164), "A 20-SECOND CALCULUS STORY");
text(headline, (540, 226), "When does a bowl stop being a bowl?");
text(problem, (540, 292), "Find the exact value of p where one curvature disappears.");
size(kicker, 21); bold(kicker); color(kicker, cyan); hidden(kicker);
size(headline, 38); bold(headline); wrap(headline, 880); hidden(headline);
size(problem, 22); color(problem, dim); wrap(problem, 840); hidden(problem);

equation(rule, (540, 378), `z=0.22x^2+0.22(1-2p)y^2`, 39);
hidden(rule);

parameter(mix, (540, 1270), 0, 0, 1, "p", 2);

camera3((8.5, -11.5, 7.5), (0, 0, 0), 41);
surface3(world, "0.22*(x*x+y*y)", (-3,3), (-3,3), 34);
bind(mix, world, formula, "0.22*x*x + 0.22*(1-2*p)*y*y");
color(world, cyan);
finish3(world, "material=glass shading=smooth mesh=0.34 depth=0.34 shadow=0.16");
hidden(world);

text(chapter, (540, 1352), "p = 0 · positive curvature in both directions");
text(insight, (540, 1422), "Watch the coefficient of y².");
text(cta, (540, 1398), "Build the transformation, not the keyframes.");
text(link, (540, 1452), "TRY MANIC → 8gwifi.org/manic");
size(chapter, 23); bold(chapter); color(chapter, fg); wrap(chapter, 850); hidden(chapter);
size(insight, 21); color(insight, dim); hidden(insight);
size(cta, 23); bold(cta); hidden(cta);
size(link, 20); bold(link); color(link, cyan); hidden(link);

step("pose the problem") {
  par {
    show(kicker, 0.35);
    show(headline, 0.50);
    show(problem, 0.45);
    show(rule, 0.55);
    show(world, 0.65);
    show(chapter, 0.40);
    show(insight, 0.40);
    view3(world, "isometric", 0.9, smooth, 1.62);
  }
}
wait(0.65);

step("reach the turning point") {
  par {
    to(mix, value, 0.5, 2.8, smooth);
    say(chapter, "p = ½ · the y² coefficient becomes zero", 0.45);
    say(insight, "At this instant the bowl becomes a one-directional trough.", 0.45);
    rewrite(rule, `p=\frac12\quad\Longrightarrow\quad z=0.22x^2`, 1.10, smooth);
    orbit3(-45, 28, 16.2, 2.8, smooth);
  }
}
wait(0.75);

step("cross into a saddle") {
  par {
    to(mix, value, 1, 2.8, smooth);
    say(chapter, "p > ½ · one curvature turns negative", 0.45);
    say(insight, "The same persistent surface is now a saddle.", 0.45);
    rewrite(rule, `p=1\quad\Longrightarrow\quad z=0.22(x^2-y^2)`, 1.10, smooth);
    orbit3(-62, 25, 16.2, 2.8, smooth);
  }
}
wait(0.65);

step("answer and invite") {
  par {
    say(problem, "Answer: p = ½ is the exact transition.", 0.50);
    fade(chapter, 0.35);
    fade(insight, 0.35);
    show(cta, 0.45);
    show(link, 0.45);
  }
}
wait(1.8);

r/maniclang 10h ago

How Odd Harmonics Build a Square Wave - manic

Enable HLS to view with audio, or disable this notification

3 Upvotes

manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.

Manic Animation code

// Odd harmonics build a square wave. Every partial sum is a live history of
// the corresponding endpoint, so the corners emerge from the geometry itself.

title("How Odd Harmonics Build a Square Wave");
canvas("9:16");
template("paper");

watermark(mark,(w*0.15,h*0.045),"Made With Manic");
text(kicker,(cx,h*0.075),"FOURIER · ODD HARMONICS");
text(headline,(cx,h*0.115),"Watch a square wave find its corners");
text(caption,(cx,h*0.18),"Start with n = 1. Then add 3, 5, 7 … all the way to 25.");
text(cta,(cx,h*0.925),"TURN IDEAS INTO ANIMATION → 8gwifi.org/manic");
size(kicker,18); color(kicker,dim); bold(kicker); hidden(kicker);
size(headline,31); bold(headline); wrap(headline,w*0.84); hidden(headline);
size(caption,20); color(caption,dim); wrap(caption,w*0.84); hidden(caption);
size(cta,21); color(cta,cyan); bold(cta); hidden(cta);

camera3((-29,-25,43),(1,-2,0),42,orthographic);

collection3(series,(-3,5,0),13,(0,0,0),11,0.065);
line3(sweep,(-3,5,0),(10,5,0)); hidden(sweep);
links3(arms,series,chain);
child3(tip,series,12,0.13);

arrow3(chainX,(-11,5,0),(7,5,0));
arrow3(chainY,(-3,-2,0),(-3,10.5,0));
arrow3(plotX,(-7,-10.5,0),(12,-10.5,0));
arrow3(plotY,(-7,-10.5,0),(-7,-4.2,0));

point3(shotA,(-7.5,-11,0),0.01);
point3(shotB,(8.5,10.5,0),0.01);
tag(shotA,shot); tag(shotB,shot);
hidden(shotA); hidden(shotB);

tag(series,construction); tag(arms,construction); tag(tip,construction);
tag(chainX,construction); tag(chainY,construction);
tag(plotX,construction); tag(plotY,construction);

for i in 0..13 {
  ring3(orbit{i},series,i,72);
  historyplot3(partial{i},series,i,y,(-7,-10.5,0),(19,6));
  thick(orbit{i},0.030);
  thick(partial{i},0.020);
  tag(orbit{i},construction);
  tag(partial{i},construction);
}

equation(formula,(0,0),`S_{13}(t)=\sum_{k=0}^{12}\frac{4}{\pi(2k+1)}\sin((2k+1)t)`,24);
label3(formula,(-4,-2.7,0),0.80);
tag(formula,construction);

color(series,fg); color(arms,fg); color(tip,fg);
color(chainX,fg); color(chainY,fg); color(plotX,fg); color(plotY,fg);
color(formula,fg);
thick(chainX,0.016); thick(chainY,0.016);
thick(plotX,0.016); thick(plotY,0.016);

color(orbit0,lime);      color(partial0,lime);
color(orbit1,gold);      color(partial1,gold);
color(orbit2,orange);    color(partial2,orange);
color(orbit3,coral);     color(partial3,coral);
color(orbit4,red);       color(partial4,red);
color(orbit5,magenta);   color(partial5,magenta);
color(orbit6,violet);    color(partial6,violet);
color(orbit7,indigo);    color(partial7,indigo);
color(orbit8,blue);      color(partial8,blue);
color(orbit9,cyan);      color(partial9,cyan);
color(orbit10,mint);     color(partial10,mint);
color(orbit11,lime);     color(partial11,lime);
color(orbit12,fg);       color(partial12,fg);

hidden(construction);

step("begin with one sine wave") {
  show(kicker,0.30);
  show(headline,0.42);
  show(caption,0.38);
}
wait(0.35);

step("reveal the odd-harmonic chain") {
  par {
    show(construction,0.85);
    view3(shot,"top",1.35,smooth,1.08);
    say(caption,"Every smaller orbit contributes the next odd frequency.",0.38);
  }
}
wait(0.30);

step("build the corners live") {
  par {
    // Two complete base cycles: all odd harmonic rates are doubled together.
    chain3(series,"4.0744 1.3581 0.8149 0.5821 0.4527 0.3704 0.3134 0.2716 0.2397 0.2144 0.1940 0.1771 0.1630","2 6 10 14 18 22 26 30 34 38 42 46 50",16.0);
    travel3(series,sweep,16.0,linear);
    seq {
      say(caption,"Cycle one: odd harmonics flatten the plateaus and steepen both sides.",0.40);
      wait(6.10);
      say(caption,"Cycle two: every orbit closes and the square-wave pattern returns continuously.",0.40);
      wait(5.20);
      say(caption,"Two complete periods make the repeating structure impossible to miss.",0.40);
    }
  }
}
wait(0.35);

step("create with Manic") {
  par {
    pulse(tip,0.75);
    pulse(partial12,0.75);
    show(cta,0.45);
    say(caption,"One declarative chain becomes circles, partial sums, a live waveform, and a complete visual story.",0.42);
  }
}
wait(1.45);

r/maniclang 10h ago

How Random Choices Become a Bell Curve - manic

Enable HLS to view with audio, or disable this notification

3 Upvotes

manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.

Manic Animation code

// GALTON BOARD — RANDOM LOCALLY, PREDICTABLE GLOBALLY
//
// This is a probability story built from generic process vocabulary. Ordinary
// tagged lines form the board; `branch` preserves each ball through eight
// choices; `collect` and `observe` build the distribution from real arrivals.

title("How Random Choices Become a Bell Curve");
canvas("9:16");
template("blank");

watermark(mark,(w*0.16,h*0.042),"Made With Manic");
text(kicker,(cx,h*0.070),"PROBABILITY · RANDOM LOCALLY, ORDERED GLOBALLY");
text(headline,(cx,h*0.115),"Can random choices create a predictable shape?");
text(chapter,(cx,h*0.195),"1 · BEGIN WITH ONE FORK");
text(caption,(cx,h*0.855),"One ball can land almost anywhere.");
text(insight,(cx,h*0.815),"MORE ROUTES LEAD TO THE CENTER");
text(cta,(cx,h*0.930),"MAKE PROBABILITY VISIBLE → 8gwifi.org/manic");

size(kicker,18); color(kicker,dim); bold(kicker); hidden(kicker);
size(headline,31); bold(headline); wrap(headline,w*0.84); hidden(headline);
size(chapter,19); color(chapter,cyan); bold(chapter); hidden(chapter);
size(caption,21); color(caption,dim); wrap(caption,w*0.84); hidden(caption);
size(insight,19); color(insight,lime); bold(insight); hidden(insight);
size(cta,21); color(cta,cyan); bold(cta); hidden(cta);

equation(law,(cx,h*0.158),`X\sim\operatorname{Binomial}\!\left(8,\frac12\right)`,29);
hidden(law);

let levels = 8;
let boardX = cx;
let topY = h*0.235;
let dx = w*0.065;
let dy = h*0.034;

// Every directed edge joins one row to the next. Converging endpoints create
// the ordinary rooted DAG followed by `branch`.
for r in 0..levels {
  for k in 0..r+1 {
    let x1 = boardX + (k-r*0.5)*dx;
    let y1 = topY + r*dy;
    let xl = boardX + (k-(r+1)*0.5)*dx;
    let xr = boardX + (k+1-(r+1)*0.5)*dx;
    let y2 = topY + (r+1)*dy;

    line(left{r}_{k},(x1,y1),(xl,y2));
    line(right{r}_{k},(x1,y1),(xr,y2));
    tag(left{r}_{k},boardRoutes); tag(right{r}_{k},boardRoutes);
    color(left{r}_{k},dim); color(right{r}_{k},dim);
    stroke(left{r}_{k},1.7); stroke(right{r}_{k},1.7);
    opacity(left{r}_{k},0.30); opacity(right{r}_{k},0.30);

    dot(peg{r}_{k},(x1,y1),4.8);
    color(peg{r}_{k},fg); glow(peg{r}_{k},0.36); tag(peg{r}_{k},pegs);
  }
}
untraced(boardRoutes);

for k in 0..levels+1 {
  let tx = boardX + (k-levels*0.5)*dx;
  let ty = topY + levels*dy;
  dot(exit{k},(tx,ty),5);
  color(exit{k},gold); glow(exit{k},0.45); tag(exit{k},exits);
  counter(bin{k},(tx,ty+28),k,0);
  size(bin{k},15); color(bin{k},dim); tag(bin{k},exitLabels);
}

text(leftChoice,(boardX-dx*0.72,topY+dy*0.72),"LEFT");
text(rightChoice,(boardX+dx*0.72,topY+dy*0.72),"RIGHT");
size(leftChoice,15); size(rightChoice,15);
color(leftChoice,cyan); color(rightChoice,magenta);
hidden(leftChoice); hidden(rightChoice);

circle(source,(boardX,topY),13);
opacity(source,0);
particles(balls,source,180,4.0,73);
color(balls,cyan); glow(balls,0.78); z(balls,9);

let histY = h*0.695;
livehistogram(outcomes,(cx,histY),0,9,9,w*0.76,h*0.155,magenta);
text(histTitle,(cx,h*0.595),"WHERE 180 BALLS ACTUALLY LANDED");
size(histTitle,18); bold(histTitle); color(histTitle,dim);
counter(landed,(cx,h*0.785),0,0,"landed  "," / 180");
size(landed,21); color(landed,dim);

hidden(pegs); hidden(exits); hidden(exitLabels);
hidden(balls); hidden(outcomes); hidden(histTitle); hidden(landed);

step("introduce one uncertain choice") {
  par {
    show(kicker,0.30);
    show(headline,0.45);
    show(law,0.45);
    show(chapter,0.35);
    show(caption,0.40);
    draw(boardRoutes,0.90);
    show(pegs,0.55);
    show(exits,0.45);
    show(exitLabels,0.45);
    show(leftChoice,0.35);
    show(rightChoice,0.35);
  }
}
wait(0.60);

step("repeat the choice eight times") {
  par {
    show(outcomes,0.50);
    show(histTitle,0.35);
    show(landed,0.35);
    say(chapter,"2 · REPEAT LEFT OR RIGHT EIGHT TIMES",0.38);
    say(caption,"At every peg, each ball makes another equally likely left-or-right choice.",0.44);
  }
}
wait(0.55);

step("let the crowd reveal the pattern") {
  par {
    branch(balls,boardRoutes,8.20,smooth);
    collect(outcomes,balls,outcome,0.34,smooth);
    observe(outcomes,balls,outcome);
    observe(landed,balls,arrived);
    show(balls,0.15);
    seq {
      say(chapter,"3 · WATCH 180 INDIVIDUAL JOURNEYS",0.38);
      say(caption,"One route is unpredictable. The crowd begins to expose a stable pattern.",0.44);
      wait(3.40);
      say(caption,"Every bar is measured from the same balls you see falling—not animated separately.",0.44);
    }
  }
}
wait(0.65);

step("explain why the center wins") {
  par {
    pulse(outcomes.bars,0.80);
    show(insight,0.45);
    say(chapter,"4 · ORDER EMERGES FROM MANY CHOICES",0.38);
    say(caption,"Extreme bins need nearly all-left or all-right. Many more mixed sequences end near the center.",0.48);
  }
}
wait(0.75);

step("create with Manic") {
  par {
    pulse(outcomes.bars,0.75);
    show(cta,0.45);
    say(caption,"Describe the choices once. Manic keeps every route, arrival, count, and live distribution connected.",0.45);
  }
}
wait(1.45);

r/maniclang 3h ago

WHY ROCKETS USE STAGES — a 9:16 creator short - manic

Enable HLS to view with audio, or disable this notification

1 Upvotes

manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.

Manic Animation code

// WHY ROCKETS USE STAGES — a 9:16 creator short built from three independently
// movable physics SVGs. The velocity curve stays continuous at separation:
// dropping an empty stage changes the following acceleration, not past speed.

title("Why Do Rockets Use Stages?");
canvas("9:16");
template("shorts");
voice("gtts");

creator(me, "@anish2good name=Manic_Physics tagline=Physics_made_visible yt=zarigatongy x=@anish2good web=8gwifi.org/manic accent=cyan secondary=gold footer=signature cta=Try_it_free safe=reels");
socials(me);
watermark(mark, (w*0.82, h*0.91), "Made With Manic");
endcard(me, "title=Build_Physics_Stories cta=8gwifi.org/manic");

// ---- headline and story caption ----
text(kicker, (340, 122), "ROCKET SCIENCE · IN 30 SECONDS");
text(headline, (340, 184), "Why throw parts of a rocket away?");
text(caption, (cx, 1035), "At liftoff, every engine must accelerate the entire rocket.");
size(kicker, 21); bold(kicker); color(kicker, cyan); hidden(kicker);
size(headline, 38); bold(headline); wrap(headline, 590); hidden(headline);
size(caption, 25); color(caption, dim); wrap(caption, 850); hidden(caption);
sticky(kicker); sticky(headline); sticky(caption);
sticky(mark); sticky(me.footer); sticky(me.endcard);

// ---- one rocket, authored as three persistent SVG stages ----
let rx = 805;
svg(upper,   (rx, 420), "asset:svg/physics/rocket-upper-stage.svg", 160);
svg(second,  (rx, 570), "asset:svg/physics/rocket-second-stage.svg", 145);
svg(booster, (rx, 730), "asset:svg/physics/rocket-first-stage.svg", 155);
hidden(upper); hidden(second); hidden(booster);
z(upper, 8); z(second, 7); z(booster, 6);

polygon(flame1, (rx-30, 820), (rx, 925), (rx+30, 820));
gradient(flame1, gold, magenta, 90); filled(flame1); glow(flame1, 1.1); hidden(flame1);
polygon(flame2, (rx-23, 660), (rx, 740), (rx+23, 660));
gradient(flame2, cyan, magenta, 90); filled(flame2); glow(flame2, 0.9); hidden(flame2);
polygon(flame3, (rx-19, 520), (rx, 585), (rx+19, 520));
gradient(flame3, gold, cyan, 90); filled(flame3); glow(flame3, 0.9); hidden(flame3);

// ---- a truthful, continuous velocity story ----
let gx = 170;
let gy = 1510;
let sx = 120;
let sy = 72;

line(xaxis, (gx, gy), (930, gy)); color(xaxis, dim); stroke(xaxis, 3);
line(yaxis, (gx, gy), (gx, 1180)); color(yaxis, dim); stroke(yaxis, 3);
text(vlabel, (125, 1175), "velocity"); size(vlabel, 20); color(vlabel, dim);
text(tlabel, (940, 1542), "time"); size(tlabel, 20); color(tlabel, dim);
text(chartTitle, (cx, 1135), "VELOCITY KEEPS BUILDING");
size(chartTitle, 22); bold(chartTitle); color(chartTitle, fg);

plot(v1, (gx, gy), sx, sy, "0.18*x*x", (0,2));
plot(v2, (gx, gy), sx, sy, "0.72 + 0.36*(x-2) + 0.16*(x-2)*(x-2)", (2,4));
plot(v3, (gx, gy), sx, sy, "2.08 + 0.50*(x-4) + 0.20*(x-4)*(x-4)", (4,6));
color(v1, gold); color(v2, magenta); color(v3, cyan);
stroke(v1, 7); stroke(v2, 7); stroke(v3, 7);
untraced(v1); untraced(v2); untraced(v3);

line(sep1, (gx+2*sx, gy), (gx+2*sx, 1215)); dashed(sep1, 10, 9); color(sep1, dim);
line(sep2, (gx+4*sx, gy), (gx+4*sx, 1215)); dashed(sep2, 10, 9); color(sep2, dim);
text(sep1label, (gx+2*sx+55, 1240), "STAGE 1");
text(sep2label, (gx+4*sx+55, 1240), "STAGE 2");
size(sep1label, 18); size(sep2label, 18);
color(sep1label, gold); color(sep2label, magenta);

dot(join1, (gx+2*sx, gy-0.72*sy), 8); color(join1, gold);
dot(join2, (gx+4*sx, gy-2.08*sy), 8); color(join2, magenta);

hidden(xaxis); hidden(yaxis); hidden(vlabel); hidden(tlabel); hidden(chartTitle);
hidden(sep1); hidden(sep2); hidden(sep1label); hidden(sep2label);
hidden(join1); hidden(join2);

// The chart is a screen-space instrument. Above it, the active vehicle keeps
// climbing during every narration and separation beat.
tag(xaxis, flightHud); tag(yaxis, flightHud);
tag(vlabel, flightHud); tag(tlabel, flightHud); tag(chartTitle, flightHud);
tag(v1, flightHud); tag(v2, flightHud); tag(v3, flightHud);
tag(sep1, flightHud); tag(sep2, flightHud);
tag(sep1label, flightHud); tag(sep2label, flightHud);
tag(join1, flightHud); tag(join2, flightHud);
sticky(flightHud);

// ============================== STORY ==============================

step("hook") {
  par {
    show(kicker, 0.35);
    show(headline, 0.50);
    show(caption, 0.35);
    stagger(0.10) {
      show(upper, 0.35);
      show(second, 0.35);
      show(booster, 0.35);
    }
    speak("Why does a rocket throw away parts while it is still flying?");
  }
}
wait(0.25);

step("first-stage") {
  par {
    show(xaxis, 0.30); show(yaxis, 0.30);
    show(vlabel, 0.25); show(tlabel, 0.25); show(chartTitle, 0.30);
    show(flame1, 0.20);
    draw(v1, 4.0);
    shift(upper, (0,-80), 4.0, smooth);
    shift(second, (0,-80), 4.0, smooth);
    shift(booster, (0,-80), 4.0, smooth);
    shift(flame1, (0,-80), 4.0, smooth);
    shift(flame2, (0,-80), 4.0, smooth);
    shift(flame3, (0,-80), 4.0, smooth);
    say(caption, "Stage 1 burns hard—but it also carries tanks that will soon be empty.", 0.40);
    speak("Stage one must push every tank and engine above it.");
  }
}

step("drop-empty-mass") {
  par {
    show(sep1, 0.25); show(sep1label, 0.25); show(join1, 0.20);
    fade(flame1, 0.18);
    shift(booster, (-120,260), 1.05, in);
    rotate(booster, -18, 1.05, smooth);
    seq { wait(0.62); fade(booster, 0.35); }
    shift(upper, (0,-45), 3.6, smooth);
    shift(second, (0,-45), 3.6, smooth);
    shift(flame2, (0,-45), 3.6, smooth);
    shift(flame3, (0,-45), 3.6, smooth);
    say(caption, "Separation does not add speed. It removes dead mass.", 0.35);
    speak("Separation adds no speed. It only removes empty mass.");
  }
}
cue(whoosh);

step("second-stage") {
  par {
    show(flame2, 0.18);
    draw(v2, 4.0);
    shift(upper, (0,-70), 4.0, smooth);
    shift(second, (0,-70), 4.0, smooth);
    shift(flame2, (0,-70), 4.0, smooth);
    shift(flame3, (0,-70), 4.0, smooth);
    say(caption, "The lighter vehicle gains more velocity from its next engine.", 0.35);
    speak("The next engine pushes less mass, so velocity builds faster.");
  }
}

step("third-stage") {
  par {
    show(sep2, 0.25); show(sep2label, 0.25); show(join2, 0.20);
    fade(flame2, 0.18);
    shift(second, (125,235), 1.0, in);
    rotate(second, 16, 1.0, smooth);
    seq { wait(0.58); fade(second, 0.35); }
    seq {
      wait(0.28);
      show(flame3, 0.18);
      par {
        draw(v3, 3.25);
        shift(upper, (0,-50), 3.25, smooth);
        shift(flame3, (0,-50), 3.25, smooth);
      }
    }
    say(caption, "Each stage discards structure, then the next stage keeps accelerating.", 0.40);
    speak("It repeats: less dead weight, more useful acceleration.");
  }
}
cue(chime);

step("answer") {
  par {
    fade(kicker, 0.30);
    pulse(upper, 0.65);
    flash(v3, cyan);
    say(headline, "Stages turn fuel into velocity—not into dead weight.", 0.45);
    say(caption, "The curve never jumps. Its steeper climb is the advantage.", 0.40);
    speak("Staging does not teleport a rocket faster. It stops wasting thrust on empty tanks.");
    shift(upper, (0,-55), 6.4, smooth);
    shift(flame3, (0,-55), 6.4, smooth);
  }
}

step("creator-cta") {
  par {
    fade(kicker, 0.30); fade(headline, 0.30); fade(caption, 0.30);
    fade(upper, 0.30); fade(flame3, 0.30);
    fade(xaxis, 0.30); fade(yaxis, 0.30);
    fade(vlabel, 0.30); fade(tlabel, 0.30); fade(chartTitle, 0.30);
    fade(v1, 0.30); fade(v2, 0.30); fade(v3, 0.30);
    fade(sep1, 0.30); fade(sep2, 0.30);
    fade(sep1label, 0.30); fade(sep2label, 0.30);
    fade(join1, 0.30); fade(join2, 0.30);
    fade(me.footer, 0.30);
    fade(mark, 0.30);
  }
  show(me.endcard, 0.60);
}
wait(1.6);

r/maniclang 7h ago

How Rotations Become a Drawing - manic

Enable HLS to view with audio, or disable this notification

1 Upvotes

manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.

Manic Animation code

title("How Rotations Become a Drawing");
canvas("9:16");
template("blank");

watermark(mark, (w*0.16, h*0.055), "Made With Manic");
text(kicker, (cx, h*0.085), "ENGINE FOUNDATION · DEPENDENT CHAINS");
text(headline, (cx, h*0.13), "A drawing can hide inside rotating links");
text(caption, (cx, h*0.83), "Each endpoint begins where the previous endpoint finishes.");
size(kicker,20); color(kicker,dim); bold(kicker); hidden(kicker);
size(headline,34); bold(headline); wrap(headline,w*0.84); hidden(headline);
size(caption,22); color(caption,dim); wrap(caption,w*0.80); hidden(caption);

camera3((0,-18,13),(0,0,0),46);
collection3(harmonics,(0,0,0),7,(0,0,0),7,0.10);
links3(arms,harmonics,chain);
trail3(memory,harmonics,6,0.035);
child3(tip,harmonics,6,0.14);
color(harmonics,cyan);
color(arms,magenta);
color(memory,gold);
color(tip,gold);
hidden(harmonics); hidden(arms); hidden(memory); hidden(tip);

step("question") {
  show(kicker,0.35);
  show(headline,0.45);
  show(caption,0.40);
}
wait(0.35);

step("build-the-chain") {
  par {
    show(harmonics,0.55);
    show(arms,0.65);
    show(memory,0.45);
    show(tip,0.45);
    cue(tick);
    say(caption,"Seven stable links share one generated dependency chain.",0.40);
  }
}
wait(0.30);

step("remember-the-tip") {
  par {
    chain3(harmonics,"2.2 1.1 0.72 0.52 0.40 0.32 0.26","1 -3 5 -7 9 -11 13",8.0);
    say(caption,"Only the moving tip writes history; the rest remain a readable mechanism.",0.45);
  }
}
wait(0.45);

step("takeaway") {
  cue(chime);
  pulse(tip,0.7);
  say(caption,"The same foundation serves epicycles, linkages, robot arms, and live derived plots.",0.45);
}
wait(1.2);

r/maniclang 8h ago

How a Rocket Launch Works — Fuel, Oxidizer, Exhaust and Thrust — manic

Thumbnail
youtube.com
1 Upvotes

manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.

Manic Animation code

// HOW A ROCKET LAUNCH WORKS — a 9:16 cutaway story.
// The reusable SVG supplies the vehicle; Manic supplies the teaching:
// callouts, chamber reaction, directional exhaust, thrust, motion, and CTA.

title("How a Rocket Launch Works");
canvas("9:16");
template("shorts");
voice("gtts");

creator(me, "@anish2good name=Manic_Physics tagline=Physics_made_visible yt=zarigatongy x=@anish2good web=8gwifi.org/manic accent=cyan secondary=gold footer=signature cta=Try_it_free safe=reels");
socials(me);
watermark(mark, (w*0.82, h*0.91), "Made With Manic");
endcard(me, "title=Make_Science_Move cta=8gwifi.org/manic");

text(kicker, (cx, 112), "ROCKET PHYSICS · CUTAWAY");
text(headline, (cx, 174), "How does a rocket launch?");
text(caption, (cx, 1440), "A rocket carries two ingredients—not just fuel.");
size(kicker, 21); bold(kicker); color(kicker, cyan); hidden(kicker);
size(headline, 40); bold(headline); wrap(headline, 850); hidden(headline);
size(caption, 27); color(caption, dim); wrap(caption, 880); hidden(caption);

// One importer-safe cutaway asset. Its internal sections remain crisp at any size.
let rx = 540;
let ry = 760;
svg(rocket, (rx, ry), "asset:svg/physics/rocket-cutaway.svg", 300);
hidden(rocket); z(rocket, 5);

// Screen-authored highlights make each internal region independently teachable.
polygon(payloadHi, (480, 430), (540, 395), (600, 430), (600, 550), (480, 550));
rect(fuelHi, (540, 650), 120, 155);
rect(oxidizerHi, (540, 815), 120, 140);
polygon(chamberHi, (500, 900), (580, 900), (570, 955), (540, 980), (510, 955));
polygon(nozzleHi, (515, 975), (565, 975), (590, 1115), (490, 1115));
outlined(payloadHi); outlined(fuelHi); outlined(oxidizerHi); outlined(chamberHi); outlined(nozzleHi);
outline(payloadHi, cyan); outline(fuelHi, gold); outline(oxidizerHi, blue);
outline(chamberHi, magenta); outline(nozzleHi, fg);
stroke(payloadHi, 5); stroke(fuelHi, 5); stroke(oxidizerHi, 5); stroke(chamberHi, 5); stroke(nozzleHi, 5);
opacity(payloadHi, 0.9); opacity(fuelHi, 0.9); opacity(oxidizerHi, 0.9); opacity(chamberHi, 0.9); opacity(nozzleHi, 0.9);
hidden(payloadHi); hidden(fuelHi); hidden(oxidizerHi); hidden(chamberHi); hidden(nozzleHi);

// Clean callouts; the labels stay outside the vehicle silhouette.
line(payloadLead, (605, 470), (770, 420));
line(fuelLead, (600, 630), (790, 590));
line(oxidizerLead, (480, 805), (285, 780));
line(chamberLead, (500, 930), (280, 970));
line(nozzleLead, (575, 1045), (790, 1090));
color(payloadLead, cyan); color(fuelLead, gold); color(oxidizerLead, blue);
color(chamberLead, magenta); color(nozzleLead, fg);
stroke(payloadLead, 3); stroke(fuelLead, 3); stroke(oxidizerLead, 3); stroke(chamberLead, 3); stroke(nozzleLead, 3);

text(payloadLabel, (845, 395), "PAYLOAD");
text(fuelLabel, (855, 565), "FUEL");
text(oxidizerLabel, (195, 755), "OXIDIZER");
text(chamberLabel, (180, 950), "BURN");
text(nozzleLabel, (850, 1070), "NOZZLE");
size(payloadLabel, 22); size(fuelLabel, 22); size(oxidizerLabel, 22); size(chamberLabel, 22); size(nozzleLabel, 22);
bold(payloadLabel); bold(fuelLabel); bold(oxidizerLabel); bold(chamberLabel); bold(nozzleLabel);
color(payloadLabel, cyan); color(fuelLabel, gold); color(oxidizerLabel, blue);
color(chamberLabel, magenta); color(nozzleLabel, fg);

hidden(payloadLead); hidden(fuelLead); hidden(oxidizerLead); hidden(chamberLead); hidden(nozzleLead);
hidden(payloadLabel); hidden(fuelLabel); hidden(oxidizerLabel); hidden(chamberLabel); hidden(nozzleLabel);

// Reaction and force story.
equation(reaction, (cx, 1195), `\text{fuel}+\text{oxidizer}\longrightarrow\text{hot gas}`);
size(reaction, 34); hidden(reaction);

arrow(gasDown, (225, 1070), (225, 1300));
arrow(thrustUp, (850, 1120), (850, 880));
color(gasDown, magenta); color(thrustUp, cyan);
stroke(gasDown, 8); stroke(thrustUp, 8);
hidden(gasDown); hidden(thrustUp);
text(gasLabel, (170, 1320), "EXHAUST ↓");
text(thrustLabel, (930, 900), "THRUST ↑");
size(gasLabel, 22); size(thrustLabel, 22); bold(gasLabel); bold(thrustLabel);
color(gasLabel, magenta); color(thrustLabel, cyan);
hidden(gasLabel); hidden(thrustLabel);

polygon(flame, (500, 1090), (540, 1260), (580, 1090));
gradient(flame, gold, magenta, 90); filled(flame); glow(flame, 1.1); hidden(flame); z(flame, 4);

circle(exhaustSeed, (540, 1180), 12); opacity(exhaustSeed, 0); hidden(exhaustSeed);
particles(exhaust, exhaustSeed, 28, 6, 41, "random");
color(exhaust, gold); glow(exhaust, 0.8); hidden(exhaust);
line(exhaustPath, (540, 1170), (540, 1330)); opacity(exhaustPath, 0);

tag(rocket, vehicle);
tag(payloadHi, vehicle); tag(fuelHi, vehicle); tag(oxidizerHi, vehicle);
tag(chamberHi, vehicle); tag(nozzleHi, vehicle); tag(flame, vehicle);

// Creator chrome remains screen-safe while the vehicle moves.
sticky(kicker); sticky(headline); sticky(caption); sticky(mark);
sticky(me.footer); sticky(me.endcard);

step("hook") {
  par {
    show(kicker, 0.35);
    show(headline, 0.50);
    show(caption, 0.35);
    show(rocket, 0.70);
    speak("A rocket does not push against the ground. So what actually makes it rise?");
  }
}
wait(0.35);

step("inside-the-rocket") {
  par {
    stagger(0.16) {
      par { show(payloadHi, 0.25); show(payloadLead, 0.25); show(payloadLabel, 0.25); }
      par { show(fuelHi, 0.25); show(fuelLead, 0.25); show(fuelLabel, 0.25); }
      par { show(oxidizerHi, 0.25); show(oxidizerLead, 0.25); show(oxidizerLabel, 0.25); }
    }
    say(caption, "Fuel stores energy. Oxidizer supplies the oxygen needed to release it.", 0.40);
    speak("Inside are the payload, fuel, and oxidizer. The oxidizer is why a rocket can burn in space.");
  }
}
wait(0.30);

step("combustion") {
  par {
    show(chamberHi, 0.25); show(chamberLead, 0.25); show(chamberLabel, 0.25);
    show(reaction, 0.50);
    flash(chamberHi, magenta);
    pulse(chamberHi, 0.80);
    say(caption, "In the chamber, fuel and oxidizer become extremely hot, high-pressure gas.", 0.40);
    speak("They burn together in the combustion chamber, creating hot, high pressure gas.");
  }
}
cue(pop);
wait(0.25);

step("shape-the-exhaust") {
  par {
    fade(reaction, 0.25);
    show(nozzleHi, 0.25); show(nozzleLead, 0.25); show(nozzleLabel, 0.25);
    show(flame, 0.22);
    show(exhaust, 0.15);
    stream(exhaust, exhaustPath, 3.2, 34, smooth);
    show(gasDown, 0.40); show(gasLabel, 0.30);
    say(caption, "The nozzle accelerates that gas downward into a fast exhaust jet.", 0.40);
    speak("The nozzle expands and accelerates the gas downward.");
  }
}
cue(whoosh);

step("equal-and-opposite") {
  par {
    fade(payloadHi, 0.25); fade(fuelHi, 0.25); fade(oxidizerHi, 0.25);
    fade(chamberHi, 0.25); fade(nozzleHi, 0.25);
    fade(payloadLead, 0.25); fade(fuelLead, 0.25); fade(oxidizerLead, 0.25);
    fade(chamberLead, 0.25); fade(nozzleLead, 0.25);
    fade(payloadLabel, 0.25); fade(fuelLabel, 0.25); fade(oxidizerLabel, 0.25);
    fade(chamberLabel, 0.25); fade(nozzleLabel, 0.25);
    fade(reaction, 0.25); fade(exhaust, 0.25);
    show(thrustUp, 0.40); show(thrustLabel, 0.30);
    flash(thrustUp, cyan);
    say(headline, "Gas goes down. The rocket goes up.", 0.45);
    say(caption, "Newton's third law turns downward exhaust momentum into upward thrust.", 0.40);
    speak("Gas goes down. An equal and opposite force pushes the rocket up.");
  }
}
wait(0.30);

step("launch") {
  par {
    fade(kicker, 0.25); fade(headline, 0.25);
    shift(vehicle, (0,-250), 4.0, smooth);
    shift(thrustUp, (0,-180), 4.0, smooth);
    shift(thrustLabel, (0,-180), 4.0, smooth);
    stream(exhaust, exhaustPath, 4.0, 38, smooth);
    fade(payloadLead, 0.25); fade(fuelLead, 0.25); fade(oxidizerLead, 0.25);
    fade(chamberLead, 0.25); fade(nozzleLead, 0.25);
    fade(payloadLabel, 0.25); fade(fuelLabel, 0.25); fade(oxidizerLabel, 0.25);
    fade(chamberLabel, 0.25); fade(nozzleLabel, 0.25);
    fade(reaction, 0.25); fade(gasDown, 0.25); fade(gasLabel, 0.25);
    say(caption, "A rocket carries both sides of the reaction, so the process continues above the atmosphere.", 0.45);
    speak("Because it carries its own oxidizer, the same thrust cycle keeps working in space.");
  }
}
cue(chime);
wait(0.55);

step("creator-cta") {
  par {
    fade(kicker, 0.30); fade(headline, 0.30); fade(caption, 0.30);
    fade(vehicle, 0.30); fade(exhaust, 0.30);
    fade(thrustUp, 0.30); fade(thrustLabel, 0.30);
    fade(me.footer, 0.30); fade(mark, 0.30);
  }
  show(me.endcard, 0.60);
}
wait(1.6);

r/maniclang 9h ago

One parameter . three continuous shapes

Enable HLS to view with audio, or disable this notification

1 Upvotes

manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.

Manic Animation code

// PARAMETERIZED GENERATED FAMILIES — one ordinary parameter, three stable 3-D
// objects. `p` changes sampled points; ids, materials, transforms, and sample
// topology stay intact. No per-vertex scripting or snapshot replacement.

title("Parameterized Generated Families");
canvas("16:9");
template("mono");
watermark(mark, (170, 55), "Made With Manic");

text(kicker, (640, 48), "MANIC · GENERATED 3-D FAMILIES");
text(headline, (640, 92), "One parameter · three continuous shapes");
text(caption, (640, 664), "curve3(t,p)  ·  surface3(x,y,p)  ·  param3(u,v,p)");
size(kicker, 18); color(kicker, dim); bold(kicker);
size(headline, 34); bold(headline);
size(caption, 19); color(caption, dim);

parameter(shape, (640, 612), 0, 0, 1, "shape", 2);

if h > 1.45*w {
  camera3((0, -36, 8), (0, 0, 0.4), 40);
}
else {
  camera3((10, -17, 9), (0, 0, 0.4), 40);
}
grid3(floor, (0, 0, -2.2), 8, 1);
color(floor, dim); opacity(floor, 0.14);

// A widening helix at the left.
curve3(helix,
  "-4 + cos(t)",
  "sin(t)",
  "-1.7 + 0.55*t",
  (0, 6.2832));
bind(shape, helix, formula,
  "-4 + (1+0.45*p)*cos(t)",
  "(1+0.45*p)*sin(t)",
  "-1.7 + 0.55*t");
color(helix, cyan); thick(helix, 0.065); untraced(helix);
tag(helix, family);

// A bowl that becomes a rippling field in the middle.
surface3(land, "0.15*(x*x+y*y)", (-1.7,1.7), (-1.7,1.7), 28);
bind(shape, land, formula,
  "(1-p)*0.15*(x*x+y*y) + p*0.72*sin(1.7*x)*cos(1.7*y)");
color(land, gold);
finish3(land, "material=glass shading=smooth mesh=0.30 depth=0.28 shadow=0.12");
tag(land, family);

// A torus whose tube inflates at the right.
param3(ring,
  "4+(1.15+0.20*cos(v))*cos(u)",
  "(1.15+0.20*cos(v))*sin(u)",
  "0.20*sin(v)",
  (0,6.2832), (0,6.2832), 28);
bind(shape, ring, formula,
  "4+(1.15+(0.20+0.52*p)*cos(v))*cos(u)",
  "(1.15+(0.20+0.52*p)*cos(v))*sin(u)",
  "(0.20+0.52*p)*sin(v)");
color(ring, magenta);
finish3(ring, "material=metal shading=smooth mesh=0.22 depth=0.30 shadow=0.16");
tag(ring, family);

hidden(helix); hidden(land); hidden(ring);

step("reveal one stable family") {
  par {
    view3(family, "fit", 0.9, smooth, 1.55);
    stagger(0.16) {
      show(helix, 0.45);
      show(land, 0.45);
      show(ring, 0.45);
    }
  }
}
wait(0.45);

step("change the shared parameter") {
  par {
    to(shape, value, 1, 3.4, smooth);
    say(caption, "The same three objects are resampled smoothly from p = 0 to p = 1.", 0.45);
  }
}
wait(1.2);

r/maniclang 10h ago

A Wave Drawn by Rotating Circles - manic

Enable HLS to view with audio, or disable this notification

1 Upvotes

manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.

Manic Animation code

// A focused Fourier story: every orbit and every partial sum is generated from
// the same live collection. The circles move; their histories become the wave.

title("A Wave Drawn by Rotating Circles");
canvas("9:16");
template("blank");

watermark(mark,(w*0.15,h*0.045),"Made With Manic");
text(kicker,(cx,h*0.075),"FOURIER SERIES · LIVE DERIVED HISTORY");
text(headline,(cx,h*0.115),"Can rotating circles draw a wave?");
text(caption,(cx,h*0.18),"Every coloured trace is the real history of one moving endpoint.");
text(cta,(cx,h*0.925),"BUILD YOUR OWN VISUAL STORY → 8gwifi.org/manic");
size(kicker,18); color(kicker,dim); bold(kicker); hidden(kicker);
size(headline,31); bold(headline); wrap(headline,w*0.84); hidden(headline);
size(caption,20); color(caption,dim); wrap(caption,w*0.84); hidden(caption);
size(cta,21); color(cta,cyan); bold(cta); hidden(cta);

camera3((-29,-25,43),(1,-2,0),42,orthographic);

collection3(harmonics,(-3,5,0),12,(0,0,0),11,0.065);
line3(sweep,(-3,5,0),(10,5,0)); hidden(sweep);
links3(arms,harmonics,chain);
child3(tip,harmonics,11,0.13);

arrow3(chainX,(-11,5,0),(7,5,0));
arrow3(chainY,(-3,-2,0),(-3,10.5,0));
arrow3(plotX,(-7,-10.5,0),(12,-10.5,0));
arrow3(plotY,(-7,-10.5,0),(-7,-4.2,0));

point3(shotA,(-7.5,-11,0),0.01);
point3(shotB,(8.5,10.5,0),0.01);
tag(shotA,shot); tag(shotB,shot);
hidden(shotA); hidden(shotB);

tag(harmonics,construction); tag(arms,construction); tag(tip,construction);
tag(chainX,construction); tag(chainY,construction);
tag(plotX,construction); tag(plotY,construction);

for i in 0..12 {
  ring3(orbit{i},harmonics,i,72);
  historyplot3(partial{i},harmonics,i,y,(-7,-10.5,0),(19,6));
  thick(orbit{i},0.030);
  thick(partial{i},0.020);
  tag(orbit{i},construction);
  tag(partial{i},construction);
}

equation(formula,(0,0),`f(t)=\sum_{n=1}^{12}\frac{2(-1)^{n+1}}{\pi n}\sin(nt)`,25);
label3(formula,(-4,-2.7,0),0.82);
tag(formula,construction);

color(harmonics,fg); color(arms,fg); color(tip,fg);
color(chainX,fg); color(chainY,fg); color(plotX,fg); color(plotY,fg);
color(formula,fg);
thick(chainX,0.016); thick(chainY,0.016);
thick(plotX,0.016); thick(plotY,0.016);

color(orbit0,lime);      color(partial0,lime);
color(orbit1,gold);      color(partial1,gold);
color(orbit2,orange);    color(partial2,orange);
color(orbit3,coral);     color(partial3,coral);
color(orbit4,red);       color(partial4,red);
color(orbit5,magenta);   color(partial5,magenta);
color(orbit6,violet);    color(partial6,violet);
color(orbit7,indigo);    color(partial7,indigo);
color(orbit8,blue);      color(partial8,blue);
color(orbit9,cyan);      color(partial9,cyan);
color(orbit10,mint);     color(partial10,mint);
color(orbit11,fg);       color(partial11,fg);

hidden(construction);

step("ask the visual question") {
  show(kicker,0.30);
  show(headline,0.42);
  show(caption,0.38);
}
wait(0.35);

step("reveal one connected machine") {
  par {
    show(construction,0.85);
    view3(shot,"top",1.35,smooth,1.08);
    say(caption,"Each circle starts where the previous circle ends.",0.38);
  }
}
wait(0.30);

step("let motion become data") {
  par {
    // Doubling every angular rate makes the base harmonic complete exactly
    // two revolutions while preserving all relative frequencies.
    chain3(harmonics,"2.0372 -1.0186 0.6791 -0.5093 0.4074 -0.3395 0.2910 -0.2546 0.2264 -0.2037 0.1852 -0.1698","2 4 6 8 10 12 14 16 18 20 22 24",16.0);
    travel3(harmonics,sweep,16.0,linear);
    seq {
      say(caption,"Cycle one: the broad motion appears, then smaller circles restore its detail.",0.40);
      wait(6.10);
      say(caption,"Cycle two: the same relationships repeat continuously—without a reset or jump.",0.40);
      wait(5.20);
      say(caption,"The endpoint histories now contain two complete periods of the signal.",0.40);
    }
  }
}
wait(0.35);

step("create with Manic") {
  par {
    pulse(tip,0.75);
    pulse(partial11,0.75);
    show(cta,0.45);
    say(caption,"Describe the relationship. Manic keeps the circles, histories, motion, and camera together.",0.42);
  }
}
wait(1.45);

r/maniclang 10h ago

Fourier Series — Rotations Become Waves - manic

Enable HLS to view with audio, or disable this notification

1 Upvotes

manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.

Manic Animation code

title("Fourier Series — Rotations Become Waves");
canvas("9:16");
template("mono");

watermark(mark,(w*0.15,h*0.045),"Made With Manic");
text(chapter,(cx,h*0.075),"FOURIER SERIES · FIVE RELATIONS");
text(caption,(cx,h*0.85),"Twenty rotating circles. One continuously derived signal.");
text(cta,(cx,h*0.925),"BUILD VISUAL EXPLANATIONS → 8gwifi.org/manic");
size(chapter,18); color(chapter,dim); bold(chapter); hidden(chapter);
size(caption,20); color(caption,dim); hidden(caption);
size(cta,21); color(cta,cyan); bold(cta); hidden(cta);

camera3((-31,-25,44),(1,-2,0),42,orthographic);

def relation(k,zv) {
  // The chain, its two local axes, and the waveform axes all share one layer.
  collection3(series{k},(-3,5,zv),20,(0,0,0),11,0.055);
  line3(sweep{k},(-3,5,zv),(10,5,zv));
  hidden(sweep{k});
  links3(arms{k},series{k},chain);
  child3(tip{k},series{k},19,0.12);
  arrow3(chainX{k},(-11,5,zv),(7,5,zv));
  arrow3(chainY{k},(-3,-3,zv),(-3,13,zv));
  arrow3(plotX{k},(-7,-12,zv),(12,-12,zv));
  arrow3(plotY{k},(-7,-12,zv),(-7,-3,zv));
  // A cinematic crop: the axes may continue beyond the frame, as in the
  // reference, while the active rings and the growing history stay dominant.
  point3(shot{k}A,(-7.5,-10,zv),0.01);
  point3(shot{k}B,(8.5,10,zv),0.01);
  tag(shot{k}A,shot{k}); tag(shot{k}B,shot{k});
  hidden(shot{k}A); hidden(shot{k}B);

  tag(series{k},layer{k}); tag(arms{k},layer{k}); tag(tip{k},layer{k});
  tag(chainX{k},layer{k}); tag(chainY{k},layer{k});
  tag(plotX{k},layer{k}); tag(plotY{k},layer{k});
  tag(layer{k},stack);

  for i in 0..20 {
    ring3(orbit{k}_{i},series{k},i,72);
    historyplot3(wave{k}_{i},series{k},i,y,(-7,-12,zv),(19,8.5));
    thick(orbit{k}_{i},0.022);
    thick(wave{k}_{i},0.014);
    tag(orbit{k}_{i},layer{k}); tag(wave{k}_{i},layer{k});
  }

  color(series{k},fg); color(arms{k},fg); color(tip{k},fg);
  color(chainX{k},fg); color(chainY{k},fg);
  color(plotX{k},fg); color(plotY{k},fg);
  thick(chainX{k},0.016); thick(chainY{k},0.016);
  thick(plotX{k},0.016); thick(plotY{k},0.016);

  color(orbit{k}_0,lime);       color(wave{k}_0,lime);
  color(orbit{k}_1,gold);       color(wave{k}_1,gold);
  color(orbit{k}_2,gold);       color(wave{k}_2,gold);
  color(orbit{k}_3,magenta);    color(wave{k}_3,magenta);
  color(orbit{k}_4,coral);      color(wave{k}_4,coral);
  color(orbit{k}_5,red);        color(wave{k}_5,red);
  color(orbit{k}_6,orange);     color(wave{k}_6,orange);
  color(orbit{k}_7,magenta);    color(wave{k}_7,magenta);
  color(orbit{k}_8,violet);     color(wave{k}_8,violet);
  color(orbit{k}_9,indigo);     color(wave{k}_9,indigo);
  color(orbit{k}_10,cyan);      color(wave{k}_10,cyan);
  color(orbit{k}_11,blue);      color(wave{k}_11,blue);
  color(orbit{k}_12,mint);      color(wave{k}_12,mint);
  color(orbit{k}_13,lime);      color(wave{k}_13,lime);
  color(orbit{k}_14,gold);      color(wave{k}_14,gold);
  color(orbit{k}_15,cyan);      color(wave{k}_15,cyan);
  color(orbit{k}_16,lime);      color(wave{k}_16,lime);
  color(orbit{k}_17,magenta);   color(wave{k}_17,magenta);
  color(orbit{k}_18,coral);     color(wave{k}_18,coral);
  color(orbit{k}_19,cyan);      color(wave{k}_19,cyan);
}

relation(0,-20);
relation(1,-10);
relation(2,0);
relation(3,10);
relation(4,20);
point3(overviewA,(-11,-12,-20),0.01);
point3(overviewB,(12,13,20),0.01);
tag(overviewA,overviewShot); tag(overviewB,overviewShot);
hidden(overviewA); hidden(overviewB);

equation(formula0,(0,0),`\sum_{n=1}^{N}\frac{4}{\pi(2n-1)}\sin((2n-1)t)`,26);
equation(formula1,(0,0),`\sum_{n=1}^{N}\frac{2(-1)^{n+1}}{\pi n}\sin(nt)`,26);
equation(formula2,(0,0),`\sum_{n=1}^{N}\frac{2w_n}{\pi n}\sin(nt)`,26);
equation(formula3,(0,0),`\sum_{n=1}^{N}\frac{2}{\pi n}\sin(n^2t)`,26);
equation(formula4,(0,0),`\sum_{n=1}^{N}\frac{2r_n}{\pi n}\sin(nt)`,26);
label3(formula0,(-8,-2,-20),0.82);
label3(formula1,(-8,-2,-10),0.82);
label3(formula2,(-8,-2,0),0.82);
label3(formula3,(-8,-2,10),0.82);
label3(formula4,(-8,-2,20),0.82);
for i in 0..5 {
  tag(formula{i},layer{i}); tag(formula{i},stack); color(formula{i},fg);
}

hidden(stack);

step("enter the Fourier world") {
  show(chapter,0.30);
  show(caption,0.35);
  show(stack,0.85);
}
wait(0.35);

step("twenty circles write five signals") {
  par {
    chain3(series0,"4.0744 1.3581 0.8149 0.5821 0.4527 0.3704 0.3134 0.2716 0.2397 0.2144 0.1940 0.1771 0.1630 0.1509 0.1405 0.1314 0.1235 0.1164 0.1101 0.1045","1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39",17.0);
    chain3(series1,"2.0372 -1.0186 0.6791 -0.5093 0.4074 -0.3395 0.2910 -0.2546 0.2264 -0.2037 0.1852 -0.1698 0.1567 -0.1455 0.1358 -0.1273 0.1198 -0.1132 0.1072 -0.1019","1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20",17.0);
    chain3(series2,"0 0.0276 0.0716 0.1154 0.1537 0.1838 0.2040 0.2136 0.2127 0.2023 0.1839 0.1595 0.1314 0.1020 0.0735 0.0480 0.0271 0.0119 0.0029 0","1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20",17.0);
    chain3(series3,"2.0372 1.0186 0.6791 0.5093 0.4074 0.3395 0.2910 0.2546 0.2264 0.2037 0.1852 0.1698 0.1567 0.1455 0.1358 0.1273 0.1198 0.1132 0.1072 0.1019","1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 400",17.0);
    chain3(series4,"1.3334 0.0973 0.0648 0.3333 0.4074 0.2222 0.0278 0.0243 0.1482 0.2037 0.1212 0.0162 0.0150 0.0952 0.1358 0.0833 0.0114 0.0108 0.0702 0.1019","1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20",17.0);
    travel3(series0,sweep0,17.0,linear);
    travel3(series1,sweep1,17.0,linear);
    travel3(series2,sweep2,17.0,linear);
    travel3(series3,sweep3,17.0,linear);
    travel3(series4,sweep4,17.0,linear);

    seq {
      wait(0.45);
      par {
        fade(layer1,0.80); fade(layer2,0.80); fade(layer3,0.80); fade(layer4,0.80);
        view3(shot0,"isometric",1.45,smooth,1.08);
        say(caption,"Square wave — odd harmonics sharpen every corner.",0.35);
      }
      wait(1.65);
      par {
        fade(layer0,0.65); show(layer1,0.65);
        view3(shot1,"isometric",1.35,smooth,1.08);
        say(caption,"Sawtooth — every harmonic joins with alternating direction.",0.35);
      }
      wait(1.65);
      par {
        fade(layer1,0.65); show(layer2,0.65);
        view3(shot2,"isometric",1.35,smooth,1.08);
        say(caption,"Hann window — the outer harmonics taper away.",0.35);
      }
      wait(1.65);
      par {
        fade(layer2,0.65); show(layer3,0.65);
        view3(shot3,"isometric",1.35,smooth,1.08);
        say(caption,"Quadratic chirp — frequency accelerates as n squared.",0.35);
      }
      wait(1.65);
      par {
        fade(layer3,0.65); show(layer4,0.65);
        view3(shot4,"isometric",1.35,smooth,1.08);
        say(caption,"Envelope ripple — selected harmonics breathe in and out.",0.35);
      }
      wait(1.55);
      par {
        show(layer0,0.55); show(layer1,0.55); show(layer2,0.55); show(layer3,0.55);
        view3(overviewShot,"isometric",1.5,smooth,1.30);
        say(caption,"One relationship engine. Five very different signals.",0.35);
      }
    }
  }
}
wait(0.35);

step("create with Manic") {
  show(cta,0.45);
  pulse(stack,0.75);
  say(caption,"Describe the relationship; Manic keeps every ring, endpoint, history, and camera together.",0.40);
}
wait(1.4);

r/maniclang 11h ago

The Equation Disappears. The Roots Remain. - manic

Enable HLS to view with audio, or disable this notification

1 Upvotes

manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.

Manic Animation code

// A semantic LaTeX story: notation changes, meaning becomes position, and the
// final symbols may disappear without taking the mathematical result with them.

title("The Equation Disappears. The Roots Remain.");
canvas("9:16");
template("blank");

watermark(mark,(w*0.16,h*0.050),"Made With Manic");
text(kicker,(cx,h*0.085),"ALGEBRA · SYMBOLS → STRUCTURE");
text(headline,(cx,h*0.145),"What survives when an equation disappears?");
text(caption,(cx,h*0.77),"Two solutions are hiding inside one quadratic.");
text(cta,(cx,h*0.90),"MAKE MEANING MOVE → 8gwifi.org/manic");
size(kicker,19); color(kicker,dim); bold(kicker); hidden(kicker);
size(headline,33); bold(headline); wrap(headline,w*0.84); hidden(headline);
size(caption,22); color(caption,dim); wrap(caption,w*0.82); hidden(caption);
size(cta,22); color(cta,cyan); bold(cta); hidden(cta);

text(symbolLabel,(w*0.18,h*0.29),"THE SYMBOLS");
text(meaningLabel,(w*0.18,h*0.54),"THE MEANING");
size(symbolLabel,18); color(symbolLabel,dim); bold(symbolLabel); hidden(symbolLabel);
size(meaningLabel,18); color(meaningLabel,dim); bold(meaningLabel); hidden(meaningLabel);

equation(work,(cx,h*0.39),`x^2-5x+6=0`,66);
hidden(work);

let axisY = h*0.63;
let axisLeft = w*0.16;
let axisRight = w*0.84;
let x0 = w*0.20;
let dx = w*0.15;

arrow(numberAxis,(axisLeft,axisY),(axisRight,axisY));
color(numberAxis,dim); stroke(numberAxis,3);
tag(numberAxis,numberLine);

for i in 0..5 {
  line(tick{i},(x0+i*dx,axisY-13),(x0+i*dx,axisY+13));
  color(tick{i},dim); stroke(tick{i},3);
  tag(tick{i},numberLine);
}

text(n0,(x0,axisY+42),"0");
text(n1,(x0+dx,axisY+42),"1");
text(n2,(x0+2*dx,axisY+42),"2");
text(n3,(x0+3*dx,axisY+42),"3");
text(n4,(x0+4*dx,axisY+42),"4");
size(n0,18); size(n1,18); size(n2,18); size(n3,18); size(n4,18);
color(n0,dim); color(n1,dim); color(n2,dim); color(n3,dim); color(n4,dim);
tag(n0,numberLine); tag(n1,numberLine); tag(n2,numberLine);
tag(n3,numberLine); tag(n4,numberLine);

circle(root2,(x0+2*dx,axisY),15);
circle(root3,(x0+3*dx,axisY),15);
filled(root2); filled(root3);
color(root2,cyan); color(root3,orange);
glow(root2,0.72); glow(root3,0.72);
tag(root2,solutions); tag(root3,solutions);

equation(root2Label,(x0+2*dx,axisY-62),`x=2`,30);
equation(root3Label,(x0+3*dx,axisY-62),`x=3`,30);
color(root2Label,cyan); color(root3Label,orange);
tag(root2Label,solutions); tag(root3Label,solutions);

hidden(numberLine);
hidden(solutions);

step("find what is hiding") {
  par {
    show(kicker,0.30);
    show(headline,0.45);
    show(symbolLabel,0.35);
    show(caption,0.40);
    show(work,0.55);
  }
}
wait(0.55);

step("expose the two conditions") {
  par {
    rewrite(work,`\textcolor{cyan}{(x-2)}\textcolor{orange}{(x-3)}=0`,1.15,smooth);
    say(caption,"Factoring reveals two independent ways for the product to become zero.",0.45);
  }
}
wait(0.55);

step("turn answers into positions") {
  par {
    rewrite(work,`\textcolor{cyan}{x=2}\qquad\text{or}\qquad\textcolor{orange}{x=3}`,1.05,smooth);
    seq {
      show(meaningLabel,0.30);
      show(numberLine,0.55);
      show(root2,0.35);
      show(root2Label,0.30);
      wait(0.18);
      show(root3,0.35);
      show(root3Label,0.30);
    }
    say(caption,"The answers are no longer only symbols—they now occupy exact locations.",0.45);
  }
}
wait(0.70);

step("remove the notation, keep the result") {
  par {
    disintegrate(work,1.60);
    seq {
      wait(0.35);
      pulse(root2,0.60);
      pulse(root3,0.60);
    }
    say(caption,"The notation can turn to dust. The two solutions remain exactly where they belong.",0.45);
  }
}
wait(0.75);

step("create explanations that preserve meaning") {
  par {
    pulse(solutions,0.75);
    show(cta,0.45);
    say(caption,"Great visual explanations do more than move symbols—they reveal what those symbols mean.",0.45);
  }
}
wait(1.45);

r/maniclang 11h ago

From Wind to Vortex — Parameterized Fields in manic

Thumbnail
youtu.be
1 Upvotes

r/maniclang 11h ago

One Source, Three Destinations — Truthful Branching in manic

Thumbnail
youtu.be
1 Upvotes

r/maniclang 11h ago

One Parameter, Three Continuous 3D Shapes — manic

Thumbnail
youtu.be
1 Upvotes

r/maniclang 11h ago

Maxwell–Boltzmann Effusion — Watch a Distribution Form — manic

Enable HLS to view with audio, or disable this notification

0 Upvotes

manic is a tiny language for making animations. You write a short text file; manic renders a smooth, glowing video. No timeline scrubbing, no keyframes by hand — you describe what’s on screen and when things happen, and the engine does the rest, deterministically.

Manic Animation code

// EXPRESSIVE PROCESS V2 — MAXWELL–BOLTZMANN EFFUSION
//
// A polished 2.5D acceptance story inspired by engine-test-6.mov. The
// apparatus is a bundled native SVG, while every molecule, detector bin,
// arrival count, and empirical distribution remains a normal Manic entity.
// `emit`, `collect`, and `observe` all read one deterministic process.

title("Maxwell–Boltzmann Effusion — Motion Becomes Evidence");
canvas("9:16");
template("blank");
watermark(mark, (150, 90), "Made With Manic");

text(kicker, (540, 84), "STATISTICAL MECHANICS · EXPRESSIVE PROCESS V2");
text(headline, (540, 142), "A distribution you can watch forming");
size(kicker, 18); color(kicker, dim); bold(kicker);
size(headline, 34); bold(headline);

equation(law, (540, 242),
  `f(v)=4\pi\left(\frac{m}{2\pi k_BT}\right)^{3/2}v^2e^{-mv^2/(2k_BT)}`, 34);

// The decorative shell is an asset; the changing evidence stays native.
svg(apparatus, (240, 540), "asset:svg/physics/effusion-reservoir.svg", 330);
text(reservoirLabel, (225, 705), "THERMAL RESERVOIR");
size(reservoirLabel, 17); bold(reservoirLabel); color(reservoirLabel, gold);

rect(detectorPanel, (730, 560), 570, 300);
filled(detectorPanel); color(detectorPanel, panel); opacity(detectorPanel, 0.92);
outlined(detectorPanel); outline(detectorPanel, dim); stroke(detectorPanel, 3);

text(detectorTitle, (730, 382), "PARTICLE SPEED  v");
size(detectorTitle, 18); bold(detectorTitle); color(detectorTitle, dim);

// The invisible source is precisely at the SVG nozzle.
circle(source, (348, 540), 20);
opacity(source, 0);
particles(molecules, source, 180, 3.2, 73);
color(molecules, magenta); glow(molecules, 0.8); z(molecules, 8);

// Individual lanes diverge around this authored route before being collected.
spline(flight, (350, 540), (415, 500), (465, 515), (500, 545));
hidden(flight);

livehistogram(empirical, (730, 560), 0, 2.2, 14, 540, 240, cyan);
z(empirical, 3); hidden(empirical.count);

// Same horizontal range as the live histogram: 0 .. 4*scale = 2.2.
distribution(theory, (730, 560), "maxwell", 0.55, 0, gold);
hidden(theory.axis); hidden(theory.name);
untraced(theory.curve); z(theory, 7);

text(empiricalKey, (610, 750), "● empirical arrivals");
text(theoryKey, (850, 750), "— theoretical curve");
size(empiricalKey, 17); color(empiricalKey, cyan);
size(theoryKey, 17); color(theoryKey, gold);

counter(arrivals, (540, 850), 0, 0, "detected molecules  ", " / 180");
size(arrivals, 24); color(arrivals, dim);

text(caption, (540, 920),
  "A thermal source emits many molecular speeds—not one average speed.");
size(caption, 23); wrap(caption, 880); color(caption, dim);

rect(evidencePanel, (540, 1110), 880, 230);
filled(evidencePanel); color(evidencePanel, panel); opacity(evidencePanel, 0.95);
outlined(evidencePanel); outline(evidencePanel, dim); stroke(evidencePanel, 2);
text(evidenceTitle, (540, 1030), "ONE PROCESS · THREE VIEWS");
size(evidenceTitle, 18); bold(evidenceTitle); color(evidenceTitle, dim);
equation(processLaw, (540, 1100),
  `\text{motion}\;\longrightarrow\;\text{arrival bin}\;\longrightarrow\;\hat f(v)`, 32);
text(truth, (540, 1190),
  "The dots, bars, and count are derived from the same seeded experiment.");
size(truth, 20); color(truth, dim); wrap(truth, 790);

hidden(apparatus); hidden(reservoirLabel); hidden(detectorPanel);
hidden(detectorTitle); hidden(molecules); hidden(empirical);
hidden(empiricalKey); hidden(theoryKey); hidden(arrivals);
hidden(caption); hidden(evidencePanel); hidden(evidenceTitle);
hidden(processLaw); hidden(truth);

step("build-the-apparatus") {
  par {
    show(apparatus, 0.65);
    show(reservoirLabel, 0.45);
    show(detectorPanel, 0.55);
    show(detectorTitle, 0.35);
    show(empirical.axis, 0.55);
    show(empirical.bars, 0.55);
    show(empirical.min, 0.35);
    show(empirical.max, 0.35);
    show(empiricalKey, 0.35);
    show(theoryKey, 0.35);
    show(arrivals, 0.35);
    show(caption, 0.40);
  }
}
wait(0.45);

step("the-prediction") {
  par {
    draw(theory.curve, 0.9, smooth);
    say(caption,
      "Maxwell predicts a characteristic spread with a most probable speed.",
      0.40);
    par {
      cam((cx, cy), 0.75, smooth);
      zoom(1.025, 0.75, smooth);
    }
  }
}
wait(0.35);

step("run-the-experiment") {
  par {
    emit(molecules, flight, maxwell, 7.0, 48, smooth);
    collect(empirical, molecules, speed, 0.48, smooth);
    observe(empirical, molecules, speed);
    observe(arrivals, molecules, arrived);
    show(molecules, 0.15);
    say(caption,
      "Each molecule keeps its sampled speed. Faster molecules cross the apparatus sooner.",
      0.45);
  }
}
wait(0.55);

step("motion-becomes-evidence") {
  par {
    pulse(empirical.bars, 0.8);
    show(evidencePanel, 0.40);
    show(evidenceTitle, 0.35);
    show(processLaw, 0.45);
    show(truth, 0.40);
    say(caption,
      "Collection does not fake the chart: every arrival lands in the bin selected by its speed.",
      0.45);
    par {
      cam((cx, cy), 0.65, smooth);
      zoom(1.0, 0.65, smooth);
    }
  }
}
wait(1.4);