Three.js Scroll Rocket Launch — Stage Separation Scrub

Three.js Scroll Rocket Launch Sequence · Scroll · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

Mission-profile phase table: pre-launch, boost, stage sep, orbit burn — classified per frame from one scrubbed value
Stage separation through group hierarchy: booster diverges locally while the parent keeps climbing — no re-parenting
Thrust-gated exhaust: 500 lifetime-recycled particles that die at MECO and relight for the second burn automatically
Exhaust respawns at whichever nozzle is active — booster before separation, upper stage after
Quadratic altitude curve so the climb accelerates like a vehicle burning off mass
One darkness scalar lerps sky, fog, and star opacity in lockstep — stars cannot appear in blue sky
Ignition rumble: 60 Hz sine on X, amplitude-enveloped by the pre-launch window
Phase-aware chase camera that switches its framing target at separation

About this UI Snippet

How to Build a Scroll-Driven Rocket Launch With Stage Separation in Three.js

Screenshot of the Three.js Scroll Rocket Launch Sequence snippet rendered live

The Three.js Scroll Rocket Launch Sequence snippet flies a two-stage rocket from a rumbling launch pad to orbit in one scroll: ignition shake, an accelerating boost climb, booster separation with a tumbling fall-away, an upper-stage relight, and a sky that darkens from dawn blue to starfield black as altitude accrues. GSAP's ScrollTrigger scrubs one flight value; a phase table carves it into the mission timeline.

A mission profile, not an animation timeline

The scroll is divided the way real launches are: pre-launch below 8%, boost to 58%, a five-point separation window, then the orbit burn. Each frame classifies the scrubbed value against these fractions and derives phase-specific behavior — rumble amplitude, thrust level, which nozzle emits, HUD phase text. Because classification happens per frame from one value (rather than chained tweens firing), scrubbing backwards flies the mission in reverse: the booster re-attaches, the sky re-lightens, the rumble returns. The quadratic altitude curve alt² × 190 makes the climb accelerate like a vehicle burning off mass, opposite to the braking curve of the planet approach.

Stage separation via group hierarchy

The rocket is a Group containing two child groups — booster and upper stage. Before separation both inherit the parent's climb; after it, the booster's *local* position and rotation animate away (falling on its own quadratic, drifting sideways, tumbling 1.8 radians) while the parent group keeps climbing with the upper stage. No re-parenting, no world-matrix surgery: the separation is two local transforms diverging inside one hierarchy, the same leverage the exploded view uses for its chips.

Exhaust with lifetimes, gated by thrust

The plume is 500 recycled particles, each with a life value that wraps at 1. On rebirth, a particle respawns at the *currently active* nozzle — booster bottom before separation, upper-stage bottom after — but only if thrust exceeds 0.15; otherwise it parks at y = −9999. This spawn-gating means the plume naturally dies during the separation coast and re-ignites for the orbit burn, with no particle-system on/off switch: the thrust scalar is the only control. A flickering point light at the nozzle (intensity thrust × (2.2 + sin(40t) × 0.5)) lights nearby geometry with engine glow.

Sky-to-space is one lerp driving three systems

Altitude normalizes into a darkness value that simultaneously lerps the background color, re-colors the fog to match (the halo-avoidance rule from the ocean dive), and fades in a 900-point starfield that only becomes visible past 35% darkness. One derived scalar keeps the three systems in perfect sync — no way for stars to appear in a blue sky.

A chase camera with phase awareness

The camera reads like launch coverage: low and looking up at the pad, pulling alongside during boost (its Y tracks 96% of rocket altitude so the vehicle slowly outruns it), then drifting wider and higher as space arrives. Its look-at target switches from the booster's midsection to the upper stage after separation, keeping the active vehicle framed while the spent booster tumbles out of shot. The ignition rumble is a 60 Hz sine on the rocket's X position, amplitude-enveloped by the pre-launch window — a cheap, effective shake that also feeds the exhaust spawn origin. For the descent-flavored sibling of this scene, see the staircase climb; for city-scale flyover framing, the city flyover.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You do not need to storyboard a launch from scratch — the mission profile is already a phase table you can edit. Paste this snippet's HTML, CSS, and JS into an AI assistant like Claude and ask it to explain the group-hierarchy separation trick, the thrust-gated particle respawn, or the single darkness scalar syncing sky, fog, and stars. The same assistant can extend the mission — a launch tower that retracts its arm at ignition, a max-Q condensation ring at a set altitude, fairing halves that jettison after separation using the same local-divergence pattern, a second booster for a side-core configuration, or a countdown overlay that ticks with early scroll. It can also re-tune the phase fractions so separation lands exactly on your page's key message. Treat the code as a starting point to interrogate and reshape, not a finished artifact.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "scroll-driven two-stage rocket launch" in plain HTML, CSS, and JavaScript using Three.js and GSAP's ScrollTrigger plugin, all loaded from a CDN (no bundler, no build step).

