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