# Debris field

A population of hull fragments on straight trajectories from one rupture, each released at its own moment and turning at its own rate, drawn back to front so a near fragment occludes a far one.

> For the complete index, see [llms.txt](https://robocn.dev/llms.txt). A Markdown version of any page is available by appending `.md` to its URL or by sending an `Accept: text/markdown` header.

## Install

```bash
bunx --bun shadcn@latest add https://robocn.dev/r/debris-field.json
```

Registry item: `debris-field` · [`https://robocn.dev/r/debris-field.json`](https://robocn.dev/r/debris-field.json)

## Notes

- This is the only drawing in the set that has to decide what is in front of what. Everything else here is one object; this is a population with nothing holding it in any order, so the fragments are sorted by `camera.depth` and painted back to front — and the order changes when the camera moves rather than the artwork being redrawn per angle.
- Every fragment is a plate off the same tiling `battle-station` is built from, on the same solved trajectory. At `spread` 0 they reassemble into the body exactly, which is what makes the scatter readable as a scatter of something.
- The fragments keep turning after they have flown out, because nothing stopped them: the tumble runs off the clock rather than off the travel. That is the difference from the station's breakup, where a plate turns only while it is being thrown.
- Solved: the tiling, the fracture front and its release order, the straight-line travel, each fragment's own tumble frame, the illumination, the depth sort, the shock ring as a real circle in a stated plane, and the trails — which are straight because the solver makes them so.
- Illustrated: the fragment edge shading and the shock ring's expansion rate and fade. There is no mass, no energy, no gravity and no collision: fragments pass through each other's paths, and `spread` is a number you can scrub in both directions rather than a time after an event.

## Usage

```tsx
import { DebrisField } from "@/components/ui/debris-field"

<DebrisField behavior="drift" courses={6} perCourse={9} showTrails />
<DebrisField spread={0.7} interactive onSpreadChange={setSpread} />
```

## Props

| name | type | default | description |
| --- | --- | --- | --- |
| `view` | `"plan" | "front" | "profile" | "iso"` | `"front"` | Where the camera stands. One field, four projections: straight down, straight on, side elevation, or three-quarter from above. |
| `spread` | `number` | — | Controlled scatter, 0 still assembled to 1 fully apart. Supplying it stops the loop. |
| `behavior` | `"burst" | "drift" | "tumble" | "static"` | `"drift"` | Burst runs the scatter out and back; drift holds it and lets the tumble carry the drawing; tumble holds it further out. |
| `speed` | `number` | `0.1` | Cycles per second. |
| `animate` | `boolean` | `true` | Off parks the machine at phase and stops rendering. A reduced-motion preference does the same. |
| `paused` | `boolean` | `false` | Freeze where it stands. |
| `phase` | `number` | `0` | Seconds of offset, so a row of machines breaks step. |
| `interactive` | `boolean` | `false` | Drag across it to scrub the scatter; arrows 5 percent, shift 15, Home assembled and End apart. |
| `onSpreadChange` | `(spread: number) => void` | — | Fires on every drag and key press, in controlled mode too. |
| `courses` | `number` | `6` | Courses the body was plated in, clamped 2..14. With `perCourse` it sets the fragment count. |
| `perCourse` | `number` | `9` | Fragments round the equator of that body, clamped 2..20. |
| `reach` | `number` | `1.3` | How far a fragment travels at full spread, in radii. Clamped 0..12. |
| `rupture` | `number` | `18` | Degrees round the field the rupture sat at. |
| `showTrails` | `boolean` | `false` | Straight lines back to the piece of hull each fragment came off — the trajectories, drawn. |
| `showShock` | `boolean` | `true` | The expanding front. |
| `seed` | `number` | `5` | Any integer. The same seed is the same field, every render. |
| `sun` | `number` | `38` | Where the light is, in degrees round the field; 0 is behind the viewer. |
| `variant` | `"solid" | "outline" | "blueprint" | "wire"` | `"solid"` | How the machine is painted. Geometry never changes between variants. |
| `size` | `"xs" | "sm" | "md" | "lg" | "xl" | number` | `"md"` | Rendered width in pixels, or a step on the scale. |
| `signal` | `"idle" | "ready" | "warning"` | — | Status-lamp state using neutral, accent, or shell colour; each component documents its visual default in the demo. |
| `label` | `string` | — | Optional technical caption under the drawing. |
| `color` | `string` | `var(--robot-shell)` | Body panels — the colour the machine reads as. |
| `accent` | `string` | `var(--robot-accent)` | Status colour: tip light, live tool, readouts. |
| `metal` | `string` | `var(--robot-metal)` | Bare machined parts: collars, bolts, tool bodies. |
| `dark` | `string` | `var(--robot-dark)` | Cast joints, base, shadow side. |
| `palette` | `Partial<RobotPalette>` | — | Override any subset of roles at once, including glow and grid. |

## Source

- `src/components/ui/debris-field.tsx`
