KQ-1520 · RATIO/LOOP
Ratio Loop
A translucent ribbon tracing a closed harmonic figure in 3D — a Lissajous knot at the ratio a:b with its depth at a + b — turning slowly on its upright axis, drawn as one triangle strip whose width follows perspective and a seamless twist, so light adds and burns brighter wherever the ribbon crosses itself. Changing the ratio reties it without ever breaking: every sample travels from where it is to the new figure on springs.glide, the change starting at one point and running both ways round the loop while it loosens and pulls in, and a drag orbits it 1:1 with a throw that coasts on before the tilt drifts home on the drift constants. The ratio chips are a radio group whose arrow keys, Home and End step through the presets while the indicator snaps between them.
Gaugeworks · resonance
f₁ : f₂
3:2 · tied
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/ratio-loop
Props
- ratio / defaultRatio
- string
- default "3:2"
- The frequency ratio the ribbon traces, "a:b": controlled, or where it starts when uncontrolled.
- onRatioChange
- (ratio: string) => void
- default —
- Fires from the chip or key that asked for a new ratio, with that ratio.
- ratios
- string[]
- default ["2:1", "3:2", "4:3", "5:3", "5:4"]
- The preset ratios the chips and keys step through.
- width
- number
- default 10
- The ribbon's width, px, 2 to 24.
- spin
- number
- default 3
- How fast the figure turns on its axis, turns a minute, 0 (still) to 12.
- twist
- number
- default 0.5
- How often the ribbon twists edge-on along its length, 0 (flat) to 1.
- tilt
- number
- default 18
- The tilt of the turning axis toward the eye, degrees, -60 to 60.
- momentum
- number
- default 0.6
- How long a thrown orbit coasts, 0 (it stops at once) to 1 (it glides on).
- glow
- number
- default 0.6
- How bright the ribbon burns, 0 to 1.
- colors
- [string, string]
- default ["var(--accent-bright)", "var(--signal)"]
- The ribbon's two colours, round the loop and back.
- showChips
- boolean
- default true
- Show the ratio chips under the figure; without them the figure itself takes the keys.
- label
- string
- default "Harmonic figure"
- The figure's accessible name.
- interactive
- boolean
- default true
- Dragging orbits the figure.
- paused
- boolean
- default false
- Hold the turning still; drags and ratio changes still work.
- dpr
- number
- default 2
- Cap on the canvas's device pixel ratio, at most 2.
- onOrbitChange
- (orbiting: boolean) => void
- default —
- Fires when a drag starts orbiting the figure (true) and when its throw has run out (false).
- disabled
- boolean
- default false
- The chips and the drag are ignored; the figure still turns.
- className
- string
- default "h-full w-full"
- Sizes the whole piece: the figure fills what the chips leave.
| Prop | Type | Default | Description |
|---|---|---|---|
| ratio / defaultRatio | string | "3:2" | The frequency ratio the ribbon traces, "a:b": controlled, or where it starts when uncontrolled. |
| onRatioChange | (ratio: string) => void | — | Fires from the chip or key that asked for a new ratio, with that ratio. |
| ratios | string[] | ["2:1", "3:2", "4:3", "5:3", "5:4"] | The preset ratios the chips and keys step through. |
| width | number | 10 | The ribbon's width, px, 2 to 24. |
| spin | number | 3 | How fast the figure turns on its axis, turns a minute, 0 (still) to 12. |
| twist | number | 0.5 | How often the ribbon twists edge-on along its length, 0 (flat) to 1. |
| tilt | number | 18 | The tilt of the turning axis toward the eye, degrees, -60 to 60. |
| momentum | number | 0.6 | How long a thrown orbit coasts, 0 (it stops at once) to 1 (it glides on). |
| glow | number | 0.6 | How bright the ribbon burns, 0 to 1. |
| colors | [string, string] | ["var(--accent-bright)", "var(--signal)"] | The ribbon's two colours, round the loop and back. |
| showChips | boolean | true | Show the ratio chips under the figure; without them the figure itself takes the keys. |
| label | string | "Harmonic figure" | The figure's accessible name. |
| interactive | boolean | true | Dragging orbits the figure. |
| paused | boolean | false | Hold the turning still; drags and ratio changes still work. |
| dpr | number | 2 | Cap on the canvas's device pixel ratio, at most 2. |
| onOrbitChange | (orbiting: boolean) => void | — | Fires when a drag starts orbiting the figure (true) and when its throw has run out (false). |
| disabled | boolean | false | The chips and the drag are ignored; the figure still turns. |
| className | string | "h-full w-full" | Sizes the whole piece: the figure fills what the chips leave. |