メインコンテンツまでスキップ

Control symbol scaling with setScaleFactor

This example demonstrates how to use setScaleFactor to dynamically scale symbol layers on the map. The example displays rally race waypoints with icons and text labels.

The control panel allows you to:

  • Scale Factor: Adjusts the global scale factor for all symbol layers using map.setScaleFactor().
  • Icon Size Scale Range: Sets the minimum and maximum scaling limits for icons using the icon-size-scale-range layout property.
  • Text Size Scale Range: Sets the minimum and maximum scaling limits for text using the text-size-scale-range layout property.

In the example, you can experiment with different scale factor values and scale ranges to see how they affect the appearance of the symbols on the map. "Icon Size Scale Range" and "Text Size Scale Range" allow you to control the minimum and maximum scaling limits for icons and text of the custom layer, respectively, providing flexibility in how symbols are displayed at different scale levels. For example, if you set icon-size-scale-range to [1, 1], the icons will not scale regardless of the scale factor value.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Control symbol scaling with setScaleFactor</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v3.20.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v3.20.0/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: 220px;
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 0;
}

.map-overlay-inner label {
display: block;
font-weight: bold;
margin-bottom: 5px;
}

.map-overlay-inner input[type='range'] {
width: 100%;
cursor: ew-resize;
}

.map-overlay-inner .range-value {
font-size: 11px;
color: #666;
margin-top: 2px;
}

.map-overlay-inner .dual-range {
display: flex;
gap: 10px;
}

.map-overlay-inner .dual-range > div {
flex: 1;
}

.map-overlay-inner .dual-range label {
font-weight: normal;
font-size: 11px;
}
</style>

<div id="map"></div>

<div class="map-overlay top">
<div class="map-overlay-inner">
<fieldset>
<label>Scale Factor: <span id="scale-factor-value">1.0</span></label>
<input id="scale-factor" type="range" min="0.5" max="3" step="0.1" value="1">
</fieldset>
<fieldset>
<label>Icon Size Scale Range</label>
<div class="dual-range">
<div>
<label>Min: <span id="icon-min-value">0.8</span></label>
<input id="icon-size-min" type="range" min="0.1" max="5" step="0.1" value="0.8">
</div>
<div>
<label>Max: <span id="icon-max-value">2.0</span></label>
<input id="icon-size-max" type="range" min="0.1" max="5" step="0.1" value="2">
</div>
</div>
</fieldset>
<fieldset>
<label>Text Size Scale Range</label>
<div class="dual-range">
<div>
<label>Min: <span id="text-min-value">0.8</span></label>
<input id="text-size-min" type="range" min="0.1" max="5" step="0.1" value="0.8">
</div>
<div>
<label>Max: <span id="text-max-value">2.0</span></label>
<input id="text-size-max" type="range" min="0.1" max="5" step="0.1" value="2">
</div>
</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';
// Rally Finland waypoints - a fictional stage route around Jyväskylä
const rallyWaypoints = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: { name: 'Start', order: 1 },
geometry: { type: 'Point', coordinates: [25.7473, 62.2426] }
},
{
type: 'Feature',
properties: { name: '01', order: 2 },
geometry: { type: 'Point', coordinates: [25.7821, 62.2589] }
},
{
type: 'Feature',
properties: { name: '02', order: 3 },
geometry: { type: 'Point', coordinates: [25.8234, 62.2712] }
},
{
type: 'Feature',
properties: { name: '03', order: 4 },
geometry: { type: 'Point', coordinates: [25.8612, 62.2534] }
},
{
type: 'Feature',
properties: { name: '04', order: 5 },
geometry: { type: 'Point', coordinates: [25.8923, 62.2321] }
},
{
type: 'Feature',
properties: { name: 'Finish', order: 6 },
geometry: { type: 'Point', coordinates: [25.9245, 62.2198] }
}
]
};

const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/gl-js-team/cmleyrmcy002f01qthcccbolv',
center: [25.83, 62.245],
zoom: 11.5
});

map.on('style.load', () => {
map.addSource('rally-waypoints', {
type: 'geojson',
data: rallyWaypoints
});

map.addLayer({
id: 'rally-waypoints',
type: 'symbol',
source: 'rally-waypoints',
layout: {
'icon-image': 'bicycle',
'icon-size': 1.5,
'icon-size-scale-range': [0.8, 2],
'text-field': ['get', 'name'],
'text-font': ['DIN Pro Medium', 'Arial Unicode MS Regular'],
'text-size': 14,
'text-size-scale-range': [0.8, 2],
'text-offset': [0, 1.2],
'text-anchor': 'top',
'icon-allow-overlap': true,
'text-allow-overlap': true
},
paint: {
'icon-color': '#e74c3c',
'text-color': '#2c3e50',
'text-halo-color': '#ffffff',
'text-halo-width': 1
}
});
});

// Scale Factor slider
const scaleFactorSlider = document.getElementById('scale-factor');
const scaleFactorValue = document.getElementById('scale-factor-value');

scaleFactorSlider.addEventListener('input', (e) => {
const value = parseFloat(e.target.value);
scaleFactorValue.textContent = value.toFixed(1);
map.setScaleFactor(value);
});

// Icon Size Scale Range sliders
const iconMinSlider = document.getElementById('icon-size-min');
const iconMaxSlider = document.getElementById('icon-size-max');
const iconMinValue = document.getElementById('icon-min-value');
const iconMaxValue = document.getElementById('icon-max-value');

function updateIconSizeScaleRange() {
const min = parseFloat(iconMinSlider.value);
const max = parseFloat(iconMaxSlider.value);
iconMinValue.textContent = min.toFixed(1);
iconMaxValue.textContent = max.toFixed(1);
map.setLayoutProperty('rally-waypoints', 'icon-size-scale-range', [
min,
max
]);
}

iconMinSlider.addEventListener('input', updateIconSizeScaleRange);
iconMaxSlider.addEventListener('input', updateIconSizeScaleRange);

// Text Size Scale Range sliders
const textMinSlider = document.getElementById('text-size-min');
const textMaxSlider = document.getElementById('text-size-max');
const textMinValue = document.getElementById('text-min-value');
const textMaxValue = document.getElementById('text-max-value');

function updateTextSizeScaleRange() {
const min = parseFloat(textMinSlider.value);
const max = parseFloat(textMaxSlider.value);
textMinValue.textContent = min.toFixed(1);
textMaxValue.textContent = max.toFixed(1);
map.setLayoutProperty('rally-waypoints', 'text-size-scale-range', [
min,
max
]);
}

textMinSlider.addEventListener('input', updateTextSizeScaleRange);
textMaxSlider.addEventListener('input', updateTextSizeScaleRange);
</script>

</body>
</html>
このコードスニペットは、YOUR_MAPBOX_ACCESS_TOKENあなたのMapboxアカウントのアクセストークンに置き換えるまで、期待通りに動作しません。
このexampleは役に立ちましたか?