KQ-1836 · FLIP/SEQUINS
Flip Sequins
A panel of glossy two-faced sequins in overlapping rows that you draw on by brushing: the sequins under the brush turn over in the direction of travel, each disc squashing along the stroke, changing face at 90° and opening out again on its own spring at the springs.snap constants (ζ 0.83, loosened toward a flutter by wobble), with a glint running along its axis while edge-on. Brushing with the fabric's nap turns them over and brushing back smooths them home, so pictures and words can be drawn and erased; a long still press sends a ring out from the finger that turns every flipped sequin home inside one 600 ms beat. Arrow keys brush, Shift lifts the brush, Enter or Space turns the sequins under it and Backspace smooths the panel.
Fernworks atelier · swatch 12
Reversible sequin
Brush right or down to turn sequins over, against it to smooth them home. Hold still to smooth the whole panel. Arrow keys brush, Shift with an arrow lifts the brush, Enter or Space turns the sequins under it, Backspace smooths the panel.
swatch 12 · brush right or down to draw
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/flip-sequins
Props
- sequin
- number
- default 18
- Sequin diameter, in px.
- flipColor
- "rose" | "gold" | "teal" | "ink" | string
- default "rose"
- The colour of the other face: a named pigment or any CSS colour.
- shine
- number
- default 0.6
- How glossy the faces are and how bright the glint is as one turns, 0 to 1.
- color
- string
- default a satin from --ink-2
- The home face's colour.
- fabric
- string
- default the page, deepened
- The fabric showing between the sequins.
- nap
- number
- default 45
- The fabric's nap in degrees: brushing along it turns sequins over, brushing against it smooths them home; strokes across it do nothing.
- brushOn
- "hover" | "press"
- default "hover"
- A mouse brushes on hover, or only while its button is down. Touch and pen always brush while pressed.
- radius
- number
- default 1.1
- The brush's reach, in sequins.
- wobble
- number
- default 0.25
- How loose each turn is, 0 (one crisp overshoot) to 1 (a fluttering settle).
- holdToSmooth
- number
- default 550
- How long a still press must be held to smooth the whole field, in ms.
- text
- string
- default ""
- A word turned over into the field when it is laid out, fitted to its width, so the first frame says something.
- onFlipChange
- (flipped: number, total: number) => void
- default —
- Fires from the stroke, press or key that changed the field (and once when it is laid out), with how many sequins show their other face.
- onSmooth
- () => void
- default —
- Fires when a long press or Backspace smooths the field.
- sound
- boolean
- default false
- A shimmer as sequins turn, pitched up for over and down for home, after a visitor's stroke or key.
- label
- string
- default "Sequin panel"
- The field's accessible name.
- dpr
- number
- default 2
- Cap on the canvas's device pixel ratio, at most 2.
- disabled
- boolean
- default false
- Shows the field but takes no input.
- className
- string
- default "h-full w-full"
- Sizes the panel; it fills its parent by default.
| Prop | Type | Default | Description |
|---|---|---|---|
| sequin | number | 18 | Sequin diameter, in px. |
| flipColor | "rose" | "gold" | "teal" | "ink" | string | "rose" | The colour of the other face: a named pigment or any CSS colour. |
| shine | number | 0.6 | How glossy the faces are and how bright the glint is as one turns, 0 to 1. |
| color | string | a satin from --ink-2 | The home face's colour. |
| fabric | string | the page, deepened | The fabric showing between the sequins. |
| nap | number | 45 | The fabric's nap in degrees: brushing along it turns sequins over, brushing against it smooths them home; strokes across it do nothing. |
| brushOn | "hover" | "press" | "hover" | A mouse brushes on hover, or only while its button is down. Touch and pen always brush while pressed. |
| radius | number | 1.1 | The brush's reach, in sequins. |
| wobble | number | 0.25 | How loose each turn is, 0 (one crisp overshoot) to 1 (a fluttering settle). |
| holdToSmooth | number | 550 | How long a still press must be held to smooth the whole field, in ms. |
| text | string | "" | A word turned over into the field when it is laid out, fitted to its width, so the first frame says something. |
| onFlipChange | (flipped: number, total: number) => void | — | Fires from the stroke, press or key that changed the field (and once when it is laid out), with how many sequins show their other face. |
| onSmooth | () => void | — | Fires when a long press or Backspace smooths the field. |
| sound | boolean | false | A shimmer as sequins turn, pitched up for over and down for home, after a visitor's stroke or key. |
| label | string | "Sequin panel" | The field's accessible name. |
| dpr | number | 2 | Cap on the canvas's device pixel ratio, at most 2. |
| disabled | boolean | false | Shows the field but takes no input. |
| className | string | "h-full w-full" | Sizes the panel; it fills its parent by default. |