120

Warp Speed Background

£10 or the whole Vault, £99

A GSAP and WebGL starfield background the visitor flies: stars drift quietly behind your content, press and hold stretches them into streaks, and release jumps to warp speed before a long deceleration back to drift.

advanced
5 more details
webgl-shaderparticle-systemvelocitypointer-trackingchromatic-aberration

This demo reads better at your own screen size than in the frame below:

Released

About this effect

A hyperspace background where the speed belongs to the visitor. At rest it is a quiet starfield: points of light drifting slowly towards the viewer, sparse and dim enough to set a headline over. Most starfield and hyperspeed backgrounds run at one constant pace; this one waits for a hand on the throttle.

Read the full effect overview

Press and hold anywhere to charge a jump. The stars stretch into streaks, the tunnel draws in towards the vanishing point, and a warm and cool fringe opens on the streak ends as the charge builds. Let go and the field jumps: a burst to top speed that holds for a beat, then a long, exponential deceleration back to drift as the streaks shorten into points again. A short press makes a short hop; a full charge makes the full jump. The pointer steers the vanishing point, with a little weight, so the tunnel bends towards wherever the visitor looks.

The nearest and fastest streaks run amber; the rest stay chalk white on near black, and every colour comes from three CSS custom properties. Content you mark sits on a quieter patch of sky, where most stars drop out and the rest dim. There is no camera shake and no flash: the jump reads through speed and stretch alone. Visitors without WebGL or JavaScript, and anyone who prefers reduced motion, see a baked still of the starfield.

Warp Speed Background - GSAP animation effect preview

What's included

14 items
  • A calm WebGL starfield at rest, quiet enough for copy
  • Press and hold to charge: stars stretch into streaks, the tunnel tightens and a chromatic fringe grows on the streak ends
  • Release to jump: a burst to top speed, then a long exponential deceleration back to drift
  • The jump scales with the charge: a short press hops, a full charge makes the full jump
  • The pointer steers the vanishing point with weight, bending the tunnel
  • Amber on the nearest, fastest streaks; chalk white everywhere else; all three colours set in CSS
  • Calm zones: behind marked content most stars drop out and the rest dim
  • Drive the speed yourself, for example from scroll velocity with ScrollTrigger
  • Touch: tap plays the full jump, drag steers, and the vanishing point wanders between touches
  • Keyboard: Space or Enter on the focused stage plays the charge and release
  • No camera shake and no flashes; reduced motion removes the jump entirely
  • Pauses off screen and in hidden tabs, and stops drawing at rest when drift is off
  • Baked still for reduced motion, no WebGL and no JavaScript
  • Small API: jump, charge, set the speed, pause and play

Perfect for

5 use cases
  • Product launch and waitlist pages that want a countdown-to-launch feel
  • Developer tool, AI and infrastructure heroes where speed is the pitch
  • Event and conference landing pages
  • Game, space and sci-fi studio sites
  • A launch button wired to the jump, so the click itself feels fast

How it works

3 sections

A three.js WebGL shader draws every star in one call. Each star is a small quad that the shader stretches from where the star was a moment ago to where it is now, so its length follows its speed and how near it is; stars that fly past the viewer reappear at the far end of the tunnel, so the field never runs out. The streak ends are split by colour channel, warm leading and cool trailing, as the charge builds.

GSAP plays the timed moments: the reveal as the stars fade up, the charge under a held press, and the jump curve with its burst, its hold and its long fall. GSAP's media queries switch between pointer, touch and reduced-motion behaviour, and its context tears everything down. A frame loop on GSAP's ticker owns the continuous motion: the idle drift, a speed that rises at once and falls away exponentially, the distance flown and the weighted steering of the vanishing point.

The background stops drawing when it leaves the screen or the tab is hidden, and goes fully idle at rest when drift is switched off.

Difficulty Advanced
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this effect's demo, from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Paid effect

Purchase to unlock the code.

Buying Warp Speed Background opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

