В OpenLayers управление масштабом карты реализуется через контрол
Zoom, входящий в стандартный набор ol.control. Он
обеспечивает базовую навигацию по уровням детализации карты и тесно
связан с системой разрешений (resolution) и зум-уровней (zoom levels),
которые лежат в основе рендеринга тайлов и векторных слоёв.
Контрол масштабирования представлен классом
ol.control.Zoom. Его задача — изменять текущий уровень зума
карты, увеличивая или уменьшая значение view.zoom. При этом
сам контрол не работает напрямую с пикселями или тайлами — он
взаимодействует через объект ol.View, который управляет
состоянием отображения.
Основные элементы:
zoom in)zoom out)ViewminZoom и maxZoomКонтрол является частью системы ol.control.Control, что
позволяет ему быть расширяемым и заменяемым.
По умолчанию контрол масштабирования уже включён в стандартный набор управления картой. Однако его можно явно конфигурировать или переопределять.
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import Zoom from 'ol/control/Zoom.js';
import TileLayer from 'ol/layer/Tile.js';
import OSM from 'ol/source/OSM.js';
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new OSM()
})
],
view: new View({
center: [0, 0],
zoom: 2
}),
controls: [
new Zoom()
]
});
В этом случае создаётся минимальная конфигурация управления, содержащая только кнопки масштабирования.
Конструктор ol.control.Zoom принимает объект
настроек:
className — CSS-класс контейнераzoomInLabel — содержимое кнопки увеличения
масштабаzoomOutLabel — содержимое кнопки уменьшения
масштабаzoomInTipLabel — текст подсказкиzoomOutTipLabel — текст подсказкиduration — длительность анимации изменения
масштабаПример настройки:
new Zoom({
duration: 250,
zoomInLabel: '+',
zoomOutLabel: '−',
zoomInTipLabel: 'Увеличить масштаб',
zoomOutTipLabel: 'Уменьшить масштаб'
});
Zoom-контрол изменяет значение zoom внутри
View. Ограничения задаются через:
minZoommaxZoomconstrainResolutionnew View({
center: [0, 0],
zoom: 5,
minZoom: 3,
maxZoom: 10
});
При достижении границ контрол автоматически блокирует дальнейшее изменение масштаба в соответствующем направлении.
Если включён constrainResolution: true, изменения
происходят дискретно, строго по доступным уровням разрешения тайловой
сетки.
Внутренне OpenLayers работает не с zoom как с числом, а с
resolution. Каждому zoom соответствует определённый
масштаб:
resolution = initialResolution / 2^zoom
При изменении масштаба через Zoom-контрол происходит пересчёт resolution, после чего обновляются слои.
Это важно для:
Контрол имеет стандартную HTML-структуру:
<div class="ol-zoom ol-unselectable ol-control">
<button class="ol-zoom-in">+</button>
<button class="ol-zoom-out">−</button>
</div>
Изменение внешнего вида выполняется через CSS:
.ol-zoom {
top: 10px;
left: 10px;
background: rgba(30, 30, 30, 0.8);
border-radius: 6px;
}
.ol-zoom button {
color: white;
background: transparent;
width: 32px;
height: 32px;
}
.ol-zoom button:hover {
background: rgba(255, 255, 255, 0.2);
}
Контрол полностью отделён от логики карты, что позволяет свободно менять визуальную часть без вмешательства в JavaScript.
Как и другие элементы управления, Zoom размещается через
ol.control.defaults или через CSS-классы
позиционирования:
import defaults from 'ol/control/defaults.js';
const map = new Map({
controls: defaults({
zoom: true
})
});
CSS-классы:
ol-top-leftol-top-rightol-bottom-leftol-bottom-rightПример перемещения:
.ol-zoom {
top: auto;
bottom: 20px;
left: 20px;
}
В некоторых интерфейсах кнопки масштабирования заменяются жестами или внешними компонентами. В этом случае стандартный контрол отключается:
import defaults from 'ol/control/defaults.js';
const map = new Map({
controls: defaults({
zoom: false
})
});
Альтернативой выступают:
view.setZoom()Zoom-контрол является лишь интерфейсом. Само изменение масштаба
доступно напрямую через View:
const view = map.getView();
view.setZoom(8);
view.setZoom(view.getZoom() + 1);
view.animate({
zoom: 10,
duration: 300
});
Это позволяет синхронизировать внешние UI-компоненты с картой.
View генерирует события при изменении zoom:
map.getView().on('change:zoom', () => {
console.log('Текущий zoom:', map.getView().getZoom());
});
Это используется для:
Zoom-контрол работает в рамках нескольких ограничений:
maxResolution и
minResolutionПри использовании нестандартных проекций поведение zoom может отличаться, так как resolution вычисляется относительно координатной системы.
При необходимости полного контроля UI создаются кастомные реализации:
import Control from 'ol/control/Control.js';
class CustomZoom extends Control {
constructor() {
const element = document.createElement('div');
const zoomIn = document.createElement('button');
zoomIn.textContent = '+';
const zoomOut = document.createElement('button');
zoomOut.textContent = '−';
element.appendChild(zoomIn);
element.appendChild(zoomOut);
super({ element });
zoomIn.addEventListener('click', () => {
const view = this.getMap().getView();
view.setZoom(view.getZoom() + 1);
});
zoomOut.addEventListener('click', () => {
const view = this.getMap().getView();
view.setZoom(view.getZoom() - 1);
});
}
}
Такой подход используется при интеграции карты в сложные интерфейсы, где стандартный UI OpenLayers не подходит.
Zoom-контрол часто дублирует жесты:
На мобильных устройствах кнопки могут быть скрыты и заменены жестовым
управлением через ol/interaction/PinchZoom.
Параметр duration определяет плавность перехода между
уровнями zoom. При больших значениях создаётся эффект инерции:
Анимация выполняется внутри View.animate, что
обеспечивает синхронизацию с рендерингом слоёв.
Zoom часто используется совместно с:
Пример синхронизации со слайдером:
const slider = document.getElementById('zoomSlider');
slider.addEventListener('input', (e) => {
map.getView().setZoom(Number(e.target.value));
});
map.getView().on('change:zoom', () => {
slider.value = map.getView().getZoom();
});
Такой подход позволяет строить альтернативные интерфейсы управления картой без использования стандартного контрола.