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.

KQ-1520 · RATIO/LOOP

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.