Particle field

stable 3.1 kB
<hk-particle-field>

Drifting points that draw a line when they come close. The link pass is the expensive half — naively O(n squared) per frame, which is why most versions of this crawl past a few hundred particles. This one bins into a spatial grid sized to the link distance, so each particle only tests its nine neighbouring cells.

#background#canvas#decorative

Live demo

Running in this page — interact with it.

Inputs

NameTypeDefaultDescription
colorstring'#dc2626'Base colour. Any hex the background derives its palette from.
speednumber1Animation multiplier. 0 freezes on the first frame.
opacitynumber1Canvas opacity — these sit behind real content.
pausedbooleanfalseStops the loop without unmounting.
densitynumber0.9Particles per 10,000 css px². Scaled by area, so it reads the same at any size.
linkDistancenumber110Max px between two particles for a link. 0 disables linking.
repelRadiusnumber120Radius in px within which the pointer pushes particles away.
particleSizenumber1.8Base dot radius in px.

Theming

Component tokens, each falling back to a global one:

PropertyDefaultControls
--hk-bg-color#dc2626Base hue. Every background derives its palette from it.

Accessibility

  • The canvas is aria-hidden — a decorative layer must never be announced.
  • Under prefers-reduced-motion it paints one frame and never starts the loop.
  • The loop stops when the element scrolls out of view and when the tab is hidden, so an offscreen background costs nothing.
  • Frames run outside the Angular zone, so animating never triggers change detection in the rest of the app.
  • Pointer tracking is bound outside the zone and never allocates, so moving across a dense field stays at frame rate.

More in Backgrounds