Skip to content

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.