KQ-1571 · GATE/RINGS

Gate Rings

A small gyroscope of nested polished rings round a glowing core, drawn in Canvas 2D with real 3D: each ring tumbles about its own axle and is cut with a single gap at the axle's end, so when the axles line up the gaps sit one behind another and the core's beam passes clean out through them, whatever the tilts. A drag tumbles the rings 1:1 and its release throws each its own share; they coast on friction and, as they slow, a field draws axles and tilts home so the light flickers through and steadies as each ring locks with a detent, while a click swings them flat into one concentric halo on the springs.snap constants in a cascade. The control is a switch: Enter swings the halo in and out, Space spins the rings, Escape brakes a spin.

KQ-1571 · GATE/RINGS

Basinworks Lightworks · gate 3

Drag to spin, click to align

Enter swings the rings flat into a halo or back; Space spins them and Escape brakes them. Drag to spin them by hand.

in line · beam through 5 rings

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/gate-rings

Props

ringCount
number
default 5
How many nested rings, 3 to 7.
finish
"brass" | "steel" | "copper" | "smoke"
default "brass"
The rings' metal, its hue taken from a token at a fixed lightness.
spin
number
default 0.6
How hard a flick or Space throws the rings and how long they coast, 0 to 1.
aligned / defaultAligned
boolean
default false
The rings swung flat into one halo, controlled or initial.
onAlignedChange
(aligned: boolean) => void
default —
Fires from the click, key or drag that swung the rings flat or out of it.
onBeamChange
(through: boolean, inLine: number) => void
default —
Fires when the beam starts or stops getting through, with how many gaps are in line.
beamAngle
number
default 0
The beam's direction from the core, degrees clockwise from the right.
gap
number
default 26
The cut in each ring, degrees, 10 to 60.
tilt
number
default 62
How far the rings stand tilted at rest, degrees, 0 to 80.
light
string
default "var(--warn)"
The core's light and the beam, any CSS colour; its hue is used at a fixed brightness.
thickness
number
default fitted
The rings' thickness, px.
paused
boolean
default false
Hold the rings where they are.
seed
number
default 1
Seeds the rest tilts and the way a throw shares out.
dpr
number
default 2
Cap on the canvas's device pixel ratio, at most 2.
sound
boolean
default false
A detent click as each ring's gap locks into line, after a visitor's action.
label
string
default "Gate rings"
The control's accessible name.
disabled
boolean
default false
No spinning or swinging.
className
string
default —
Sizes the piece; it fills its parent by default (h-full w-full).