Skip to content

irxmanim: short animations with no dependencies and no script - #49

Merged
tamnd merged 1 commit into
mainfrom
irxmanim
Sep 6, 2026
Merged

tamnd merged 1 commit into
mainfrom
irxmanim

Conversation

@tamnd

@tamnd tamnd commented Sep 6, 2026

Copy link
Copy Markdown
Owner

The animation library from #10. It takes manim's vocabulary, mobjects and a
scene and play for one beat of it, and none of manim's implementation:
manim renders video, which wants cairo, ffmpeg and usually a LaTeX install,
and none of that fits in the first cell of a Colab notebook or survives
being saved into one. What comes out of here is one inline <svg> with a
stylesheet in it.

from irxmanim import Scene, Code, fade_in, fade_out, highlight, move

s = Scene(430, 208, caption="opt -passes=dce deletes the instruction nothing reads")
code = s.add(Code(x=36, y=58, lines=before))
s.play(fade_in(code))
s.play(highlight(code[2]))
s.play(fade_out(code[2]))
s.play(move(code[3], dy=-17), move(code[4], dy=-17))

Mobjects: Box, Code, Caption, Arrow with link for an arrow between
two of them, Group, and the Wash a highlight fades in. Code is a group
with one mobject per line, so a pass can be shown doing what a pass does,
which is to touch one instruction and leave the rest alone.

Animations: fade_in, fade_out, move, highlight, pulse, draw.

Print a scene and you get the storyboard, which is the form a review reads.
Show it in a notebook and you get the picture. svg() writes a file and
frame(t) gives one still with nothing moving in it.

What this closes off, and why

  • CSS keyframes, no script. The output goes into saved notebooks, into
    Colab's output sandbox and into static HTML on the site, and script
    survives none of those reliably. It also means the picture animates when
    it is loaded as an ordinary <img>, which script would not.
  • The markup is the last frame. Elements are written out where they end
    up and the animation walks back to the beginning and forward again. A
    renderer that drops the stylesheet, a printed page, and anybody whose
    system asks for less motion all get the finished picture rather than an
    empty box. prefers-reduced-motion: reduce turns the animation off
    rather than being ignored.
  • Easing is sampled here, not handed to CSS. A keyframe timing function
    applies per stop, and one mobject's stops get interleaved with another's,
    which distorts the curve quietly.
  • Ninety seconds is the cap, the one in CONTRIBUTING.md. A scene over
    it raises rather than rendering.

Also in here

irx.ir grows pieces(), the tokeniser loop that irx.ir.highlight and
irx.graphs._tspans each had their own copy of. Three things render IR now
and they agree about what a keyword is.

docs/diagrams/pass-step.svg is the first scene, wired into build.py diagrams like the others, and byte stable across rebuilds because the one
generated id in it is a content hash. The IR in it is what opt -passes=dce -S printed, and the transcript is in the script that draws it.

Checks

  • toolkit: 244 tests, OK (35 new, none of which need a compiler)
  • repo: 98 tests, OK
  • ruff check ., build.py check, build.py diagrams twice with no diff,
    prosecheck, refcheck --ledger clean

Part of #10.

manim's vocabulary, none of manim. Mobjects, a scene, and `play` for one
beat of it, rendered as a single inline SVG with a stylesheet in it.
manim itself renders video, which wants cairo, ffmpeg and usually a
LaTeX install, and none of that fits in the first cell of a Colab
notebook or survives being saved into one.

The mobjects are Box, Code, Caption, Arrow, Group and the Wash a
highlight fades in. Code is a group with one mobject per line, so a pass
can be shown doing what a pass does, which is to touch one instruction
and leave the rest alone. The animations are fade_in, fade_out, move,
highlight, pulse and draw.

Three things this closes off deliberately:

CSS keyframes, no script. The output goes into a saved notebook, into
Colab's output sandbox and into static HTML, and script survives none of
those reliably. It also animates as an ordinary <img>.

The markup is the last frame. Elements are written out where they end
up and the animation walks back to the start, so a renderer with no
stylesheet, a printed page, and anybody who asked for less motion get
the finished picture rather than a blank one. prefers-reduced-motion is
honoured. `frame(t)` gives any other moment as a still.

Easing is sampled here rather than handed to CSS, because a keyframe
timing function applies per stop and the stops of one mobject end up
interleaved with another's.

Ninety seconds is the cap from CONTRIBUTING.md, and a scene over it
raises rather than rendering.

Also: irx.ir grows `pieces()`, which is the tokeniser loop that both
irx.ir.highlight and irx.graphs already had a copy of, and now the three
things that render IR agree about what a keyword is.

docs/diagrams/pass-step.svg is the first scene, and the IR in it is what
`opt -passes=dce -S` actually printed.
@tamnd
tamnd merged commit 88afd18 into main Sep 6, 2026
8 checks passed
@tamnd
tamnd deleted the irxmanim branch September 6, 2026 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant