Turn a GPX, TCX or FIT file into a 3D terrain flyover video, in your browser.
English | Traditional Chinese | Simplified Chinese | Japanese | Korean | Spanish | French | German | Portuguese
450 frames in 236 seconds, no GPU. I rendered the 9.15 km sample route to a 15 s, 1080 x 1920 H.264 clip of 12.8 MB. The command was npm run render -- public/samples/yushan.gpx out.mp4 --title "Yushan Main Peak". It ran in Google Chrome 149 on a 3 core Linux machine with software WebGL (SwiftShader), so no graphics card helped. I haven't timed a machine with a GPU.
A route video should be made where your file already is. Ridgereel has no server and no account. A Web Worker reads the file and your own browser encodes the video.
| Before | After | |
|---|---|---|
| File | yushan.gpx, 71 KB, 671 trackpoints |
ridgereel-yushan-main-peak.mp4, 12.8 MB |
| Picture | Coordinates in XML | 1080 x 1920 H.264, 15 s, 30 fps, 450 frames |
| Stats | Not shown | Distance 9.15 km, ascent 1,371 m, time 4:17:54, drawn into the frame |
| Start and end | Exact coordinates | The first and last 200 m are cut and the map there is pixelated |
| Where it ran | A file on your disk | Your browser tab |
The sample route takes its geometry from OpenStreetMap and its elevation from terrain tiles. Its timestamps are synthetic, worked out with Naismith's rule, and the file says so in its metadata. It demos the renderer and isn't a recorded activity.
Open the live demo, press Try the sample route, then press Export video. To use your own route, drop a .gpx, .tcx or .fit file on the page. Files from the same trip can be dropped together. Not sure how to export a file from your watch or app? See Get your file.
- Reads GPX, TCX and FIT files from Garmin, Strava, Coros, Suunto, Apple Watch and similar, including a
.gzor.zipthat holds one. - Builds 3D terrain from AWS Terrarium elevation tiles and drapes satellite, topographic, street or generated relief imagery over it. A custom tile URL works too.
- Has three cameras: follow, drone and overview.
- Exports 9:16, 1:1 or 16:9 MP4 with WebCodecs. Every frame depends only on the time, so the same settings give the same picture.
- Keeps the stats clear of the Reels and Threads buttons in 9:16.
- Previews the finished video, and on a phone you can share it straight from the page.
- Draws distance, ascent, time, pace or speed, an elevation profile, a title and the map credits into the video.
- Comes in nine interface languages, listed at the top of this page.
Ridgereel is a static web app, so the demo needs no install.
Run it on your machine
You need Node 20 or newer.
git clone https://github.com/Arthur031221/Ridgereel.git
cd Ridgereel
npm install
npm run devOpen http://localhost:5173. Video export needs a secure context, and localhost counts as one.
Host it yourself
npm run buildCopy the dist folder to any static host. Serve it over https, since WebCodecs only works in secure contexts. To publish under a sub path such as GitHub Pages, build with GITHUB_PAGES=1 and the base path becomes /Ridgereel/. Change base in vite.config.ts if your repository has another name.
Render from the command line
npm install
npm run render -- route.gpx out.mp4 --ratio 9:16 --duration 15 --preset followThis opens the same app in headless Google Chrome and saves the download. It needs Chrome and a network connection for tiles. Set CHROME if the binary isn't at /usr/bin/google-chrome. The options are listed in docs/usage.md.
Your file is never uploaded. The end to end test loads a route whose name contains a marker, records every request the page makes, and fails if any request goes to a host other than the app and the four tile servers, isn't a GET, or carries that marker.
Tile servers still see which area you open, because that's how a map works. If the place matters, keep Hide start and end on and choose a map service you trust. The default cuts 200 m from both ends of the route and pixelates the imagery around the original start and end.
- I tested export in Chrome only. Edge and Safari have WebCodecs and should work, but I haven't run them.
- A browser without WebCodecs falls back to a real time recording. Timing then depends on your machine and the result isn't frame exact.
- Imagery is one 4096 pixel texture across the whole scene. On a long route the ground near the camera looks soft.
- The Esri, OpenTopoMap and CARTO servers are public and have their own terms. They suit personal use. For heavy or commercial use, point the Custom style at a source you're licensed to use. See THIRD_PARTY_NOTICES.md.
- There's no npm package. Ridgereel is an app, and you run it from this repository.
The route is cleaned and resampled about every 5 m, capped at 3,000 samples. Elevation tiles are decoded and stitched into one terrain, and a Three.js scene draws it with a 2D overlay on top. The encoder reads that canvas frame by frame. docs/architecture.md has the details.
Pull requests are welcome, and adding a language takes one JSON file. See CONTRIBUTING.md.
MIT. Map data and fonts keep their own licenses, listed in THIRD_PARTY_NOTICES.md.
Assisted by Claude/Codex.
