# Airliner

A four-engine double-deck widebody you can walk all the way round and take completely to bits. The camera goes to any angle at all, the skin opens on the reader's side wherever they are standing, and the teardown is the build order run backwards.

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

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

## Notes

- Solved: the undercarriage. Each of the five legs swings about a fixed trunnion with a two-part side stay that folds as it goes, and the stay's knee is an elbow solve — `gearRetraction` in `airframe`. The teardown is `explodeAssembly` from `assembly-geometry`: twelve stages, not parts, so a handed pair leaves together and nothing moves before what was fitted after it is clear. The surfaces come from `controlMix`, which holds the rules a big aeroplane really flies by — the slats lead the flaps, the outboard ailerons lock out with the flaps up, the roll spoilers rise on the down-going wing only.
- Illustrated: everything else. The loft is a loft, the aerofoil is a thickness distribution and not a section anyone would fly, and the engines are drawn rather than modelled. Nothing computes lift, drag, load factor or a stall, and the aircraft does not travel — it turns on a stand and comes apart on a bench.
- Because the camera goes to any angle, the drawing is depth-sorted: every part is emitted with the depth of its own centroid and the whole set is ordered once a frame. The skin is longitudinal panels rather than one silhouette, because a fuselage with an upper deck is not a convex body — and that is also what makes the cutaway a camera-relative cull rather than a fixed hole.
- Exploding parks the aeroplane: the surfaces go neutral and the gear goes down over the first sixth of the teardown, because an offset from a seat that is itself moving means nothing. The frame is fitted to an envelope grown by `explode` alone, so it zooms out when the machine comes apart and never breathes with a surface or a leg.
- An original archetype named for its job — a generic four-engine double-deck widebody. No manufacturer's name, no livery, no registration, and the default palette is the theme's.

## Usage

```tsx
import { Airliner } from "@/components/ui/airliner"

// On a bench: turning slowly, coming apart and going back together.
<Airliner behavior="service" />

// Any angle at all, on top of the four the set names.
<Airliner view="profile" azimuth={38} elevation={-14} />

// The near side of the skin opens wherever the reader is standing.
<Airliner cutaway={0.8} />

// Drag turns it; shift-drag takes it apart. Arrow keys do the same.
<Airliner interactive control="orbit" onOrbitChange={setOrbit} />

// Or drive it, which stops the loop.
<Airliner explode={0.45} configuration={1} />
```

## Props

| name | type | default | description |
| --- | --- | --- | --- |
| `view` | `"plan" | "front" | "profile" | "iso"` | `"iso"` | Where the camera stands. One aeroplane, four projections: straight down, straight on, side elevation, or three-quarter from above. |
| `azimuth` | `number` | — | Degrees the camera swings round the machine, on top of `view`. Any angle at all, and it wraps: the far side is 180 either way. |
| `elevation` | `number` | — | Degrees the camera rises above the view's own elevation, clamped to ±88 — past the pole it is under the floor. |
| `onOrbitChange` | `(orbit: { azimuth, elevation }) => void` | — | Where the camera stands, while a person is turning it. |
| `explode` | `number` | — | The teardown, 0 seated to 1 every part its own clearance away. Supplying it stops the loop. |
| `onExplodeChange` | `(explode: number) => void` | — | Fires while it is dragged or keyed, so interaction works in controlled mode too. |
| `explodeOverlap` | `number` | `0.45` | How much the stages overlap: 0 is strictly one stage at a time, 1 is every part moving together. |
| `showLeaders` | `boolean` | `true` | Dashed leaders from each part back to its seat. Nothing is drawn at rest. |
| `configuration` | `number` | — | The flap lever, 0 clean to 1 dirty. It runs the slats, the three flap settings and the gear, in the order they come out. |
| `onConfigurationChange` | `(configuration: number) => void` | — | The lever, while a person is working it. |
| `gear` | `number` | — | The five legs on their own, 0 up to 1 down, when they should not follow the lever. |
| `pitch` | `number` | — | Nose-up degrees commanded. It goes through the mixer, never straight onto a surface. |
| `roll` | `number` | — | Starboard-wing-down degrees commanded. Ailerons and the roll spoilers on the down-going wing. |
| `yaw` | `number` | — | Nose-right degrees commanded, onto the rudder. |
| `speedbrake` | `number` | — | The speedbrake lever, 0 to 1. This is the one that puts both sides of spoilers up together. |
| `cutaway` | `number` | `0` | Open the reader's side of the skin, 0 closed to 1 the whole near hemisphere. A cut panel keeps its outline, so the silhouette survives. |
| `showCabin` | `boolean` | `true` | Decks, seats, the flight deck and the freight. Only drawn once the skin is open or the machine is apart. |
| `showStructure` | `boolean` | `true` | Frames inside the shell, likewise. |
| `behavior` | `"cruise" | "approach" | "departure" | "turntable" | "service" | "static"` | `"cruise"` | Hold a lazy wing-over, come down dirty, clean up after a departure, turn on a table, or come apart and go back together. |
| `control` | `"orbit" | "explode" | "configuration"` | `"orbit"` | What a drag does. Shift swaps the turntable for the other tool and back, so one pointer reaches both. |
| `interactive` | `boolean` | `false` | Hand it to a person: drag to turn it, shift-drag to take it apart, or focus it and use the arrow keys. |
| `active` | `boolean` | `true` | Light the navigation lamps and the beacons. |
| `showGround` | `boolean` | `true` | The contact shadow, drawn as the machine's own footprint and foreshortened by the camera. |
| `label` | `string` | — | Optional technical caption under the drawing. |
| `speed` | `number` | `0.24` | Cycles per second: one teardown, one turn of the table, one circuit. |
| `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. |
| `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/airliner.tsx`