£10 Standard license, unlimited projects

Browse free effects

Or the whole library: the Vault, £99, one payment.

Documentation

Quick Start

1. Add to your HTML <head>:

Code snippet omitted: it ships with the download.

The inline script is not optional. The layer carries a baked still of the starfield for visitors without JavaScript or WebGL and for anyone who prefers reduced motion. Without this probe every visitor would download that image and see it for the moment three.js takes to arrive, then watch it swap for the canvas. The probe runs before first paint and stamps html.gl when a canvas is coming; the stylesheet drops the still under that class, so it is never even requested. The effect removes the class again if it cannot build a renderer after all.

2. Put the layer inside any positioned container, before your content:

Code snippet omitted: it ships with the download.

data-warp-calm marks content that should sit on a quieter patch of sky. Put it on the box that holds your text (up to four elements per layer).

3. Add before the closing </body> tag:

Code snippet omitted: it ships with the download.

Why the import map rather than a plain <script src> for three.js: three ships as ES modules only, and its old UMD build logs a deprecation warning on every page load. The shim imports it as a module (dynamically, so a blocked CDN falls back to the still instead of a blank layer), puts it on window, and then loads script.js as an ordinary script, so the effect itself stays a plain file you can drop into any build (or none).

Already using three.js as a module? Skip the shim and make sure window.THREE is set before script.js runs:

Code snippet omitted: it ships with the download.

Using It With Your Own Design

What the effect needs from your markup: a positioned container (relative, absolute or fixed) holding the [data-warp] layer and your content. The layer fills the container with position: absolute; inset: 0, at any size, so it works on a full-viewport hero or a single card. Your content needs position: relative (or any z-index context) to sit above it. The layer takes no pointer events; the container listens for the pointer instead, so steering and press-to-charge work over your text too. Presses on links, buttons and form fields are ignored.

What is only the demo's styling: everything under DEMO in style.css: the .stage box, its crosshair cursor and the cue line. Replace it wholesale.

CSS the effect depends on:

  • The container must have a real size. The canvas is sized from the layer, which takes the container's box.
  • The .warp block (position: absolute; inset: 0, overflow: hidden, pointer-events: none), .warp__canvas, and the .gl .warp rule that drops the still.
  • The two still images in img/, referenced from .warp and its portrait media query.
  • On touch screens the container needs touch-action: pan-y so vertical swipes still scroll the page. The script sets it inline while it runs if you have not.

Colours are custom properties on .warp, read once at start and handed to the shader, so a restyle never touches the script:

Code snippet omitted: it ships with the download.

Any CSS colour works (hex, rgb(), oklch(), color-mix()). Streaks add light, so the ground should stay dark: near black, deep navy or a dark aubergine. The chromatic split is drawn from these same colours (the accent leads, a cooled version of the streak colour trails), so it never introduces hues outside your palette.

If you change the colours, re-bake the still. The still images are a frame of the default palette. Screenshot your restyled layer with the content hidden (a landscape frame around 2400 x 1350 and a portrait one around 780 x 1690) and save them over img/warp-still.webp and img/warp-still-portrait.webp. Until you do, reduced-motion and no-WebGL visitors see the default still on top of your --warp-ground.

Contrast. Behind data-warp-calm content most stars drop out and the rest dim, so body copy stays readable at rest. At full warp speed long streaks still cross the whole layer, so give text that must stay legible during a jump its own backing (the demo cue uses an 82% ground-coloured pill, which holds above 7:1 with a full-brightness streak behind it).

Options

