Skip to content

Repository files navigation

Animated GPX Route Viewer

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.

Features

  • πŸ—ΊοΈ 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)

Quick Start

1. Setup

Clone the repository:

git clone https://github.com/outcomer/animated-route.git
cd animated-route

2. Run

Start a local web server:

Python 3:

python -m http.server 8000

Node.js (http-server):

npx http-server -p 8000

PHP:

php -S localhost:8000

Then open: http://localhost:8000

3. Load GPX File

  1. Click the hamburger menu (☰) to open controls
  2. Click πŸ“ Load GPX button
  3. Select your GPX file
  4. Track will be displayed automatically
  5. All data is saved to localStorage

That's it! No configuration files to edit.

Controls

Sidebar Menu

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.

Video Recording

Record your animation directly in the browser with professional quality:

  1. Load a GPX track
  2. Click ⏺ Record
  3. Grant screen capture permission
  4. Select the browser tab to record
  5. Browser enters fullscreen automatically
  6. Wait 3 seconds for fullscreen popup to disappear
  7. Animation starts with cinematic intro
  8. 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).

Configuration

Application State

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
};

Map Styles

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.

Default Weight

Edit js/TrackVisualization.js:

const DEFAULT_WEIGHT = 80; // kg

Project Structure

animated-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

Metrics Calculated

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.

Data Persistence

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_appData
  • example.com_appData

Technical Details

Architecture

  • 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

Animation System

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

Track Densification

Tracks are automatically processed to ensure smooth animation:

  • Interpolates points to 5m spacing
  • Preserves elevation data
  • Generates timestamp estimates
  • Quality verification with warnings

Browser Requirements

  • Modern browser with:
    • ES6 module support
    • MediaRecorder API (for video recording)
    • FileReader API (for GPX upload)
    • Fullscreen API (for recording)
    • Dynamic Viewport Height support (dvh units)

Tested On

  • Chrome/Edge 90+
  • Firefox 88+
  • Safari 14+

Customization

Change Track Color

Edit js/track.js:

trackColor: 'rgb(255 0 0)',  // Red track

Modify Animation Duration Range

Edit index.html:

<input type="range" id="durationSlider" min="5" max="300" step="5" value="60">

Adjust Recording Settings

Edit js/TrackVisualization.js in the startRecording() method:

const options = {
    mimeType: 'video/webm;codecs=av1',
    videoBitsPerSecond: 15000000  // 15 Mbps
};

Modify Marker Icons

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',
    // ...
});

Tips

Getting GPX Files

  1. Export from fitness apps (Strava, Garmin Connect, Komoot, etc.)
  2. Record with GPS tracking apps
  3. Create custom routes with GPX Studio

Performance

  • 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

Mobile Usage

  • 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

Troubleshooting

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 100dvh for 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

License

MIT

Contributing

Pull requests are welcome! For major changes, please open an issue first.

Credits

Author

David Evdoshchenko

Support

For issues and questions, please open a GitHub issue.

About

Animated GPX route visualizer with Leaflet.js. Upload GPS tracks, animate playback, and record cinematic route videos with customizable map styles and camera following.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages