KQ-1891 · DRYING/LINE
Drying Line
Darkroom prints pegged to a sagging cord under a red safelight, on a pulley loop you pull past: a drag follows 1:1 and commits by projection to the nearest print on the glide spring with the release velocity, and the page's scroll pulls it too. Every print is a real pendulum and a torsion pendulum, swung about its peg by the line's acceleration and twisted by the air each its own way, damped by `sway`, so the glossy faces turn and a band of red light slides across them before they hang still and the loop stops. Clicking a print unclips it: the jaw opens on the flick spring and the print glides to the front with its darkroom note, and Back on the line or Escape carries it back as the jaw snaps shut on snap; Left and Right pull the line a print, Home and End go to the ends.
Coldbrook Darkroom
Tuesday · fibre prints, drying
print 1 of 8 · pier at low tide · on the line
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/drying-line
Props
- items
- { src?: string; alt: string; caption?: string; note?: string; aspect?: number }[]
- default defaultDryingPrints
- The prints along the line; the default is eight black-and-white photographs drawn in code.
- sway
- number
- default 0.5
- How freely the prints swing and twist, 0 (stiff, quickly still) to 1 (loose, long and wide).
- sag
- number
- default 0.45
- How deep the cord sags between its hooks, 0 (taut) to 1 (a deep curve).
- pegs
- "wood" | "binder" | "film"
- default "wood"
- What holds each print: a wooden spring peg, a steel binder clip or a film clip.
- value / defaultValue
- number
- default 0
- The print at the middle of the room; a new controlled value pulls the line there.
- onValueChange
- (index: number) => void
- default —
- Fires from the drag, scroll or key that brought a new print to the middle.
- onUnclip
- (index: number | null) => void
- default —
- Fires when a print is unclipped to the front (its index) and when it goes back (null).
- spacing
- number
- default 112
- Distance between prints on the line, px; the loop is always wider than the room.
- scroll
- boolean
- default true
- The page's scroll (or the nearest scroll container's) pulls the line too.
- light
- string
- default "oklch(0.66 0.19 32)"
- The safelight's colour, any CSS colour.
- label
- string
- default "Drying line"
- Names the line for assistive technology.
- disabled
- boolean
- default false
- Shows the line but takes no pulls, clicks or keys.
- className
- string
- default —
- Sizes the room (default h-56 w-full).
| Prop | Type | Default | Description |
|---|---|---|---|
| items | { src?: string; alt: string; caption?: string; note?: string; aspect?: number }[] | defaultDryingPrints | The prints along the line; the default is eight black-and-white photographs drawn in code. |
| sway | number | 0.5 | How freely the prints swing and twist, 0 (stiff, quickly still) to 1 (loose, long and wide). |
| sag | number | 0.45 | How deep the cord sags between its hooks, 0 (taut) to 1 (a deep curve). |
| pegs | "wood" | "binder" | "film" | "wood" | What holds each print: a wooden spring peg, a steel binder clip or a film clip. |
| value / defaultValue | number | 0 | The print at the middle of the room; a new controlled value pulls the line there. |
| onValueChange | (index: number) => void | — | Fires from the drag, scroll or key that brought a new print to the middle. |
| onUnclip | (index: number | null) => void | — | Fires when a print is unclipped to the front (its index) and when it goes back (null). |
| spacing | number | 112 | Distance between prints on the line, px; the loop is always wider than the room. |
| scroll | boolean | true | The page's scroll (or the nearest scroll container's) pulls the line too. |
| light | string | "oklch(0.66 0.19 32)" | The safelight's colour, any CSS colour. |
| label | string | "Drying line" | Names the line for assistive technology. |
| disabled | boolean | false | Shows the line but takes no pulls, clicks or keys. |
| className | string | — | Sizes the room (default h-56 w-full). |