Interactive GPX track visualization with smooth animation on a map using Leaflet.js. Features built-in video recording, automatic data persistence, and cinematic route playback.
- πΊοΈ Beautiful route animation with cinematic intro (zoom out β countdown β zoom in)
- π Automatic metrics calculation (distance, elevation, calories, time)
- π Upload GPX files through UI (no configuration needed)
- πΎ Automatic data persistence in localStorage
- π¬ Built-in video recording (no external tools required)
- π¨ Multiple map tile styles (CartoDB Light/Dark/Voyager, OSM, Satellite, etc.)
- π Start/finish markers with delays
- π― Optional camera follow during animation
- β±οΈ Adjustable animation duration (5-300 seconds)
- π Configurable zoom level with live preview
- βοΈ Customizable weight for calorie calculation
- π§ Collapsible sidebar with all controls
- π± Responsive design for mobile devices
- π΄ Track densification for smoother animation (5m intervals)
Clone the repository:
git clone https://github.com/outcomer/animated-route.git
cd animated-routeStart a local web server:
Python 3:
python -m http.server 8000Node.js (http-server):
npx http-server -p 8000PHP:
php -S localhost:8000Then open: http://localhost:8000
- Click the hamburger menu (β°) to open controls
- Click π Load GPX button
- Select your GPX file
- Track will be displayed automatically
- All data is saved to localStorage
That's it! No configuration files to edit.
Click the hamburger icon (β°) in the top-right corner to open/close the controls panel.
Track Management:
- π Load GPX - Upload a GPX track file
- β - Delete currently loaded track
Animation Controls:
- βΆ Animate - Begin route playback with cinematic intro (zoom out, 3-2-1 countdown, zoom in to route)
- βΊ Record - Record animation to video file with automatic fullscreen
Settings:
- Animation duration - Set total animation time (5-300 seconds)
- Zoom - Set zoom level for animation (0-18)
- My Weight - Set your weight in kg for calorie calculation (40-150)
- Use densified track - Use interpolated track with 5m point spacing for smoother animation
- Follow route during animation - Camera follows the animated route (when disabled, camera stays centered on full route)
- Map style - Choose from 9 different map tile styles
Click outside the sidebar to close it.
Record your animation directly in the browser with professional quality:
- Load a GPX track
- Click βΊ Record
- Grant screen capture permission
- Select the browser tab to record
- Browser enters fullscreen automatically
- Wait 3 seconds for fullscreen popup to disappear
- Animation starts with cinematic intro
- Video downloads automatically when complete
Recording Features:
- AV1 codec with 15 Mbps bitrate
- Up to 1920x1080 resolution (16:9 aspect ratio)
- 120 FPS capture capability
- Automatic filename based on GPX file name (
track-{filename}.webm) - Cursor hidden during recording
- Automatic fullscreen mode
- No controls visible during recording
Note: Recording requires a modern browser with MediaRecorder API support (Chrome/Edge recommended).
Edit js/track.js to customize defaults:
const state = {
title: 'GPX Route Viewer', // Page title
animationDuration: 60, // Default animation duration in seconds
cameraFollow: true, // Camera follows route by default
trackColor: 'rgb(0 0 0)', // Track line color (black)
initialZoom: 12, // Initial map zoom level
fullRoute: [], // Populated on GPX load
gpxData: null // Populated on GPX load
};The app includes 9 built-in map styles selectable via UI:
- CartoDB Light (default)
- CartoDB Dark
- CartoDB Voyager
- OSM Standard
- OSM HOT
- CyclOSM
- Satellite (ArcGIS World Imagery)
- World Street Map
- World Topo Map
Map style preference is saved to localStorage.
Edit js/TrackVisualization.js:
const DEFAULT_WEIGHT = 80; // kganimated-route/
βββ index.html # Main HTML file
βββ js/
β βββ track.js # Main entry point & configuration
β βββ TrackVisualization.js # Core application logic
β βββ UIController.js # UI controls handler
β βββ RouteAnimator.js # Animation engine (requestAnimationFrame)
β βββ GPXMetrics.js # Metrics calculation utilities
β βββ GPXDensifier.js # Track densification for smooth animation
βββ css/
β βββ track.css # Styles (Exo 2 font, Material Icons)
βββ favicon.svg # App icon
βββ .gitignore
βββ README.md
The app automatically calculates and displays:
- Distance - Total route length (km)
- Elevation - Gain and loss (meters)
- Speed - Moving average and total average (km/h)
- Time - Moving time and total time (HH:MM:SS)
- Calories - Estimated calories burned (kcal) based on:
- MET values for cycling at different speeds
- Body weight
- Elevation gain
Metrics are displayed in the info box at the bottom-left corner after loading a track.
All data is automatically saved to localStorage:
- GPX file content - Original track data
- GPX densified content - Processed track with 5m point spacing
- GPX file name - For display and video naming
- Weight - User's weight setting
- Animation duration - Preferred animation duration
- Zoom level - Preferred zoom level
- Camera follow - Camera follow preference
- Use densified - Track densification preference
- Map style - Selected map tile style
Storage key format: {hostname}_appData
Examples:
localhost_appDataexample.com_appData
- ES6 Modules - Modular code organization with JSDoc
- Leaflet.js - Map rendering and interaction
- Canvas Renderer - Efficient polyline rendering
- requestAnimationFrame - Smooth 60 FPS animation loop
- MediaRecorder API - In-browser video capture
- FileReader API - GPX file loading
- localStorage - Data persistence
- Material Icons - UI icons
- Exo 2 Font - Google Fonts typography
The animation uses requestAnimationFrame for smooth 60 FPS playback:
- Time-based animation (not frame-based)
- Configurable duration (5-300 seconds)
- Cinematic intro sequence with zoom and countdown
- Optional camera follow mode
- Progress indicator during playback
Tracks are automatically processed to ensure smooth animation:
- Interpolates points to 5m spacing
- Preserves elevation data
- Generates timestamp estimates
- Quality verification with warnings
- Modern browser with:
- ES6 module support
- MediaRecorder API (for video recording)
- FileReader API (for GPX upload)
- Fullscreen API (for recording)
- Dynamic Viewport Height support (
dvhunits)
- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
Edit js/track.js:
trackColor: 'rgb(255 0 0)', // Red trackEdit index.html:
<input type="range" id="durationSlider" min="5" max="300" step="5" value="60">Edit js/TrackVisualization.js in the startRecording() method:
const options = {
mimeType: 'video/webm;codecs=av1',
videoBitsPerSecond: 15000000 // 15 Mbps
};Edit js/TrackVisualization.js in the initMap() method to change marker URLs:
this.startIcon = L.icon({
iconUrl: 'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png',
// ...
});- Export from fitness apps (Strava, Garmin Connect, Komoot, etc.)
- Record with GPS tracking apps
- Create custom routes with GPX Studio
- Animation optimized with Canvas renderer
- Densified tracks provide smoother animation
- Original tracks work fine but may appear jerky
- Large files (>5MB) may exceed localStorage limits
- Sidebar is collapsible and touch-friendly
- Click/tap outside sidebar to close it
- Uses dynamic viewport height (
100dvh) for proper mobile display - Info box adjusts to screen size
GPX file not loading:
- Must use local web server (not
file://protocol) - Check browser console for errors
- Ensure GPX file is valid XML with
<trkpt>elements
localStorage quota exceeded:
- Large GPX files may exceed 5-10MB browser limit
- Simplify track or use smaller GPX files
- Clear old data from localStorage
Video recording not working:
- Ensure browser supports MediaRecorder with AV1 codec
- Select the correct browser tab when prompted
- Check browser permissions for screen capture
- Try Chrome/Edge if Firefox has issues
Sidebar footer not visible on mobile:
- Uses
100dvhfor proper mobile viewport handling - Update browser to latest version
- Try landscape orientation for more vertical space
Animation stuttering:
- Enable "Use densified track" for smoother animation
- Close other browser tabs
- Increase animation duration for slower playback
- Reduce recording resolution expectations
MIT
Pull requests are welcome! For major changes, please open an issue first.
- Leaflet.js - Interactive map library
- OpenStreetMap - Map data
- CartoDB - Map tiles
- Google Fonts - Exo 2 typeface
- Material Icons - UI icons
David Evdoshchenko
- GitHub: @outcomer
- LinkedIn: david-evdoshchenko
For issues and questions, please open a GitHub issue.