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