Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/aurora-borealis/llms.txt

Use this file to discover all available pages before exploring further.

The StarField component paints a living night sky directly onto a full-screen HTML <canvas> element. It runs entirely outside of React’s render cycle — after the initial mount, all updates happen through a requestAnimationFrame loop that drives star movement, opacity oscillation, and the occasional shooting star. The canvas is transparent so it composites cleanly over AuroraBackground without blocking its gradient layers.

Usage

import { S as StarField } from './components/StarField.js';

export default function App() {
  return (
    <>
      <AuroraBackground />
      <StarField />
      {/* Foreground content */}
    </>
  );
}
StarField accepts no props. Star density, twinkle speed, and shooting-star parameters are all controlled by constants inside the component file.

Star generation

On mount and on every resize event the component recalculates the number of stars to fill the current viewport using a density formula:
const count = Math.floor(canvas.width * canvas.height / 4000);
This keeps the visual density constant across screen sizes — a 1920 × 1080 display generates roughly 518 stars, while a 390 × 844 mobile viewport generates about 82. Each star is initialised with the following properties:
PropertyRangePurpose
x0 – canvas.widthHorizontal position
y0 – canvas.heightVertical position
size0.5 – 2 pxRadius of the drawn circle
opacity0.0 – 1.0 (random)Starting brightness
speed0 – 0.05 px/frameUpward drift velocity
twinkleSpeed0.005 – 0.025Opacity change per frame
twinkleDir+1 or −1Current twinkle direction
Star color is fixed at rgba(236, 254, 255, opacity) — a near-white cyan that reads as neutral starlight over teal and violet aurora bands.

Animation loop

The requestAnimationFrame loop performs three operations per frame for each star:

1. Upward drift

Each star moves upward by its speed value every frame:
star.y -= star.speed;
When a star drifts above the top edge (y < 0), it wraps to the bottom of the canvas with a freshly randomised x position, creating a continuous slow parallax.

2. Twinkling

Opacity walks linearly using twinkleSpeed and twinkleDir:
star.opacity += star.twinkleSpeed * star.twinkleDir;
if (star.opacity >= 1.0 || star.opacity <= 0.1) {
  star.twinkleDir *= -1; // reverse direction at bounds
}
The 0.1 floor keeps stars faintly visible at all times rather than blinking to full black, preserving the field density.

3. Drawing

Each star is rendered as a filled circle:
ctx.beginPath();
ctx.arc(star.x, star.y, star.size, 0, Math.PI * 2);
ctx.fillStyle = `rgba(236, 254, 255, ${star.opacity})`;
ctx.fill();
The canvas is cleared with ctx.clearRect at the start of every frame so transparent compositing over the aurora background remains correct.

Shooting star system

Trigger probability

Each frame has a 0.5 % chance of spawning a new shooting star (threshold: Math.random() > 0.995). A maximum of 3 shooting stars can be active simultaneously.

Trail appearance

Each shooting star is drawn as a gradient line — rgba(236, 254, 255, opacity) at the head fading to fully transparent at the tail — using the Canvas 2D createLinearGradient API.

Shooting star properties

PropertyValue / RangeNotes
Initial x0 – canvas.widthRandom horizontal spawn
Initial y0Always spawns at the top edge
length20 – 100 pxTrail length
speed5 – 15 px/frameTravel velocity
angleπ/4 ± 0.1 radNear-45° diagonal
opacity1.0 (initial)Decreases by 0.015 per frame

Fade and removal

Each active shooting star loses 0.015 opacity per frame. Once opacity <= 0, it is removed from the active array, freeing a slot for a future spawn. The combination of travel speed and fade rate means the longest possible shooting star trail is visible for approximately 67 frames (~1.1 s at 60 fps).

Resize behavior

window.addEventListener('resize', () => {
  canvas.width  = window.innerWidth;
  canvas.height = window.innerHeight;
  initStars(); // regenerates the star array for the new dimensions
});
Resizing resets the canvas dimensions and regenerates the star array from scratch. The animation loop is not interrupted — the next frame simply draws the new star set. The resize listener is removed during React’s cleanup phase (useEffect cleanup) alongside cancellation of the requestAnimationFrame handle, preventing memory leaks in strict-mode double-invocations and during hot-module replacement.

Performance notes

The canvas is positioned with fixed inset-0, set to pointer-events-none, and given a transparent background. This ensures it never captures user input and that the browser’s compositor can layer it directly over AuroraBackground without a paint invalidation.
Because all drawing happens in the requestAnimationFrame callback rather than in React state, there are zero re-renders after mount. The only React involvement is the initial useEffect that obtains the canvas ref and starts the loop.

Customization

All customization requires editing components/StarField.js. There are no props.

Star density

Adjust the divisor in the density formula. Smaller values produce more stars; larger values produce fewer:
// Default — roughly 1 star per 4000 px²
const count = Math.floor(canvas.width * canvas.height / 4000);

// Denser — 1 star per 2500 px²
const count = Math.floor(canvas.width * canvas.height / 2500);

// Sparser — 1 star per 8000 px²
const count = Math.floor(canvas.width * canvas.height / 8000);

Twinkle speed

The twinkleSpeed for each star is set during initStars:
twinkleSpeed: Math.random() * 0.02 + 0.005  // range: 0.005 – 0.025
Increase the multiplier for faster, more restless twinkling; decrease it for a calmer, slow-breathing effect.

Shooting star probability

The spawn check runs once per frame:
if (Math.random() > 0.995 && shootingStars.length < 3) {
  // spawn
}
  • Raise the threshold (e.g. 0.998) for rarer events.
  • Lower the threshold (e.g. 0.990) for more frequent streaks.
  • Change 3 to allow more simultaneous shooting stars.
Setting the density divisor below 1500 on a 4K display can push star counts above 5 000 and cause frame-rate drops on lower-end GPUs, since each star requires its own arc + fill draw call.
To give shooting stars a warmer color (gold instead of white), replace the head color in the createLinearGradient call with rgba(253, 224, 71, opacity) for a meteorite-like streak.

Build docs developers (and LLMs) love