KQ-1882 · SECOND/CONTACT

Second Contact

A solar eclipse you drive: drag the dark moon (anywhere on the sky moves it 1:1; a tap glides it there on springs.glide) and as it covers more of the sun the sky deepens through twilight to night, a ring of sunset lights the horizon and stars come out. The moon's limb is a seeded profile of mountains and valleys, so near totality the last crescent breaks into Baily's beads of light through the valleys, then one diamond ring with the inner corona already showing, then totality: a pearly corona with long helmet streamers and fine striations drifting in colour around the hue, and pink prominences on the limb. One WebGL2 pass draws the scene while the light is measured on the CPU (the visible share of the disc, and the gaps at 720 angles round the limb gathered into beads); the moon is a slider of how much of the sun is covered, so arrow keys move it in fine steps near the sun, Home sets it at totality and End back where it began, and releasing leaves it where it is.

KQ-1882 · SECOND/CONTACT

Drag the sky to move the moon, or tap where it should go. Arrow keys move it, in fine steps near the sun and big steps with Shift; Home sets it over the sun, End back where it began.

The diamond ring.

diamond ring · the inner corona is showing

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/second-contact

Props

value / defaultValue
{ x: number; y: number }
default — / { x: -0.95, y: 0.28 }
Where the moon's centre is, in sun radii from the sun's centre, y down; controlled or initial.
onValueChange
(point: { x: number; y: number }) => void
default —
Fires from the drag, tap or key that moved the moon.
onPhaseChange
(phase: "clear" | "partial" | "beads" | "diamond" | "totality") => void
default —
Fires when the eclipse moves between clear, partial, beads, the diamond ring and totality.
corona
number
default 0.6
How far the corona reaches, 0 to 1: a tight bright collar to streamers past three radii.
beads
number
default 0.7
How bright the last light is, 0 to 1: faint pinpricks to blazing beads and a big diamond.
hue
number
default 200
The corona's tint, a hue in degrees.
sunSize
number
default 0.21
The sun's radius as a share of the shorter side, 0.12 to 0.32.
prominences
number
default 0.5
How many pink prominences stand on the limb at totality, 0 to 1.
stars
boolean
default true
Stars come out as the sky darkens.
sky
string
default a pigment from the accent token
The daytime sky, any CSS colour.
night
string
default a deep blue pigment
The sky at totality, any CSS colour.
shimmer
number
default 0.4
How much the beads and the corona shimmer, 0 to 1.
seed
number
default 7
Seeds the moon's mountains and valleys and the corona's streamers.
dpr
number
default 2
Cap on the canvas's device pixel ratio, at most 2.
label
string
default "Eclipse"
The scene's accessible name.
disabled
boolean
default false
No dragging or keys.
className
string
default —
Sizes the scene; it fills its parent by default.