Portfolio
  • 01Home
  • 02Projects
  • 03About
  • 04Skills
  • 05Lab
  • 06Writing
  • 07Contact

© 2026 Hamza Syrage

LabView all
Arrow FieldCursorCursor SpotlightCursorGooey CursorCursorImage CompareMediaInteractive ChartDataMagnetic ButtonInteractionMarquee RevealTypographyMorphing ShapeAnimationsNested ViewsOverlaysOdometer CounterDataParticle ConstellationCanvasRipple ClickButtonsScroll RevealScrollShuffle GridLayoutStep WizardNavigationTabsNavigationTilt CardCards

UI Experiments

All Lab Entries
Canvas

Particle Constellation

A field of drifting particles that link up into a live network as the cursor moves through.

A field of particles drifting across a canvas, connected by lines when they're close enough. No framer-motion here, just a requestAnimationFrame loop drawing directly to a <canvas>.

#Step 1: Static Particles

Start with a canvas sized to match its CSS dimensions, accounting for devicePixelRatio. Randomly position 55 particles and draw them as small dots. No animation yet.

tsx
Loading...

#Step 2: Drift Animation

Add a requestAnimationFrame loop. Each frame, every particle moves by its velocity. If it hits an edge, the velocity component is negated (bounce). The ctx.setTransform(1, 0, 0, 1, 0, 0) call resets the canvas transform before re-scaling, preventing stacked scales on resize.

tsx
Loading...

#Step 3: Cursor Linking

Check every pair of particles for distance. If they're within LINK_DISTANCE (90px), draw a line between them. The cursor gets its own links with a larger distance (140px) and a claret color. The i + 1 in the inner loop avoids drawing each line twice. This is O(n²), fine for 55 particles, but you'd want a spatial hash grid for 500+.

tsx
Loading...

#Step 4: Distance Fade

Lines now fade based on distance. The opacity formula 1 - dist / LINK_DISTANCE means particles at distance 0 are fully opaque, and particles at the threshold are fully transparent. Stronger connections near the pointer.

tsx
Loading...

#Configuration

Tune the particle count, link radius, drift speed, and line opacity.

All parameters
Particles55
Link distance90px
Drift speed0.4
Line opacity1
tsx
Loading...