Media & effects
Shooting Stars
Deep space canvas cosmos with glowing shooting stars, radiant twinkling starfield, and interactive stardust
detent-shooting-stars
Port status
- Catalog status
- implemented
- Origin
- upstream
- Phase
- 4
- Wave
- phase-4-canvas
- Group
- Media & effects
Fixed demo copy
A calm sky above your content
Move the pointer across the sky for multi-plane parallax, or click to summon a meteor through the pointer. The canvas is decorative: everything you can read here is real light DOM.
8.3 KB gzip for the class module
Variants
The sky follows the colour scheme: without an explicit background or starColors it paints
from --detent-shooting-stars-bg and the star, head and trail variables. The slotted copy inherits
--detent-shooting-stars-text, which defaults to the page text token. The component emits no events.
Recorded states
reduced motionrecorded state; no setter
Usage
Import
import '/components/shooting-stars/define.js';
// or register it yourself
import { DetentShootingStars } from '/components/shooting-stars/shooting-stars.js';
Attributes
anglebackgroundclick-to-spawnhead-colorintervalmax-active-shooting-starsmax-star-sizemin-star-sizenebulaparallaxpausedshow-embersstar-counttrail-colortwinkle-speed
Properties
speedstarColorstrailLength
Slots
default
Events
No events are recorded for this component.
Example
Runnable example: site/examples/shooting-stars.ts. The snippet below is generated from the catalogued attributes.
<detent-shooting-stars
angle="42"
background="#020617"
click-to-spawn
head-color="#FFFFFF"
interval="2200"
max-active-shooting-stars="2"
max-star-size="2.2"
min-star-size="0.6"
nebula
parallax
paused
show-embers
star-count="120"
trail-color="#38BDF8"
twinkle-speed="1"
></detent-shooting-stars>
Property-only values
const element = document.querySelector('detent-shooting-stars');
if (element !== null) {
// starColors: string[]
element.starColors = [];
// speed: [number, number] | number
element.speed = undefined;
// trailLength: [number, number] | number
element.trailLength = undefined;
}
Source
The pinned upstream source for this row:
src/components/ui/ShootingStars.tsxsha256 ec36fd45db4d…
Native files
The native module and its artifacts:
src/components/shooting-stars/shooting-stars.tssrc/components/shooting-stars/styles.csssrc/components/shooting-stars/define.tsdocs/components/shooting-stars.mdsite/examples/shooting-stars.tstests/browser/shooting-stars.spec.tsevidence/components/shooting-stars.md
API
Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.
Attributes
| Attribute | Property | Type | Default | Notes |
|---|---|---|---|---|
angle | angle | number | 42 | Kebab-case attribute; camelCase property. |
background | background | string | '#020617' | Kebab-case attribute; camelCase property. |
click-to-spawn | clickToSpawn | boolean | true | Presence semantics: present means true, absent means false. |
head-color | headColor | string | '#FFFFFF' | Kebab-case attribute; camelCase property. |
interval | interval | number | 2200 | Kebab-case attribute; camelCase property. |
max-active-shooting-stars | maxActiveShootingStars | number | 2 | Kebab-case attribute; camelCase property. |
max-star-size | maxStarSize | number | 2.2 | Kebab-case attribute; camelCase property. |
min-star-size | minStarSize | number | 0.6 | Kebab-case attribute; camelCase property. |
nebula | nebula | boolean | true | Presence semantics: present means true, absent means false. |
parallax | parallax | boolean | true | Presence semantics: present means true, absent means false. |
paused | — | — | — | Recorded in the catalog as an attribute. |
show-embers | showEmbers | boolean | true | Presence semantics: present means true, absent means false. |
star-count | starCount | number | 120 | Kebab-case attribute; camelCase property. |
trail-color | trailColor | string | '#38BDF8' | Kebab-case attribute; camelCase property. |
twinkle-speed | twinkleSpeed | number | 1 | Kebab-case attribute; camelCase property. |
Properties
| Property | Type | Default | Notes |
|---|---|---|---|
speed | [number, number] | number | [12, 22] | Property-only: assign from script; not accepted as an attribute. |
starColors | string[] | ['#FFFFFF', '#E0F2FE', '#C7D2FE', '#FEF08A'] | Property-only: assign from script; not accepted as an attribute. |
trailLength | [number, number] | number | [90, 180] | Property-only: assign from script; not accepted as an attribute. |
Events
No custom events are recorded for this component.
Slots
| Slot | Notes |
|---|---|
default | Consumer content; rendered through a slot, never re-created. |
CSS customisation
- React `children`/`ReactNode` props become DOM slots; caller content stays light DOM.
- `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- Each frame advances one bounded step with a re-baselined spawn clock, so a pause never produces a burst.
- A hidden document pauses the loop (PC-10.6 addition; the source had no visibilitychange).
- Work is bounded: 2000 stars, 24 meteors and 400 embers.
- The background value refuses url( so it can never fetch a network resource.
- The fixed dark surface publishes --detent-shooting-stars-text (#f8fafc) for legible slotted content (19.28:1).
- paused is exposed as attribute and property with the pinned source default false.
- The reduced-motion state is published as space[data-motion].
- The canvas needs no id, so two instances cannot collide.
What it does
A deep-space canvas sky: stratified twinkling stars, three nebula hazes, meteors with tapered gradient trails, head flares and stardust embers, pointer parallax and click-to-spawn, with the caller's content above the sky.
Upstream behaviour
- Zero external runtime dependencies: 100% native HTML5 Canvas 2D with sub-pixel DPR scaling
- Multi-depth twinkling starfield with radiant 4-point celestial cross-sparkles and soft halo blooms
- Cinematic meteors with radiant head bursts, tapered linear-gradient fading trails, and custom trajectory angles
- Stardust ember particles dynamically shed from traveling meteor tails for realistic atmospheric burns
- Subtle ambient cosmic nebula haze clouds rendering layered indigo, violet, and cyan deep-space depth
- Interactive mouse parallax tilt creating multi-plane 3D astronomical perspective
- Interactive click & tap summons custom meteors sweeping directly across the interaction point
- Full prefers-reduced-motion compliance freezing meteors and twinkle to a serene static night sky
- Stratified children wrapper supporting titles, hero copy, and buttons with intact pointer events
Differences from upstream
- React `children`/`ReactNode` props become DOM slots; caller content stays light DOM.
- `className` prop is replaced by documented CSS parts/custom properties; no Tailwind in consumers.
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- Each frame advances one bounded step with a re-baselined spawn clock, so a pause never produces a burst.
- A hidden document pauses the loop (PC-10.6 addition; the source had no visibilitychange).
- Work is bounded: 2000 stars, 24 meteors and 400 embers.
- The background value refuses url( so it can never fetch a network resource.
- The fixed dark surface publishes --detent-shooting-stars-text (#f8fafc) for legible slotted content (19.28:1).
- paused is exposed as attribute and property with the pinned source default false.
- The reduced-motion state is published as space[data-motion].
- The canvas needs no id, so two instances cannot collide.