How the Camera Dead Zone Prevents Jitter in Google Timeline Visualizer

The camera dead zone prevents jitter by creating a tolerant rectangular region around the viewport center where small marker movements are ignored, eliminating constant micro-adjustments that would cause shaky playback.

Google Timeline Visualizer renders animated journeys by moving a virtual camera that follows a travel marker across the map. Without stabilization, every tiny marker displacement would trigger a camera recenter, producing perceptible shake during playback. The project solves this through a camera dead zone—a dynamically scaled buffer zone implemented in web/src/camera.ts that suppresses insignificant movements while ensuring the marker remains visible.

What Causes Camera Jitter in Map Animations

Jitter arises when the camera repositions on every frame update. In a typical journey with frequent location samples, the marker advances in small increments. If the camera tracks these exactly, viewers perceive rapid, jerky motion rather than smooth traversal. The dead zone breaks this 1:1 coupling by introducing intentional lag—camera movement becomes event-driven rather than continuous.

How the Dead Zone Size Is Defined

The dead zone scales proportionally with viewport dimensions. This ensures jitter suppression remains effective regardless of zoom level or render size.

const CAMERA_DEAD_ZONE_HALF = 0.20;   // web/src/camera.ts#L73

This constant sets the dead zone to 20% of the viewport span in each direction, creating a 40% total width/height tolerance band centered on the current view.

Computing Dead Zone Extents Per Frame

For each animation frame, the actual dead zone boundaries are computed from the current viewport spans (spanX, spanY):

const deadHalfX = spanX * CAMERA_DEAD_ZONE_HALF;   // web/src/camera.ts#L27
const deadHalfY = spanY * CAMERA_DEAD_ZONE_HALF;   // web/src/camera.ts#L28

By deriving these values dynamically, the system adapts to any viewport size without configuration changes.

Marker Position Testing and Center Adjustment

The core jitter prevention logic compares the travel marker (sample.marker) against the computed dead zone. The camera center (centerX, centerY) only updates when the marker exits the tolerance region:

if (markerX < centerX - deadHalfX) centerX = markerX + deadHalfX;
else if (markerX > centerX + deadHalfX) centerX = markerX - deadHalfX;

if (sample.marker.y < centerY - deadHalfY) centerY = sample.marker.y + deadHalfY;
else if (sample.marker.y > centerY + deadHalfY) centerY = sample.marker.y - deadHalfY;
// web/src/camera.ts#L29-L33

This implementation has two key properties:

  • Threshold activation — Movements inside the dead zone produce zero camera response
  • Edge-seeking correction — When triggered, the camera shifts exactly enough to reposition the marker at the dead zone edge, not the center, minimizing subsequent adjustments

Vertical Center Clamping for Additional Smoothing

After potential dead zone adjustment, the vertical center undergoes boundary clamping:

centerY = clampCenterY(centerY, spanY);   // web/src/camera.ts#L33

This prevents the camera from displaying invalid map regions and adds a secondary smoothing layer to vertical motion.

Complete Camera Track Generation

The dead zone integrates into the broader buildCameraTrack pipeline that produces frame-ready camera positions:

// Example: building a camera track with dead-zone handling
import { buildCameraTrack } from './camera';
import { SQUARE_480 } from './types';

const journey = /* … construct CameraJourney … */;
const size = SQUARE_480;                     // 480 px square render size
const track = buildCameraTrack(journey, size, 'dynamic');

// The resulting `track.frames` contain centres that only move when the marker
// leaves the dead zone, yielding a jitter-free animation.

Each frame in the resulting CameraTrack contains precomputed center coordinates that respect the dead zone constraints, allowing the renderer to consume positions without recalculation.

Why This Approach Eliminates Jitter

The camera dead zone architecture prevents jitter through three mechanisms:

  1. Tolerance band filtering — Spatial quantization eliminates high-frequency marker noise below the 20% threshold
  2. Minimum-displacement updates — Camera movements are quantized to dead zone edge crossings, creating stepwise rather than continuous motion
  3. Viewport-relative scaling — The 20% ratio maintains consistent visual smoothing across all zoom levels and render dimensions

Summary

  • The camera dead zone in Google Timeline Visualizer is defined as 20% of viewport span on each axis (CAMERA_DEAD_ZONE_HALF = 0.20 in web/src/camera.ts)
  • Dead zone extents are recomputed per-frame in buildCameraTrack based on current spanX and spanY values
  • Marker positions trigger camera updates only when crossing dead zone boundaries, with corrections calculated to position the marker at the zone edge
  • Final vertical center values are clamped via clampCenterY for boundary safety and additional smoothing
  • The CameraTrack output provides dead-zone-respecting centers ready for frame-by-frame rendering

Frequently Asked Questions

How large is the camera dead zone in Google Timeline Visualizer?

The dead zone spans 40% of the viewport in each dimension—20% on each side of center. This is controlled by the CAMERA_DEAD_ZONE_HALF = 0.20 constant in web/src/camera.ts. The implementation multiplies this against current viewport spans (spanX, spanY) to derive actual pixel boundaries.

Does the dead zone size change with zoom level?

Yes. Because dead zone extents are computed as spanX * CAMERA_DEAD_ZONE_HALF and spanY * CAMERA_DEAD_ZONE_HALF, the absolute pixel size scales with viewport dimensions. This viewport-relative design ensures consistent jitter suppression regardless of map zoom or output resolution.

What happens when the marker exits the dead zone?

The camera center updates by the minimum displacement needed to reposition the marker at the dead zone edge—not the viewport center. For example, if the marker exceeds centerX + deadHalfX, the new center becomes markerX - deadHalfX. This edge-seeking behavior prevents oscillation around the threshold.

Where is the camera dead zone logic tested?

The dead zone behavior is validated in web/src/camera.test.ts, which exercises buildCameraTrack across various journey configurations. These tests ensure that camera frames correctly suppress minor marker deviations while responding appropriately to significant positional changes.

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 →