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.