Attribute Values Default Description
data-warp (present) Marks the layer
data-warp-density 0.2 to 2.5 1 Star count multiplier (3,000 stars on desktop, 1,400 on touch screens at 1)
data-warp-drift 0 on 0 stops the idle drift and, on touch screens, the wandering vanishing point. The field then stands still until the visitor charges or jumps
data-warp-hold 0 on 0 disables press-to-charge and tap-to-jump. Keyboard, jump(), charge() and setSpeed() still work, so your own button can drive it
data-warp-intensity 0 to 1 1 Scales the whole response: charge, jump, split, tunnel tightening and steering range. At 0 only the drift remains
data-warp-calm (present) On content in the same container: quiets the sky behind it (up to four elements)
data-warp-keys (present) On a focusable ancestor: Space or Enter plays a jump

With data-warp-drift="0" the canvas stops drawing as soon as everything settles, and only wakes for input.

Behaviour

  • Load: the stars fade up out of the dark over about 1.2 seconds.
  • Rest: points drift slowly towards the viewer; the nearest show the faintest trail.
  • Pointer: the vanishing point follows the cursor with weight and travels part of the way towards it, so the tunnel bends rather than slides. When the pointer leaves the container it eases back to centre.
  • Press and hold: over 1.5 seconds the stars stretch into streaks, the tunnel tightens towards the vanishing point, the field gathers a little speed and the chromatic split grows on the streak ends.
  • Release: a burst to top speed for 0.4 seconds, then a 1.4 second exponential deceleration, after which the speed itself settles back to the drift. The jump scales with the charge: a quick click makes a short hop, a full charge the full jump. Pressing again mid-deceleration starts a new charge from wherever the field is.
  • Touch: tap plays the full scripted jump; drag steers the vanishing point, which wanders slowly on its own 2.5 seconds after your finger lifts.
  • Calm zones: behind marked content most stars drop out and the rest dim, with a soft edge so the sky reads as one field.
  • No camera shake and no flashes. The jump reads through speed and stretch alone.

Accessibility

  • Reduced motion: no canvas and no jump at all. The layer shows the baked still of the starfield, with short streaks for depth. No autonomous motion of any kind.
  • Without JavaScript, or without WebGL: the same still. It is never hidden until a canvas actually exists.
  • Keyboard: with data-warp-keys on a focusable ancestor, Space or Enter plays a short charge and release. Name the action in that element's aria-label and give it a visible focus ring (the demo's .stage:focus-visible).
  • Screen readers: the layer and its canvas are aria-hidden; nothing in them is content.
  • Vestibular safety: the jump is a short, centred acceleration with no shake, rotation or flash, and reduced motion removes it entirely.

Dependencies

Dependency Version Required
three.js 0.180.0 Yes, as an ES module (see Quick Start)
GSAP core 3.12+ (the demo is built against 3.15.0) Yes: the load reveal, the charge under a held press, the jump curve (burst, hold and exponential fall), the ticker the frame loop runs on, matchMedia branching and teardown

No GSAP plugins (the scroll recipe above adds ScrollTrigger on your side). GSAP plays the timed values; the frame loop owns the continuous ones (the drift, the speed that rises at once and falls exponentially, the distance flown and the steering); the shader places and stretches every star from those numbers each frame. Everything used from three.js (WebGLRenderer, ShaderMaterial, InstancedBufferGeometry, OrthographicCamera) is long-stable API, so pinning a different version is a one-line change in the import map.

Browser Support

Anything with WebGL, which is every current browser. Support is probed before three.js is asked for a renderer: three logs its own failure to the console as errors before it throws, so a visitor with WebGL disabled would otherwise get a console full of red on a page that had quietly fallen back. Probed first, that visitor gets the still and a clean console. In a browser too old for import maps the module never runs, and the still is again what shows.

Performance

One draw call per frame: every star is an instance of one small quad, positioned entirely on the GPU, so nothing is allocated or uploaded per frame. Stars that fly past the viewer reappear at the far end of the tunnel. The loop runs only while the layer is on screen and the tab is visible. Pixel ratio is capped at 2 (1.5 on touch devices), and touch devices draw fewer stars.

The first lever on low-end hardware is data-warp-density (try 0.6). Setting data-warp-drift="0" as well means the canvas draws only during a charge or jump, instead of continuously.

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.