A coming-soon page with a small 3D drone race on it. No build step — plain HTML, CSS and ES modules, with three.js vendored into the repo.
index.html page + WebGL capability check
style.css styling (all colours are CSS custom properties at the top)
game3d.js the race: course, arena, flight model, cameras
game.js 2D side-view sim, used only if WebGL is unavailable
404.html not-found page
vendor/ three.js r169 + the bloom postprocessing passes
ES modules need a real origin, so opening index.html from disk won't work:
python3 -m http.server 8000 # then open http://localhost:8000Twelve neon gates on a closed loop around a stadium. The drone flies forward on
its own — you only steer — so there's no throttle to manage and no way to
crash. Fly through the cyan gate; missing one costs two seconds. Clear all
twelve for a lap. Best lap is kept in localStorage.
| Key | Action |
|---|---|
W / ↑ |
climb |
S / ↓ |
dive |
A D / ← → |
turn (the airframe banks into it) |
Shift |
boost |
Space |
brake |
C |
switch chase ⇄ FPV |
R |
restart the lap |
On-screen buttons appear on touch devices and hide the moment a physical key is pressed.
The constants at the top of game3d.js are the whole feel of it:
const GATE_COUNT = 12;
const GATE_HALF = 3.6; // gate opening — raise to make the course easier
const CRUISE = 17; // units/s, the speed you fly at by default
const BOOST = 30;
const TURN_RATE = 1.75; // rad/s
const CLIMB_RATE = 11;The course is generated in one loop further down: twelve points around a
circle, radius and height modulated by a couple of sine terms, fed to a closed
CatmullRomCurve3. Change those sines and the whole track changes.
- Bloom is what makes the neon read, but its blur kernel is sized in texels, so on a canvas narrower than 640px it smears across the entire frame. It's switched off below that width and scaled with canvas size above it.
- The crowd, the ad boards and the pitch markings are drawn into
<canvas>textures at startup — no image files to load. window.__fpvexposes the scene, camera and state for poking at in devtools.