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:
-
UI selection —
web/index.htmlprovides a<select id="camera-movement">element with optionsfixed,steady, anddynamic. -
Value reading —
web/src/main.tscaptures the selection:cameraMovementSelect.value as CameraMovement. -
Track building —
web/src/renderer.tsreceives the mode inbuildCameraTrack(journey, size, cameraMovement). -
Profile application — Inside
buildCameraTrack, the correspondingMOVEMENT_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: 1with 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
CameraMovementinweb/src/types.tsand configurable at runtime throughMOVEMENT_PROFILESinweb/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →