KQ-1142 · LOOP/LIFT
Loop Lift
Draw a loop around part of a picture and the loop closes and smooths on one glide spring — the gap between the pen's end and its start grows shut while the wobble relaxes through a Fourier low-pass — then exactly that part lifts out: a copy of the picture clipped by the loop rises on the snap spring with a geometric glow, a shadow and a caption naming what it caught, while the rest dims. Escape, a tap or a new loop drops it back on glide. The things in the picture are a listbox: the arrow keys walk them, and Enter draws the loop around the chosen one with the same marker squeak, close and lift.
Draw a loop around part of the picture to lift it out. Arrow keys move between the things in it; Enter or Space lifts the chosen one, and Escape drops it.
4 items · circle one or press enter
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/loop-lift
Props
- children
- React.ReactNode
- default —
- The picture. It is drawn twice: once as itself, and once as the lifted copy, which is aria-hidden and inert.
- label
- string
- default —
- The accessible name of the list of things in the picture.
- regions
- { id: string; label: string; x: number; y: number; width: number; height: number }[]
- default —
- The things in the picture, as fractions (0 to 1) of its box: what a loop can catch, what the caption names and what the keyboard walks.
- value / defaultValue
- { points: [number, number][]; regions: string[]; area: number } | null
- default null
- The lifted selection: the closed, smoothed loop as fractions of the picture, the ids of the regions it encloses, and the enclosed share of the picture. null when nothing is lifted.
- onValueChange
- (value: LoopLiftValue | null) => void
- default —
- Fires from the loop, tap or key that changed the selection. Controlled, the piece lifts when the value comes back; a refused selection's outline fades.
- smoothing
- number
- default 0.5
- How much the loop relaxes when it closes, 0 to 1: the harmonics kept run from 14 (every wobble of the hand survives) down to 1 (an ellipse).
- lift
- number
- default 12
- How high the lifted piece rises, in px, 0 to 24: its offset, its scale and how far its shadow falls. 0 is a flat highlight.
- glow
- number
- default 0.6
- Strength and reach of the halo around the lifted piece, 0 to 1, drawn as layered strokes of the loop rather than a blur.
- dim
- number
- default 0.5
- How dark the rest of the picture goes while a piece is lifted, 0 to 0.8.
- sound
- boolean
- default false
- Play the marker's squeak (following the pen's speed), the tick as the loop closes, the lift's shimmer (higher for a smaller piece) and the drop. Nothing plays, and no audio context exists, unless this is on.
- disabled
- boolean
- default false
- Blocks drawing and takes the things in the picture out of the tab order.
- className
- string
- default —
- Merged onto the frame's classes.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | — | The picture. It is drawn twice: once as itself, and once as the lifted copy, which is aria-hidden and inert. |
| label | string | — | The accessible name of the list of things in the picture. |
| regions | { id: string; label: string; x: number; y: number; width: number; height: number }[] | — | The things in the picture, as fractions (0 to 1) of its box: what a loop can catch, what the caption names and what the keyboard walks. |
| value / defaultValue | { points: [number, number][]; regions: string[]; area: number } | null | null | The lifted selection: the closed, smoothed loop as fractions of the picture, the ids of the regions it encloses, and the enclosed share of the picture. null when nothing is lifted. |
| onValueChange | (value: LoopLiftValue | null) => void | — | Fires from the loop, tap or key that changed the selection. Controlled, the piece lifts when the value comes back; a refused selection's outline fades. |
| smoothing | number | 0.5 | How much the loop relaxes when it closes, 0 to 1: the harmonics kept run from 14 (every wobble of the hand survives) down to 1 (an ellipse). |
| lift | number | 12 | How high the lifted piece rises, in px, 0 to 24: its offset, its scale and how far its shadow falls. 0 is a flat highlight. |
| glow | number | 0.6 | Strength and reach of the halo around the lifted piece, 0 to 1, drawn as layered strokes of the loop rather than a blur. |
| dim | number | 0.5 | How dark the rest of the picture goes while a piece is lifted, 0 to 0.8. |
| sound | boolean | false | Play the marker's squeak (following the pen's speed), the tick as the loop closes, the lift's shimmer (higher for a smaller piece) and the drop. Nothing plays, and no audio context exists, unless this is on. |
| disabled | boolean | false | Blocks drawing and takes the things in the picture out of the tab order. |
| className | string | — | Merged onto the frame's classes. |