Skip to content

Both copy text to your clipboard — Build with AI copies a setup prompt to paste into Claude Code, Cursor, Codex or Copilot; Copy page as Markdown copies this page to paste into a chat. How it works

Change Building Color Based on Zoom Level

Use the interpolate expression with zoom to change 3D building colors as the user zooms in and out.

Zoom in to see building colors transition from grey → blue → gold.

Zoom-Based Color with interpolate

Use the interpolate expression with ['zoom'] as the input to smoothly transition colors between zoom levels:

javascript
// Add your building polygons as a GeoJSON source
map.addSource('buildings', {
  type: 'geojson',
  data: {
    type: 'FeatureCollection',
    features: [
      { type: 'Feature', properties: { height: 80 }, geometry: { type: 'Polygon', coordinates: [[[lng1,lat1],[lng2,lat1],[lng2,lat2],[lng1,lat2],[lng1,lat1]]] } },
      // ... more building polygons
    ]
  }
});

map.addLayer({
  id: 'buildings-3d',
  type: 'fill-extrusion',
  source: 'buildings',
  paint: {
    'fill-extrusion-height': ['get', 'height'],
    'fill-extrusion-base': 0,
    'fill-extrusion-opacity': 0.85,

    // Color changes based on zoom
    'fill-extrusion-color': [
      'interpolate',
      ['linear'],
      ['zoom'],
      13, '#94a3b8',  // grey at zoom 13
      15, '#3b82f6',  // blue at zoom 15
      17, '#f59e0b',  // gold at zoom 17+
    ],
  }
});

Step-Based Color (Discrete Jumps)

Use step for discrete color jumps instead of smooth transitions:

javascript
'fill-extrusion-color': [
  'step',
  ['zoom'],
  '#94a3b8',  // default (zoom < 14)
  14, '#3b82f6', // zoom >= 14 → blue
  16, '#f59e0b', // zoom >= 16 → gold
  18, '#ef4444', // zoom >= 18 → red
]

Update Color at Runtime

javascript
map.setPaintProperty('buildings-3d', 'fill-extrusion-color', [
  'interpolate', ['linear'], ['zoom'],
  13, '#e2e8f0',
  16, '#22c55e',
]);

Also Apply to Height and Opacity

javascript
paint: {
  // Height from data
  'fill-extrusion-height': ['get', 'height'],
  'fill-extrusion-base': ['get', 'min_height'],

  // Fade in as zoom increases
  'fill-extrusion-opacity': [
    'interpolate', ['linear'], ['zoom'],
    13, 0,    // invisible at zoom 13
    14, 0.85  // fully visible at zoom 14
  ],

  // Color by zoom
  'fill-extrusion-color': [
    'interpolate', ['linear'], ['zoom'],
    14, '#94a3b8',
    17, '#3b82f6',
  ],
}

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>
    <script>
      const map = new mapmetricsgl.Map({
        container: 'map',
        style: '<StyleFile_URL_with_Token>',
        center: [2.3522, 48.8566],
        zoom: 14,
        pitch: 45,
        bearing: -17
      });

      const geojsonBuildings = {
        type: 'FeatureCollection',
        features: [
          { type: 'Feature', properties: { height: 80 }, geometry: { type: 'Polygon', coordinates: [[[2.348,48.858],[2.350,48.858],[2.350,48.860],[2.348,48.860],[2.348,48.858]]] } },
          { type: 'Feature', properties: { height: 120 }, geometry: { type: 'Polygon', coordinates: [[[2.351,48.857],[2.353,48.857],[2.353,48.860],[2.351,48.860],[2.351,48.857]]] } },
          { type: 'Feature', properties: { height: 200 }, geometry: { type: 'Polygon', coordinates: [[[2.344,48.856],[2.347,48.856],[2.347,48.859],[2.344,48.859],[2.344,48.856]]] } },
          { type: 'Feature', properties: { height: 50 }, geometry: { type: 'Polygon', coordinates: [[[2.354,48.858],[2.356,48.858],[2.356,48.859],[2.354,48.859],[2.354,48.858]]] } },
        ]
      };

      map.on('load', () => {
        map.addSource('buildings', { type: 'geojson', data: geojsonBuildings });
        map.addLayer({
          id: 'buildings-3d',
          type: 'fill-extrusion',
          source: 'buildings',
          paint: {
            'fill-extrusion-height': ['get', 'height'],
            'fill-extrusion-base': 0,
            'fill-extrusion-opacity': 0.85,
            'fill-extrusion-color': [
              'interpolate', ['linear'], ['zoom'],
              13, '#94a3b8',
              15, '#3b82f6',
              17, '#f59e0b',
            ],
          }
        });
      });
    </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 BuildingColorZoom = () => {
  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: [2.3522, 48.8566],
      zoom: 14,
      pitch: 45,
      bearing: -17
    });

    map.current.on('load', () => {
      const geojsonBuildings = {
        type: 'FeatureCollection',
        features: [
          { type: 'Feature', properties: { height: 80 }, geometry: { type: 'Polygon', coordinates: [[[2.348,48.858],[2.350,48.858],[2.350,48.860],[2.348,48.860],[2.348,48.858]]] } },
          { type: 'Feature', properties: { height: 120 }, geometry: { type: 'Polygon', coordinates: [[[2.351,48.857],[2.353,48.857],[2.353,48.860],[2.351,48.860],[2.351,48.857]]] } },
          { type: 'Feature', properties: { height: 200 }, geometry: { type: 'Polygon', coordinates: [[[2.344,48.856],[2.347,48.856],[2.347,48.859],[2.344,48.859],[2.344,48.856]]] } },
          { type: 'Feature', properties: { height: 50 }, geometry: { type: 'Polygon', coordinates: [[[2.354,48.858],[2.356,48.858],[2.356,48.859],[2.354,48.859],[2.354,48.858]]] } },
        ]
      };
      map.current.addSource('buildings', { type: 'geojson', data: geojsonBuildings });
      map.current.addLayer({
        id: 'buildings-3d',
        type: 'fill-extrusion',
        source: 'buildings',
        paint: {
          'fill-extrusion-height': ['get', 'height'],
          'fill-extrusion-base': 0,
          'fill-extrusion-opacity': 0.85,
          'fill-extrusion-color': [
            'interpolate', ['linear'], ['zoom'],
            13, '#94a3b8',
            15, '#3b82f6',
            17, '#f59e0b',
          ],
        }
      });
    });

    return () => { map.current?.remove(); map.current = null; };
  }, []);

  return <div ref={mapContainer} style={{ height: '500px', width: '100%' }} />;
};

export default BuildingColorZoom;

For more information, visit the MapMetrics GitHub repository.