Requirements:
- A pinned full-viewport section with a canvas, WebGLRenderer, PerspectiveCamera (resized with aspect on window resize), ambient + warm directional light, a wide ground cylinder, and a launch tower box beside the pad.
- A rocket as a Group containing TWO child groups: a booster (cylinder body, 4 fins, nozzle) and an upper stage (cylinder + cone capsule). White MeshStandardMaterial bodies with dark accents.
- One GSAP tween (ease "none") scrubbing p 0→1 on a ScrollTrigger with pin: true, scrub ~0.5, end ~+=500%.
- A mission phase table applied per frame: pre-launch below 0.08 (60 Hz X-rumble with a ramp-in envelope), boost to SEP = 0.58, a 0.05-wide separation coast, then orbit burn. Derive thrust per phase: 0 → 1 → 0.1 → 0.75.
- Altitude = ((p − 0.08) / 0.92)² × 190 clamped at 0, applied to the rocket group — an ACCELERATING climb.
- Stage separation WITHOUT re-parenting: after SEP the booster's LOCAL transform diverges (its own downward quadratic, sideways drift, ~1.8 rad tumble) while the parent group keeps climbing with the upper stage; before SEP its local transform resets to identity so reverse scroll re-attaches it.
- Exhaust: 500 particles with wrapping lifetimes; on wrap, respawn at the ACTIVE nozzle (booster bottom before SEP, upper-stage bottom after) only when thrust > 0.15, else park at y = −9999. Additive blending, plus a flickering PointLight at the nozzle scaled by thrust.
- One darkness scalar dark01 = min(1, altitude/130) lerping the sky background dawn-blue → black, copying the same color into the fog, and fading in a 900-point starfield only past 0.35.
- A chase camera: low and looking up pre-launch, tracking ~96% of altitude alongside during boost, widening in space; its lookAt target switches from booster midsection to upper stage at SEP.
- A HUD with live altitude (scaled to km) and phase name (PRE-LAUNCH / BOOST / STAGE SEP / ORBIT BURN); intro overlay fades at p > 0.02.
- Confirm reverse scrolling flies the mission backwards, booster re-attaching and sky re-lightening.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Load the three CDN scriptsAdd three.min.js, gsap.min.js, and ScrollTrigger.min.js in that order before the snippet JS.
  2. 2
    Paste HTML, CSS, and JSA white two-stage rocket stands beside its tower under a dawn sky, HUD reading ALT 0.0 KM · PRE-LAUNCH.
  3. 3
    Scroll to igniteThe vehicle shakes with a 60 Hz rumble, the plume lights, and liftoff begins — altitude climbing on an accelerating curve.
  4. 4
    Watch separation at 58%The booster tumbles away trailing nothing while the upper stage coasts briefly, then relights for the orbit burn.
  5. 5
    Reach orbitThe sky completes its fade to black, stars at full strength, HUD reading ORBIT BURN as the camera settles wide.
  6. 6
    Re-profile the missionAdjust SEP and the phase fractions, the alt² × 190 climb curve, or the thrust table to fly a different vehicle.

Real-world uses

Common Use Cases

Aerospace and launch-provider sites
The obvious literal fit — annotate each phase with mission copy pinned via scroll pin steps.
Startup "launch" landing pages
Product launches get the metaphor at full fidelity: countdown, liftoff, stage sep as feature tiers, orbit as the CTA.
Space sim and strategy game promos
Kerbal-adjacent games can preview ascent mechanics; hand off to the black hole approach for late-game stakes.
Teaching phase-based scrub design
A compact study in carving one scrubbed value into mission phases with per-phase behavior — reusable for any multi-act sequence.
Portfolio hero with vertical momentum
The climb-and-darken arc gives personal sites a punchy opening that resolves into a calm starfield for content below.
Milestone and funding storytelling
Map boost to growth metrics and separation to a pivot — the altitude HUD doubles as a counter like the animated stat row.

Got questions?

Frequently Asked Questions

The rocket Group contains booster and upper-stage child groups. Both inherit the parent's climb, so before separation their local transforms are identity. After p crosses SEP, the booster's LOCAL position and rotation animate away — falling on its own quadratic, drifting sideways, tumbling — while the parent keeps rising. World position = parent climb + local divergence, so the fall-away is automatic and perfectly reversible when scrolling back.

Each particle has a lifetime that wraps at 1. On wrap it respawns at the active nozzle only if the thrust scalar exceeds 0.15; otherwise it parks off-screen at y = −9999. Thrust is derived per frame from the phase table (1 during boost, 0.1 during the separation coast, 0.75 for the orbit burn), so the plume dies and relights purely as a consequence of thrust — there is no explicit particle-system toggle anywhere.

All three consume one derived scalar: dark01 = min(1, altitude / 130). The background lerps dawn-blue to space-black by it, the fog color copies the same lerped color (so distant geometry dissolves correctly at every altitude), and star opacity is max(0, dark01 − 0.35) × 1.4, keeping stars invisible until the sky is ~35% dark. One input, three outputs — desynchronization is structurally impossible.

A 60 Hz sine on the rocket's X position — sin(t × 60) × 0.06 — multiplied by an envelope that ramps in across the 2%–10% scroll window and is zero elsewhere. The exhaust spawn origin and engine light follow the same offset, so the whole vehicle-plus-plume assembly shakes as one. It reads as engines straining against hold-downs at a cost of one line.

Yes. Export via the JSX, Vue, Angular, or Tailwind buttons. Build the rocket hierarchy, particles, and ScrollTrigger in a mount effect against a canvas ref; update the two HUD spans through refs since they change per frame. On cleanup kill the ScrollTrigger, dispose all geometries and materials (booster, upper stage, exhaust, stars, ground, tower), and call renderer.dispose().