KQ-1820 · SPIRAL/ENGRAVING
Spiral Engraving
A round plate engraved with one continuous spiral line whose width swells where the picture is dark and thins to an unbroken hairline where it is light, drawn per pixel in one WebGL2 pass that samples the picture at each pixel's own position. As the plate turns the line flows inward like a vortex while the picture holds still within it; a drag round the plate turns it 1:1 and a release keeps the throw's spin, easing back to the resting turn over a time set by friction. The first time it is seen the line swells from a hairline into the picture as a front runs out from the spindle. Arrow keys flick it either way, Enter flings it and Home brakes it.
Basinworks Observatory · plate IV
The quiet moon, cut in one line
still · drag round the plate to spin it
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/spiral-engraving
Props
- pitch
- number
- default 4
- Distance between neighbouring turns of the line, CSS px, 3 to 10.
- contrast
- number
- default 1.2
- How hard the picture's tones are pushed apart, 0.5 to 2.
- spin
- number
- default 20
- The resting spin in turns per minute, 0 to 60; the line flows by one pitch per turn.
- subject
- "moon" | "peak" | "bloom"
- default "moon"
- The picture drawn in code when there is no src.
- src
- string
- default —
- An image URL to engrave (CORS-enabled); the subject stands in while it loads or if it cannot be read.
- alt
- string
- default by subject
- What the picture shows, for assistive technology.
- ink
- string
- default "var(--foreground)"
- The line's colour. A light ink on dark paper prints a white-line engraving (the line swells in light tones).
- paper
- string
- default "var(--card)"
- The plate's colour.
- thin
- number
- default 0.08
- The line's width in the lightest tones as a share of the pitch, 0 to 0.4; it never breaks.
- bold
- number
- default 0.9
- The line's width in the darkest tones as a share of the pitch, 0.5 to 1.
- friction
- number
- default 0.5
- How quickly a fling slows back to the resting spin: 0 coasts long, 1 stops short.
- direction
- "inward" | "outward"
- default "inward"
- Which way the line flows as the plate turns.
- reveal
- "inView" | "mount" | "none"
- default "inView"
- When the line swells from a hairline into the picture.
- onSpinChange
- (state: "still" | "turning" | "flung") => void
- default —
- Fires when the plate comes to rest, settles into its resting spin, or is flung faster.
- label
- string
- default "Spin the plate"
- The plate's accessible name.
- paused
- boolean
- default false
- Hold the plate still; a drag still turns it.
- disabled
- boolean
- default false
- No dragging or keys.
- dpr
- number
- default 2
- Cap on the canvas's pixel ratio, at most 2.
- className
- string
- default —
- Classes for the root; it is square, so give it a width.
| Prop | Type | Default | Description |
|---|---|---|---|
| pitch | number | 4 | Distance between neighbouring turns of the line, CSS px, 3 to 10. |
| contrast | number | 1.2 | How hard the picture's tones are pushed apart, 0.5 to 2. |
| spin | number | 20 | The resting spin in turns per minute, 0 to 60; the line flows by one pitch per turn. |
| subject | "moon" | "peak" | "bloom" | "moon" | The picture drawn in code when there is no src. |
| src | string | — | An image URL to engrave (CORS-enabled); the subject stands in while it loads or if it cannot be read. |
| alt | string | by subject | What the picture shows, for assistive technology. |
| ink | string | "var(--foreground)" | The line's colour. A light ink on dark paper prints a white-line engraving (the line swells in light tones). |
| paper | string | "var(--card)" | The plate's colour. |
| thin | number | 0.08 | The line's width in the lightest tones as a share of the pitch, 0 to 0.4; it never breaks. |
| bold | number | 0.9 | The line's width in the darkest tones as a share of the pitch, 0.5 to 1. |
| friction | number | 0.5 | How quickly a fling slows back to the resting spin: 0 coasts long, 1 stops short. |
| direction | "inward" | "outward" | "inward" | Which way the line flows as the plate turns. |
| reveal | "inView" | "mount" | "none" | "inView" | When the line swells from a hairline into the picture. |
| onSpinChange | (state: "still" | "turning" | "flung") => void | — | Fires when the plate comes to rest, settles into its resting spin, or is flung faster. |
| label | string | "Spin the plate" | The plate's accessible name. |
| paused | boolean | false | Hold the plate still; a drag still turns it. |
| disabled | boolean | false | No dragging or keys. |
| dpr | number | 2 | Cap on the canvas's pixel ratio, at most 2. |
| className | string | — | Classes for the root; it is square, so give it a width. |