# Domino Chain (Real Physics) — `domino-chain@1.1.0`

A long line of dominoes topples one after another, simulated with real forces — then the camera pulls back.

Push the first domino and watch the wave run down the line. Each domino is simulated with gravity and contact forces, so the speed of the wave, the way pieces lean on each other and the final resting angles come from the physics rather than a keyframed animation. Change how many dominoes there are, how far apart they stand, how hard the first one is pushed and the colour gradient along the line.

- Kind: physics; status: published; digest sha256:67bd6f2636033cde0db0105e82789a0a9b32c505b0c0d6623b44e090adeddc19
- Role: Motion source: per-frame tilt angles for a row of toppling dominoes.
- Implementation: js; entry `src/domino-chain.js`
- Files: https://aipixelwizard.com/registry/domino-chain/1.1.0/<path> (`LICENSE`, `asset.json`, `demo.js`, `index.html`, `src/domino-chain.js`)
- Manifest JSON: https://aipixelwizard.com/api/v1/visuals/domino-chain/versions/1.1.0
- Runnable demo: https://aipixelwizard.com/registry/domino-chain/1.1.0/index.html (open over http; it imports sibling packages by relative path)
- Dependencies (exact): `apw-runtime@1.0.0` (demo) — Demo harness and colour helpers. src/domino-chain.js has no dependencies.

## Exports
- `simulateDominoChain({ count?, spacing?, thickness?, gravity?, push?, fps?, durationSeconds?, stepHz? }) => { angleAt(frame, i), pivotX(i), frontAt(frame), count, spacing, thickness, height, frameCount, stats }` — Fixed-step simulation baked to per-frame angles.
- `drawDomino(ctx, sim, frame, i, view, fill?, pip?) => void` — Canvas 2D helper to draw one domino at its simulated angle.

## Parameters
- `count` (integer 6–60, default 36) — Dominoes
- `spacing` (number 0.3–0.85, default 0.55) — Spacing: Distance between dominoes as a fraction of their height. Closer falls faster.
- `push` (number 1–3, default 1.4) — First push: How hard the first domino is flicked. Too soft and it will not tip — that is physics.
- `gravity` (number 3–40, default 14) — Gravity: 9.81 behaves like metre-tall dominoes. Raise it for a quicker, smaller-looking chain.
- `pullBack` (boolean, default true) — Pull back at the end
- `colorA` (color, default "#ffd166") — First colour
- `colorB` (color, default "#ff4d8d") — Last colour
- `background` (color, default "#101018") — Background

## Composition
- Inputs: Options plus the clip's fps and duration.
- Outputs: angleAt(frame, i) in radians (0 upright, π/2 flat) and pivotX(i); frontAt(frame) for a following camera.
- Coordinates: Side view. Domino height = 1 unit, floor at y = 0, domino i pivots on its front-bottom edge at x = i × spacing.
- Lighting: None (motion only).
- Timing: Bake once; frames are random-access lookups.
- Works with: kinetic-title, gradient-background, orbit-camera
- For 3D, rotate box meshes about their front-bottom edge by angleAt(frame, i) around the axis perpendicular to the line.

## Output and loop
- 1080×1080, 30 fps, 8 s, simulation
- Seamless loop: no — The chain falls once and stays down.
- Verified 2026-10-03 in Chrome 154.0.8037.97 headless on Linux 7.0.0-38-generic (x64), Node 22.14.0 (Canvas 2D); deterministic: yes

## Use it
New project: Call simulateDominoChain({ fps, durationSeconds }) once, then each frame draw domino i rotated by angleAt(frame, i) around its pivot at pivotX(i).

Existing project: Copy src/domino-chain.js. Bake once at scene creation; in your frame loop set each existing domino object's rotation from angleAt. Keep your renderer and art.

Reuse ideas:
- Build 3D dominoes in Three.js and rotate each about its front-bottom edge by angleAt (works with Orbit Camera).
- Let the last domino trigger a Kinetic Title reveal by starting the title at the frame where the last angle exceeds 0.05.
- Use frontAt(frame) to drive a progress indicator or camera in any scene.

## Limitations
- One degree of freedom per domino: no sliding, bouncing or tumbling, so impossible-looking setups (very wide spacing) simply stop.
- Straight line on a flat floor; no curves, branches or other objects.
- Contact is a stiff spring (penalty) model; pieces can overlap by up to about 0.04 units (4% of height) while pressing.

## License
MIT. Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.

Provenance: Original code written for AI Pixel Wizard in October 2026. Demo scene rebuilt in October 2026 to the catalog quality bar (docs/QUALITY.md); the reusable source is unchanged.

