Поворот (rotation) в OpenLayers относится к базовым трансформациям
вида карты и объектов, позволяя изменять ориентацию отображаемой сцены
вокруг заданной точки. Внутренне библиотека оперирует углами в радианах,
а анимация вращения реализуется через механизм изменения состояния
View во времени.
Ключевым объектом для управления вращением является
ol/View, где параметр rotation определяет
текущий угол поворота карты.
В OpenLayers вращение карты задаётся значением угла в радианах:
Основной метод установки:
view.setRotation(angle);
Также значение можно получить:
const current = view.getRotation();
Однако статическая установка не даёт эффекта анимации — она просто
мгновенно меняет ориентацию. Для плавного вращения используется
встроенный механизм анимаций View.animate.
Метод animate у ol/View позволяет
интерполировать значение rotation во времени.
view.animate({
rotation: Math.PI,
duration: 1000
});
В данном случае карта совершит поворот на 180 градусов за 1 секунду.
Основные параметры объекта анимации:
rotation — целевой угол в радианахduration — длительность анимации в миллисекундахeasing — функция сглаживанияПример с функцией плавности:
import { easeIn, easeOut } from 'ol/easing';
view.animate({
rotation: Math.PI * 2,
duration: 1500,
easing: easeIn
});
При анимации OpenLayers не просто заменяет угол, а интерполирует его значение между текущим и целевым состоянием.
Если обозначить:
r0 — начальный уголr1 — конечный уголt — прогресс от 0 до 1то текущее значение вычисляется как:
r(t) = r0 + (r1 - r0) * easing(t)
Такой подход обеспечивает плавность вращения и позволяет комбинировать rotation с другими параметрами вида.
Часто вращение используется не изолированно, а совместно с изменением центра и масштаба:
view.animate({
center: [0, 0],
zoom: 4,
rotation: Math.PI / 2,
duration: 2000
});
В этом случае происходит комплексная трансформация сцены: карта одновременно поворачивается, масштабируется и перемещается.
По умолчанию вращение происходит вокруг центра текущего view. Однако можно задать точку, относительно которой происходит анимация.
Используется параметр anchor в более сложных сценариях
через последовательные трансформации:
const center = view.getCenter();
view.animate({
rotation: Math.PI / 4,
anchor: center,
duration: 1200
});
Хотя anchor не всегда явно поддерживается в
высокоуровневом API, концептуально вращение всегда вычисляется
относительно центра проекции.
В случаях, когда требуется полный контроль над вращением, используется ручная интерполяция:
const start = view.getRotation();
const end = start + Math.PI;
const startTime = performance.now();
function rotateFrame(time) {
const t = (time - startTime) / 1000;
const progress = Math.min(t, 1);
const angle = start + (end - start) * progress;
view.setRotation(angle);
if (progress < 1) {
requestAnimationFrame(rotateFrame);
}
}
requestAnimationFrame(rotateFrame);
Этот подход позволяет внедрять кастомные easing-функции и синхронизировать вращение с внешними событиями.
При многократных вращениях угол может выходить за пределы
2π. OpenLayers корректно обрабатывает такие случаи, но для
стабильности логики часто выполняется нормализация:
function normalizeAngle(angle) {
return ((angle + Math.PI) % (2 * Math.PI)) - Math.PI;
}
Это помогает избежать резких скачков при переходе через границу полного оборота.
Вращение часто привязывается к пользовательскому вводу:
map.getView().on('change:rotation', () => {
const rotation = view.getRotation();
console.log(rotation);
});
window.addEventListener('keydown', (e) => {
const step = Math.PI / 18;
if (e.key === 'ArrowLeft') {
view.setRotation(view.getRotation() - step);
}
if (e.key === 'ArrowRight') {
view.setRotation(view.getRotation() + step);
}
});
Функции сглаживания играют ключевую роль в восприятии вращения. OpenLayers предоставляет набор стандартных easing-функций:
easeIneaseOuteaseInOutlinearПример:
import { easeInOut } from 'ol/easing';
view.animate({
rotation: Math.PI,
duration: 2000,
easing: easeInOut
});
Гладкая кривая делает вращение визуально более естественным, особенно при больших углах.
При вращении карты важно учитывать, что координатная система остаётся неизменной. Меняется только матрица преобразования отображения.
OpenLayers применяет rotation как часть трансформации:
screen = translate(center) × rotate(angle) × scale(resolution)
Это означает, что:
Анимация rotation относится к GPU-ускоряемым операциям в современных браузерах. Однако при высокой нагрузке могут возникать ограничения:
Оптимизация достигается за счёт:
При необходимости синхронного вращения нескольких экземпляров карты используется общий обработчик:
view1.on('change:rotation', () => {
view2.setRotation(view1.getRotation());
});
Такой подход применяется в сравнении слоёв или зеркальном отображении данных.
setRotation без
интерполяцииКорректная работа требует строгого соблюдения радианной системы и
понимания внутреннего цикла анимации View.
При включённой инерции взаимодействий (drag/rotate interaction) rotation может продолжаться после отпускания мыши. Это реализуется через momentum-интерполяцию, где угол продолжает изменяться по убывающей скорости.
Такая логика накладывается поверх View.animate, создавая
комбинированный эффект плавного затухания вращения.