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.