Skip to content

Customize the Map Transform Constrain ​

Control how and where the map camera can move by setting bounds, zoom limits, and using transformCameraUpdate to enforce custom constraints.

Set Max Bounds ​

Restrict panning so the camera cannot move outside a bounding box:

javascript
// At initialization
const map = new mapmetricsgl.Map({
  container: 'map',
  style: '<StyleFile_URL_with_Token>',
  maxBounds: [[-25, 34], [45, 72]], // [SW, NE]
});

// At runtime
map.setMaxBounds([[-25, 34], [45, 72]]);

// Remove constraint
map.setMaxBounds(null);

Limit Zoom Levels ​

javascript
// At initialization
const map = new mapmetricsgl.Map({
  minZoom: 3,
  maxZoom: 18,
  // ...
});

// At runtime
map.setMinZoom(3);
map.setMaxZoom(12);

// Remove limits
map.setMinZoom(null);
map.setMaxZoom(null);

Limit Pitch and Bearing ​

javascript
const map = new mapmetricsgl.Map({
  minPitch: 0,
  maxPitch: 60,  // default 60
  // ...
});

transformCameraUpdate — Custom Constraints ​

Use transformCameraUpdate to intercept and modify every camera update before it is applied:

javascript
const map = new mapmetricsgl.Map({
  // ...
  transformCameraUpdate: ({ center, zoom, pitch, bearing, elevation, padding }) => {
    // Example: keep latitude above the equator
    return {
      center: {
        lng: center.lng,
        lat: Math.max(0, center.lat), // clamp lat to >= 0
      },
      zoom,
      pitch,
      bearing,
    };
  }
});

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>#map { height: 500px; width: 100%; }</style>
  </head>
  <body>
    <div id="map"></div>
    <button id="lock">Lock to Europe</button>
    <button id="unlock">Unlock</button>
    <script>
      const europeBounds = [[-25, 34], [45, 72]];

      const map = new mapmetricsgl.Map({
        container: 'map',
        style: '<StyleFile_URL_with_Token>',
        center: [10, 50],
        zoom: 4,
        minZoom: 2,
        maxZoom: 18,
      });

      document.getElementById('lock').addEventListener('click', () => {
        map.setMaxBounds(europeBounds);
        map.fitBounds(europeBounds, { padding: 20 });
      });

      document.getElementById('unlock').addEventListener('click', () => {
        map.setMaxBounds(null);
      });
    </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 europeBounds = [[-25, 34], [45, 72]];

const CustomizeMapTransformConstrain = () => {
  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: [10, 50],
      zoom: 4,
      minZoom: 2,
    });
    return () => { map.current?.remove(); map.current = null; };
  }, []);

  const lock = () => {
    map.current?.setMaxBounds(europeBounds);
    map.current?.fitBounds(europeBounds, { padding: 20 });
  };
  const unlock = () => map.current?.setMaxBounds(null);

  return (
    <div>
      <div ref={mapContainer} style={{ height: '500px', width: '100%' }} />
      <div style={{ marginTop: 10, display: 'flex', gap: 8 }}>
        <button onClick={lock}>Lock to Europe</button>
        <button onClick={unlock}>Unlock</button>
      </div>
    </div>
  );
};

export default CustomizeMapTransformConstrain;

For more information, visit the MapMetrics GitHub repository.