KQ-1453 · SWEEP/SCOPE

Sweep Scope

A background that is a radar scope: range rings with their numbers, faint spokes and ticks, and a beam that nods across the upper half from a centre on the bottom edge (or turns full circle from the middle), its afterglow exact — every half-degree of bearing remembers when the beam last crossed it — lighting ground clutter as it rakes it, while vessels drifting across show only where the beam last painted them, each paint fading into a dotted track. A press places a contact whose corner brackets close in on springs.snap; nothing shows there until the sweep finds it, when the blip lands on springs.recoil and a ping ring opens, and keyboard focus on a control inside places a contact at that control.

KQ-1453 · SWEEP/SCOPE

Basinworks Harbour

Every vessel on one screen

Live traffic for small ports

sweeping · 4 rings · signal

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/sweep-scope

Props

children
React.ReactNode
default —
The content on top of the scope: a hero line, a heading, a call to action.
speed
number
default 1
How fast the sweep turns, 0.25 to 3 (1 is a full turn every 4.5 s).
rings
number
default 4
How many range rings the scope draws, 1 to 8.
color
"signal" | "cobalt" | "amber" | "ice" | string
default "signal"
The phosphor: a named token or any CSS colour.
origin
"bottom" | "center"
default "bottom"
Where the scope's centre sits: on the bottom edge (the sweep nods across the upper half) or in the middle (it turns full circle).
trail
number
default 110
How far behind the beam its afterglow reaches, degrees, 20 to 300.
persistence
number
default 2600
How long a contact glows after the beam paints it, ms.
contacts
number
default 6
How many vessels drift across the scope by themselves, 0 to 16.
clutter
number
default 0.35
Ground returns near the centre that the beam lights as it rakes them, 0 to 1.
grid
number
default 0.6
How strongly the rings, spokes and ticks are drawn, 0 to 1.
labels
boolean
default true
Range numbers on the rings and bearings where the spokes leave the frame.
cursor
boolean
default true
A faint range ring and crosshair follow the pointer.
interactive
boolean
default true
A press, and keyboard focus inside, places a contact for the sweep to find.
paused
boolean
default false
Stop the sweep: the scope holds its picture; placed contacts still mark.
seed
number
default 1
Seeds the vessels, their courses and the clutter.
dpr
number
default 2
Cap on the canvas's device pixel ratio, at most 2.
onPlace
(contact: { id: number; bearing: number; range: number }) => void
default —
Fires when a contact is placed, with where it is.
onFind
(contact: { id: number; bearing: number; range: number }) => void
default —
Fires when the sweep first paints a placed contact.
className
string
default "h-full w-full"
Sizes and shapes the box.