This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a Motion Canvas animation project for a Polylog video on cryptography. Motion Canvas is a TypeScript framework for creating programmatic animations using generator functions and JSX-like syntax.
./setup.sh— First-time setup: clones the Polylog fork of Motion Canvas, builds it, installs deps, sets up pre-commit hooksnpm run start— Start dev preview server at http://localhost:9000/npm run build— Production build (tsc && vite build)
There are no tests. A pre-commit hook auto-formats staged src/ files with Prettier.
Entry point: src/project.ts registers scenes, imports global.css, and imports ./monkeypatch (which extends Motion Canvas Node with helper methods like worldToView/viewToWorld). Scenes are imported with the ?scene suffix (a Vite plugin convention). Scenes are toggled on/off by commenting lines in the scenes array.
Scenes (src/scenes/): Each scene exports a makeScene2D() generator function. Animations are sequenced by yielding timing expressions (waitFor, all, sequence, signal tweens). Example/demo scenes live in src/scenes/examples/. Note: modular-operations.tsx and modular-ops-alt.tsx co-exist — project.ts currently registers modular-ops-alt under the modularOperations import name.
Config (src/config.ts): Central character assignments — which ParticipantKind ('prover', 'verifier', 'postman') plays left/right/evil roles, their accent colors, and whether the postman flips. All scenes import from here instead of hardcoding roles.
Components (src/components/): Reusable scene-graph nodes used across scenes:
participant.tsx—Participantnode with expression-based face images (neutral, happy, evil, etc.) and fixed positions (PROVER_POSITION,VERIFIER_POSITION)padlock.tsx—Padlockcomponent with wrap/unwrap animationskey.tsx—Keycomponent with unlock-and-return animationsevil-postman.tsx—EvilPostmanwith cone-of-vision trackingmodular-clock.tsx—ModularClockfor modular arithmetic visualizationsShiki.ts— wraps Shiki as a Motion CanvasCodeHighlighterPoliticalParty.tsx,Three.ts— Specialized components
Utilities (src/utilities/): Shared animation helpers and styled components:
color.tsx—Solarizedcolor palette,FONT_FAMILYconstant,colorLerptext.tsx—PolyTxtcomponent (styledTxt),smartTextLerp(diff-based character interpolation)latex.tsx—PolyLatexcomponent withwrite()/unwrite()path-drawing animationsprotocol.tsx—ProtocolScaffold/ProtocolAnimation/ProtocolSpy— the core framework for two-party protocol scenes (participants, keys, padlocks, box sending, math animations). Most cryptography scenes build on this.lock.tsx—LockedBoxnode with 3D-rotation open/close and padlock slotsmoving.tsx— Offscreen movement helpers (move nodes in/out of frame)clock-gestures.tsx— Power gesture overlays for modular clock visualsgossip-intro.tsx— Scientist gossip intro animationvisuals.tsx— Shadow creationcreation.tsx— Generic appear/disappear/indicate helpers
Shaders (src/shaders/): GLSL fragment shaders (gradient.glsl, rotate3d.glsl) used for visual effects on nodes.
Assets (src/assets/images/): Character face images organized by participant (vv/, vr/, amit/) with expression variants, plus scientist portraits and cryptographer photos.
Audio (audio/): Raw .wav files at the repo root. Wired up in src/utilities/audio.tsx.
All sounds live in audio/ (e.g. audio/spin.wav, audio/padlock/on1.wav) and are exposed as named factories from src/utilities/audio.tsx. Each exported factory returns a fresh SoundBuilder; call .play() on it (eagerly, not via yield*) to fire it during a generator.
import { spinSound, padlockOnSound } from '../utilities/audio';
spinSound().play(); // fire-and-forget
yield* something(2); // sound plays during this animationAdding a new sound:
- Drop the
.wavintoaudio/(or a subfolder). - Add an export in src/utilities/audio.tsx using
makeSound - Import and call
fooSound().play()at the desired point in the generator.
- Resolution: 1920×1080 at 60fps
- Styling: Solarized color scheme (
Solarizedobject incolor.tsx), Computer Modern Serif font (FONT_FAMILY), 50px base font size. If CMU hasn't loaded in the preview, force an HMR update by touching a file. - Formatting: Prettier with 88-char line width, single quotes, trailing commas, sorted imports (via
@ianvs/prettier-plugin-sort-imports) - Motion Canvas fork: Uses
@polylog-cs/motion-canvas(cloned locally intomotion-canvas/), linked via npm workspaces
The examples/ directory contains ~30 TSX example files (plus GLSL shaders) organized in 3 sections, demonstrating Motion Canvas patterns from basics to advanced. When creating animations, consult examples/REFERENCE.md for a comprehensive code reference organized by concept (scene basics, animation flow, flexbox, signals, effects, camera, shaders, etc.). For full examples, read the individual .tsx files in examples/.