# Pantograph

A single-arm roof current collector. Height and reach are not independent — asking for height folds the knee in and walks the pan back over its own base — and the head stays level because a control rod says so, not because it was pinned there.

> 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/pantograph-collector.json
```

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

## Notes

- Solved: the arms, from `pantographPose()`. The head rides the workspace of a two-link chain, so height is bought with reach and the pan travels back over the base as it rises; past full extension the height clamps rather than producing a broken pose, and the docs' `reachable` flag says so.
- The head's attitude is a second closed loop: a control rod runs from the lower arm to a lever on the head, and the head's angle is whatever assembles that loop at this height. It comes out flat at the height the levelling was set for and tips away from it at the ends of the travel — which is what a working range is.
- Illustrated: the stagger pattern, and the wire itself, which is a straight run rather than a catenary. No uplift, no contact force, no sag and no arcing.

## Usage

```tsx
import { PantographCollector } from "@/components/ui/pantograph-collector"

<PantographCollector behavior="raise" />

// Front is where the stagger reads: the contact walks across the strip.
<PantographCollector view="front" height={1} along={35} />
<PantographCollector interactive onHeightChange={setHeight} />
```

## Props

| name | type | default | description |
| --- | --- | --- | --- |
| `view` | `"plan" | "front" | "profile" | "iso"` | `"profile"` | Where the camera stands. One collector, four projections: straight down, straight on, side elevation, or three-quarter from above. |
| `height` | `number` | — | Working height, 0 stowed to 1 at the wire. Supplying it stops the loop. |
| `onHeightChange` | `(height: number) => void` | — | The height being asked for, while a person is working it. |
| `behavior` | `"raise" | "run" | "stow" | "static"` | `"raise"` | Up, work under the wire, and down; up and holding; or down bar the one moment it is put up and brought straight back. |
| `along` | `number` | — | How far along the run it is, which is what walks the contact across the strip and slides the masts past. Omit it and the clock runs it. |
| `speed` | `number` | `0.25` | Raise 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` | Press and drag up and down to work it; arrows 5%, shift 15%, Home stows and End is at the wire. |
| `showWire` | `boolean` | `true` | The contact wire, its masts, and the stagger it is strung with. |
| `showRoof` | `boolean` | `true` | The roof and insulators it stands on. |
| `active` | `boolean` | — | Light the strip. Omit and it lights on contact. |
| `label` | `string` | — | Caption underneath the collector. |
| `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. |
| `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/pantograph-collector.tsx`
