Skip to content

Offset the Vanishing Point Using Padding

Use camera padding to shift the effective center of the map — so that a point of interest stays visible even when a sidebar or panel overlaps part of the map.

Locations


What is Padding?

Padding shifts the camera's effective center so that a point of interest appears in the unobscured area of the map. This is ideal when part of the map is covered by a UI element like a sidebar, bottom sheet, or info panel.

javascript
// The map visually shifts so the center appears
// in the area NOT covered by the 300px left panel
map.flyTo({
  center: [lng, lat],
  zoom: 12,
  padding: {
    left: 300,   // left panel width
    top: 0,
    right: 0,
    bottom: 0,
  }
});

Set Padding at Initialization

javascript
const map = new mapmetricsgl.Map({
  container: 'map',
  style: '<StyleFile_URL_with_Token>',
  center: [0, 20],
  zoom: 4,
  padding: { left: 320, top: 0, right: 0, bottom: 0 }
});

setPadding at Runtime

javascript
// Animate padding change (e.g., when a panel opens/closes)
map.easeTo({
  padding: { left: 320, top: 0, right: 0, bottom: 0 },
  duration: 300,
});

// Or set it instantly
map.setPadding({ left: 0 });

fitBounds with Padding

javascript
map.fitBounds([[-180, -85], [180, 85]], {
  padding: { left: 300, top: 40, right: 40, bottom: 40 }
});

Complete Example

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <link href="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.css" rel="stylesheet" />
    <script src="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.js"></script>
    <style>
      body { margin: 0; }
      #container { position: relative; width: 100%; height: 100vh; }
      #map { width: 100%; height: 100%; }
      #sidebar {
        position: absolute; top: 0; left: 0;
        width: 300px; height: 100%;
        background: rgba(255,255,255,0.9);
        padding: 20px; box-sizing: border-box; z-index: 1;
      }
    </style>
  </head>
  <body>
    <div id="container">
      <div id="map"></div>
      <div id="sidebar">
        <h3>Cities</h3>
        <button onclick="go(-74, 40.7)">New York</button>
        <button onclick="go(2.35, 48.85)">Paris</button>
        <button onclick="go(139.7, 35.7)">Tokyo</button>
      </div>
    </div>
    <script>
      const map = new mapmetricsgl.Map({
        container: 'map',
        style: '<StyleFile_URL_with_Token>',
        center: [0, 20],
        zoom: 2,
        padding: { left: 300 }
      });

      function go(lng, lat) {
        map.flyTo({
          center: [lng, lat],
          zoom: 11,
          padding: { left: 300, top: 0, right: 0, bottom: 0 }
        });
      }
    </script>
  </body>
</html>
jsx
import React, { useEffect, useRef } from 'react';
import mapmetricsgl from '@mapmetrics/mapmetrics-gl';
import '@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css';

const cities = [
  { name: 'New York', center: [-74.0, 40.7] },
  { name: 'Paris', center: [2.35, 48.85] },
  { name: 'Tokyo', center: [139.7, 35.7] },
];

const PANEL_WIDTH = 300;

const OffsetVanishingPoint = () => {
  const mapContainer = useRef(null);
  const map = useRef(null);

  useEffect(() => {
    if (map.current) return;
    map.current = new mapmetricsgl.Map({
      container: mapContainer.current,
      style: '<StyleFile_URL_with_Token>',
      center: [0, 20],
      zoom: 2,
      padding: { left: PANEL_WIDTH }
    });
    return () => { map.current?.remove(); map.current = null; };
  }, []);

  const flyTo = (center) => {
    map.current?.flyTo({
      center,
      zoom: 11,
      padding: { left: PANEL_WIDTH, top: 0, right: 0, bottom: 0 }
    });
  };

  return (
    <div style={{ position: 'relative', height: '500px' }}>
      <div ref={mapContainer} style={{ width: '100%', height: '100%' }} />
      <div style={{
        position: 'absolute', top: 0, left: 0,
        width: PANEL_WIDTH, height: '100%',
        background: 'rgba(255,255,255,0.9)',
        padding: 20, boxSizing: 'border-box', zIndex: 1
      }}>
        <h3 style={{ marginTop: 0 }}>Cities</h3>
        {cities.map(c => (
          <button key={c.name} onClick={() => flyTo(c.center)}
            style={{ display: 'block', width: '100%', margin: '0 0 8px', padding: '8px', cursor: 'pointer' }}>
            {c.name}
          </button>
        ))}
      </div>
    </div>
  );
};

export default OffsetVanishingPoint;

For more information, visit the MapMetrics GitHub repository.