Skip to main content

Documentation Index

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

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

Aurora Drift achieves its organic, weightless motion through spring-based animations rather than fixed-duration tweens. Instead of saying “move from A to B in 0.3 seconds,” spring animations apply simulated physical forces — stiffness pulls the value toward its target while damping resists overshoot — producing motion that feels alive and naturally decelerating. The custom useSpring hook in assets/use-spring.js wraps Framer Motion’s low-level motionValue.attach() API to expose this physics model as a simple composable hook.

What Is Spring Physics?

A spring animation has no fixed duration. It is governed entirely by three parameters:
  • Stiffness — how aggressively the value accelerates toward its target. Higher stiffness = snappier, more energetic movement.
  • Damping — how quickly the oscillation decays. Higher damping = less bounce, faster settling.
  • Mass — the simulated weight of the object. Higher mass = slower response, more inertia.
This mirrors how a real spring behaves: pull it far and release it — a stiff spring snaps back fast, a loose one drifts lazily. This is why Aurora’s aurora layer drifts with a dream-like lag while the cursor glow responds almost instantly.

The useSpring Hook

The hook lives in assets/use-spring.js and accepts a source value (either a raw number or an existing MotionValue) plus a config object.
// assets/use-spring.js (simplified)
import { useMotionValue } from 'framer-motion';

// Signature:
// useSpring(source, config)
//   source — a number or MotionValue
//   config — { damping, stiffness, mass? }
// Returns a derived MotionValue that spring-follows `source`

Basic Usage

import { useMotionValue } from 'framer-motion';
import { useSpring } from '../assets/use-spring';
import { motion } from 'framer-motion';

function MyComponent() {
  // 1. Create a raw motion value for the "target" position
  const rawX = useMotionValue(0);

  // 2. Derive a spring-interpolated follower
  const springX = useSpring(rawX, { damping: 25, stiffness: 200, mass: 0.5 });

  // 3. Drive the element with the spring output
  return <motion.div style={{ x: springX }} />;
}
useSpring uses motionValue.attach() internally, which wires the spring into Framer Motion’s frameloop. This means the spring updates every animation frame without triggering React re-renders — no useState, no reconciliation overhead.

Spring Presets Used in Aurora Drift

Each major animated element in the project uses a carefully tuned preset that matches its visual role:
PresetstiffnessdampingmassUsed InFeel
Aurora parallax40050AuroraBackgroundSlow, heavy, majestic drift
Cursor glow200250.5CursorGlowSnappy, light, responsive
Nav underline30030Nav (layoutId)Balanced, confident slide

Aurora Background Parallax

The aurora SVG layer uses high damping to create that slow, fog-like lag behind the mouse:
// AuroraBackground.js
const springX = useSpring(x, { damping: 50, stiffness: 400 });
const springY = useSpring(y, { damping: 50, stiffness: 400 });

Cursor Glow Follow

The glow orb needs to feel attached to the cursor without being glued to it. A lighter mass and lower damping keep it feeling floaty:
// CursorGlow.js
const config = { damping: 25, stiffness: 200, mass: 0.5 };
const springX = useSpring(rawX, config);
const springY = useSpring(rawY, config);
The active-route underline uses Framer Motion’s built-in layout animation with a spring transition, giving it a fluid slide between nav items:
// Nav.js
<motion.div
  layoutId="nav-underline"
  transition={{ type: 'spring', stiffness: 300, damping: 30 }}
/>
To make any animation feel snappier, increase stiffness — the spring pulls harder toward the target. To reduce bounce or overshoot, increase damping — it absorbs kinetic energy faster. These two knobs are usually enough; only reach for mass when you need to simulate a heavier or lighter physical object.

Setting Up a Spring Animation: Step by Step

1

Create a source MotionValue

Use useMotionValue to create the “target” that your element will chase.
const rawX = useMotionValue(0);
2

Attach a spring follower

Pass the source and your config to useSpring. The returned value automatically tracks rawX with physics.
const springX = useSpring(rawX, { damping: 25, stiffness: 200 });
3

Wire up an event handler

On user interaction (e.g., mousemove), update the raw value — the spring output will follow automatically.
useEffect(() => {
  const onMove = (e) => rawX.set(e.clientX);
  window.addEventListener('mousemove', onMove);
  return () => window.removeEventListener('mousemove', onMove);
}, [rawX]);
4

Apply to a motion element

Pass the spring MotionValue to a motion.* element’s style prop.
return <motion.div style={{ x: springX }} />;

Spring vs. Tween: When to Use Each

Tween animations play over a fixed duration using an easing curve (e.g., ease-out over 0.3s). They are predictable and great for UI transitions that need to complete in a guaranteed time — like a modal appearing or a button state change.Spring animations are physics-driven and have no fixed duration. They continue until the simulated energy dissipates below a threshold (restDelta and restSpeed). The main trade-offs:
TweenSpring
DurationFixedVariable (physics-driven)
InterruptionCan look abrupt mid-playInherits current velocity — feels natural
Use caseUI state changes, entrancesPointer tracking, layout shifts, gesture responses
Configduration, easestiffness, damping, mass
Aurora Drift uses springs for all pointer-reactive elements because they handle interruption gracefully — if the user moves the mouse before the animation settles, the spring picks up the velocity and continues smoothly rather than snapping.

Quick Reference

Snappy & Light

{ stiffness: 200, damping: 25, mass: 0.5 }Best for: cursor tracking, hover effects, small interactive elements

Slow & Majestic

{ stiffness: 400, damping: 50 }Best for: background parallax, large decorative layers, ambient motion

Balanced Slide

{ type: 'spring', stiffness: 300, damping: 30 }Best for: nav indicators, tab underlines, card selection highlights

Bouncy & Energetic

{ stiffness: 500, damping: 10 }Best for: confirmation feedback, icon toggles, playful micro-interactions

Build docs developers (and LLMs) love