Google Timeline Visualizer Camera Tracking Modes: Fixed, Steady, and Dynamic Explained

Google Timeline Visualizer offers three camera tracking modes—Fixed zoom, Steady following, and Dynamic following—each controlling how the virtual camera follows your journey with different zoom behaviors and responsiveness levels.

The camera tracking modes in Google Timeline Visualizer give users fine-grained control over how their location history is presented. These modes are defined in web/src/types.ts and implemented in web/src/camera.ts, then surfaced through a dropdown UI in web/index.html. This article breaks down each mode's technical implementation and when to use it.


Camera Movement Type Definitions

The foundation of all camera tracking modes is the CameraMovement type in web/src/types.ts:

// web/src/types.ts (line 32)
export type CameraMovement = 'fixed' | 'steady' | 'dynamic';

This type is used throughout the codebase to ensure type safety when selecting or switching modes.


The Three Camera Tracking Modes

Each mode is implemented as a movement profile in the MOVEMENT_PROFILES object within web/src/camera.ts. The profiles configure zoom aggression, context window size, and leg-aware behavior.

Fixed Zoom Mode

Fixed zoom maintains a constant zoom level throughout the entire animation.

The zoom level is computed once from the FIXED_ZOOM_PERCENTILE of raw samples, then locked. The viewport pans to keep the journey centered, but the scale never changes regardless of speed or direction changes.

// web/src/camera.ts (lines 36-47)
fixed: {
  // Constant zoom based on percentile of all samples
  contextFraction: 4,        // Large context window
  zoomOutAlpha: 1,           // Immediate zoom out (but zoom is fixed)
  zoomInAlpha: 1,            // Immediate zoom in (but zoom is fixed)
  legAware: false,           // No special handling for transport legs
  // Zoom computed once from FIXED_ZOOM_PERCENTILE
}

Best for: Getting a consistent overview of your entire journey without distracting zoom changes.

Steady Following Mode

Steady following provides a smooth, stable camera that gently adapts to the journey's scale.

This mode uses a full context window (contextFraction: 1) and applies heavy damping to zoom changes. The zoomOutAlpha of 0.14 and zoomInAlpha of 0.035 create a deliberate, unhurried feel.

// web/src/camera.ts (lines 48-58)
steady: {
  contextFraction: 1,        // Full journey context
  zoomOutAlpha: 0.14,        // Slow zoom out
  zoomInAlpha: 0.035,        // Very slow zoom in
  legAware: false,           // Uniform treatment of all segments
  // Smooth, cinematic pacing
}

Best for: Relaxed, movie-like playback where you want to appreciate the overall flow without jarring transitions.

Dynamic Following Mode

Dynamic following reacts aggressively to rapid changes in your journey.

This mode uses a tight context window (contextFraction: 0.10) and enables leg-aware behavior, which treats different transport types (flights, drives, walks) distinctly. Zoom changes are roughly twice as fast as Steady mode.

// web/src/camera.ts (lines 59-69)
dynamic: {
  contextFraction: 0.10,     // Tight local context
  zoomOutAlpha: 0.24,        // Fast zoom out
  zoomInAlpha: 0.06,         // Moderate zoom in
  legAware: true,            // Different behavior per transport type
  // Responsive to speed and direction changes
}

Best for: Complex, multi-modal journeys where you want the camera to emphasize transitions between flights, drives, and walking segments.

Mode Context Fraction Zoom Speed Leg Aware Feel
Fixed 4× (large) N/A No Static, map-like
Steady 1× (full) Slow No Cinematic, relaxed
Dynamic 0.1× (tight) Fast Yes Responsive, energetic

How Camera Tracking Modes Are Wired Into the Application

The camera tracking mode selection flows through four key files:

  1. UI selection — web/index.html provides a <select id="camera-movement"> element with options fixed, steady, and dynamic.

  2. Value reading — web/src/main.ts captures the selection: cameraMovementSelect.value as CameraMovement.

  3. Track building — web/src/renderer.ts receives the mode in buildCameraTrack(journey, size, cameraMovement).

  4. Profile application — Inside buildCameraTrack, the corresponding MOVEMENT_PROFILES[cameraMovement] configures how viewport frames are computed and smoothed.

This architecture lets users swap camera tracking modes at runtime without reprocessing the underlying journey data.


Programmatically Switching Camera Tracking Modes

You can preview different camera tracking modes programmatically using the buildCameraTrack function from web/src/renderer.ts:

import { buildCameraTrack } from './renderer';
import type { CameraMovement } from './types';

// Preview a specific camera mode
function previewWithMode(mode: CameraMovement) {
  const track = buildCameraTrack(journey, size, mode);
  const viewport = cameraViewportAt(track, 0);
  console.log(`Mode: ${mode}`, viewport);
}

// Compare all three modes
previewWithMode('fixed');    // Constant zoom
previewWithMode('steady');   // Smooth, full-context following
previewWithMode('dynamic');  // Tight, responsive following

The returned track contains precomputed viewport frames that obey the selected movement profile's constraints.


Summary

  • Fixed zoom locks the zoom level using FIXED_ZOOM_PERCENTILE, panning only to center the path—ideal for consistent overviews.
  • Steady following uses contextFraction: 1 with heavy damping (zoomOutAlpha: 0.14, zoomInAlpha: 0.035) for smooth, cinematic playback.
  • Dynamic following employs contextFraction: 0.10, leg-aware behavior, and faster zoom rates for responsive, detail-focused presentation.
  • Mode selection is type-safe via CameraMovement in web/src/types.ts and configurable at runtime through MOVEMENT_PROFILES in web/src/camera.ts.

Frequently Asked Questions

What is the default camera tracking mode in Google Timeline Visualizer?

The default mode is Steady following. In web/index.html, the <option value="steady"> element has the selected attribute, and the UI labels it "Steady following" (or localized equivalent via data-i18n="cameraSteady").

How does Dynamic following handle different transport types differently?

Dynamic following enables leg-aware behavior through legAware: true in its profile. When enabled, the camera logic in buildCameraTrack treats transport-type legs—such as flights versus ground travel—differently, potentially zooming out further for longer flight segments or adjusting framing based on expected speed.

Can I implement a custom camera tracking mode?

Yes, though it requires modifying the source. You would: (1) extend CameraMovement in web/src/types.ts with a new literal type, (2) add a corresponding profile to MOVEMENT_PROFILES in web/src/camera.ts with your desired contextFraction, zoomOutAlpha, zoomInAlpha, and legAware values, and (3) add the option to the <select> in web/index.html.

Why does Fixed zoom still have contextFraction and alpha values in its profile?

The contextFraction, zoomOutAlpha, and zoomInAlpha fields exist for API consistency across all profiles, but Fixed zoom ignores them during playback. The zoom level is computed once from FIXED_ZOOM_PERCENTILE and never updated, making these values inert for that mode.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →