Change a layer's color with buttons
This example uses setPaintProperty to change the colors of different fill layers on a map using a classic style.
- The
waterandbuildinglayers use the Mapbox Streets v8 vector tileset from the Mapbox Light style (light-v11) as avectorsource.
Classic styles are no longer maintained
This example uses classic Mapbox styles (for example: MAPBOX_STREETS,SATELLITE, OUTDOORS, etc). These styles are no longer maintained and may not include the latest features or updates. Developers are encouraged to use the Mapbox Standard or Mapbox Satellite styles or creating custom styles using Mapbox Studio.
- The
trianglescustom layer, added withaddLayer, uses a custom tileset (examples.ckv9z0wgf5v7c27p7me2mf0l9-9wrve) as avectorsource.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Change a layer's color with buttons</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v3.17.0-beta.1/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v3.17.0-beta.1/mapbox-gl.js"></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<style>
.map-overlay {
font:
12px/20px 'Helvetica Neue',
Arial,
Helvetica,
sans-serif;
position: absolute;
width: 200px;
top: 0;
left: 0;
padding: 10px;
}
.map-overlay .map-overlay-inner {
background-color: #fff;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
border-radius: 3px;
padding: 10px;
margin-bottom: 10px;
}
.map-overlay-inner fieldset {
border: none;
padding: 0;
margin: 0 0 10px;
}
.map-overlay-inner fieldset:last-child {
margin: 0;
}
.map-overlay-inner select {
width: 100%;
}
.map-overlay-inner label {
display: block;
font-weight: bold;
margin: 0 0 5px;
}
.map-overlay-inner button {
display: inline-block;
width: 36px;
height: 20px;
border: none;
cursor: pointer;
}
.map-overlay-inner button:focus {
outline: none;
}
.map-overlay-inner button:hover {
box-shadow: inset 0 0 0 3px rgba(0, 0, 0, 0.1);
}
</style>
<div id="map"></div>
<div class="map-overlay top">
<div class="map-overlay-inner">
<fieldset>
<label>Select layer</label>
<select id="layer" name="layer">
<!-- Each value matches a layer ID. -->
<option value="water">Water</option>
<option value="building">Buildings</option>
<option value="triangles">Triangles</option>
</select>
</fieldset>
<fieldset>
<label>Choose a color</label>
<div id="swatches"></div>
</fieldset>
</div>
</div>
<script>
// TO MAKE THE MAP APPEAR YOU MUST
// ADD YOUR ACCESS TOKEN FROM
// https://account.mapbox.com
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
const map = new mapboxgl.Map({
container: 'map',
// Choose from Mapbox's core styles, or make your own style with Mapbox Studio
style: 'mapbox://styles/mapbox/light-v11', // style URL for Mapbox Light
center: [12.338, 45.4385],
zoom: 18
});
map.on('load', () => {
// Add a custom layer that uses
// a vector tileset source.
map.addLayer({
id: 'triangles',
source: {
type: 'vector',
url: 'mapbox://examples.ckv9z0wgf5v7c27p7me2mf0l9-9wrve' // custom tileset
},
'source-layer': 'triangles',
type: 'fill'
});
});
const swatches = document.getElementById('swatches');
const layer = document.getElementById('layer');
const colors = [
'#ffffcc',
'#a1dab4',
'#41b6c4',
'#2c7fb8',
'#253494',
'#fed976',
'#feb24c',
'#fd8d3c',
'#f03b20',
'#bd0026'
];
for (const color of colors) {
const swatch = document.createElement('button');
swatch.style.backgroundColor = color;
swatch.addEventListener('click', () => {
map.setPaintProperty(layer.value, 'fill-color', color);
});
swatches.appendChild(swatch);
}
</script>
</body>
</html>
This code snippet will not work as expected until you replace
YOUR_MAPBOX_ACCESS_TOKEN with an access token from your Mapbox account.import React, { useEffect, useRef, useState } from 'react';
import mapboxgl from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
const MapboxExample = () => {
const mapContainerRef = useRef();
const mapRef = useRef();
const [layer, setLayer] = useState('water');
const colors = [
'#ffffcc',
'#a1dab4',
'#41b6c4',
'#2c7fb8',
'#253494',
'#fed976',
'#feb24c',
'#fd8d3c',
'#f03b20',
'#bd0026'
];
const handleClick = (color) => {
mapRef.current.setPaintProperty(layer, 'fill-color', color);
};
useEffect(() => {
// TO MAKE THE MAP APPEAR YOU MUST
// ADD YOUR ACCESS TOKEN FROM
// https://account.mapbox.com
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';
mapRef.current = new mapboxgl.Map({
container: mapContainerRef.current,
style: 'mapbox://styles/mapbox/light-v11', // style URL for Mapbox Light
config: {
basemap: {
theme: 'monochrome'
}
},
center: [12.338, 45.4385],
zoom: 18
});
mapRef.current.on('load', () => {
mapRef.current.addLayer({
id: 'triangles',
source: {
type: 'vector',
url: 'mapbox://examples.ckv9z0wgf5v7c27p7me2mf0l9-9wrve'
},
'source-layer': 'triangles',
type: 'fill'
});
});
}, []);
const labelStyles = {
display: 'block',
fontWeight: 'bold',
margin: '0 0 5px'
};
const handleLayerChange = (e) => {
setLayer(e.target.value);
};
return (
<div style={{ height: '100%', position: 'relative' }}>
<div id="map" ref={mapContainerRef} style={{ height: '100%' }}></div>
<div
style={{
font: `12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif`,
position: 'absolute',
width: 220,
top: 0,
left: 0,
padding: '10px'
}}
>
<div
style={{
backgroundColor: '#fff',
boxShadow: '0 1px 2px rgba(0, 0, 0, 0.1)',
borderRadius: '3px',
padding: '10px',
marginBottom: '10px'
}}
>
<fieldset
style={{
border: 'none',
padding: 0,
margin: '0 0 10px'
}}
>
<label style={labelStyles}>
Select layer
<select
style={{ width: '100%' }}
id="layer"
name="layer"
onChange={handleLayerChange}
>
<option value="water">Water</option>
<option value="building">Buildings</option>
<option value="triangles">Triangles</option>
</select>
</label>
</fieldset>
<fieldset>
<label style={labelStyles}>
Choose a color
<div id="swatches">
{colors.map((color, i) => (
<button
key={i}
style={{
backgroundColor: color,
display: 'inline-block',
width: '36px',
height: '20px',
border: 'none',
cursor: 'pointer'
}}
onClick={() => handleClick(color)}
></button>
))}
</div>
</label>
</fieldset>
</div>
</div>
</div>
);
};
export default MapboxExample;
This code snippet will not work as expected until you replace
YOUR_MAPBOX_ACCESS_TOKEN with an access token from your Mapbox account.Was this example helpful?