Анимированные стили

HERE Technologies предоставляет в JavaScript API гибкую систему стилизации карт, где визуальные изменения могут быть не статичными, а плавно анимированными. Анимация стилей в HERE Maps строится на сочетании трёх механизмов: переходов свойств слоёв, интерполяции визуальных параметров и синхронизации со сценой карты (камерой и таймлайном отображения).


Архитектура стилевой системы и роль анимаций

Стиль карты в HERE Maps API представляет собой набор правил, описывающих отображение векторных тайлов: дороги, здания, водные объекты, подписи и POI. Каждый элемент стиля может включать визуальные параметры:

  • цвет (fill / stroke)
  • прозрачность
  • толщина линий
  • масштабозависимость
  • приоритет отрисовки (z-index)
  • фильтры по типам объектов

Анимация появляется там, где эти параметры изменяются во времени, а не мгновенно.

В основе лежит концепция интерполируемых свойств — значений, которые могут плавно переходить из одного состояния в другое.


Плавные переходы при смене стиля карты

На уровне API смена стиля обычно происходит через map.setStyle() или переключение схемы (setBaseLayer, setScheme). Без дополнительных механизмов это мгновенное обновление, но визуально оно может быть сглажено через контролируемую анимацию.

Пример базового переключения стиля:

map.setStyle('https://custom-style-url/style.json');

Чтобы превратить это в анимацию, применяется подход с промежуточными состояниями:

  1. загрузка нового стиля
  2. постепенное изменение параметров прозрачности старого слоя
  3. наложение нового слоя
  4. завершение перехода

Интерполяция визуальных свойств

Анимация в стиле чаще всего реализуется через линейную интерполяцию значений:

  • цвет: RGB-переход
  • opacity: 1 → 0 или 0 → 1
  • толщина линий: 2px → 6px
  • насыщенность и контрастность

Общая модель интерполяции:

value(t) = start + (end - start) * t

где t изменяется от 0 до 1 во времени анимации.


Анимация слоёв через requestAnimationFrame

Для кастомных эффектов используется requestAnimationFrame, позволяющий синхронизировать изменения со скоростью рендеринга браузера.

Пример плавного изменения прозрачности слоя:

function animateOpacity(layer, from, to, duration) {
  const start = performance.now();

  function frame(time) {
    const t = Math.min((time - start) / duration, 1);
    const opacity = from + (to - from) * t;

    layer.setStyle({
      opacity: opacity
    });

    if (t < 1) {
      requestAnimationFrame(frame);
    }
  }

  requestAnimationFrame(frame);
}

Этот подход используется для:

  • появления/исчезновения POI
  • акцентирования районов
  • визуального переключения тематических слоёв

Камерные анимации и связь со стилями

Отдельный класс анимаций связан не со стилем напрямую, а с положением камеры карты. Однако визуально они часто воспринимаются как стилизация сцены.

Ключевой метод:

map.getViewModel().setLookAtData({
  position: { lat: 52.52, lng: 13.405 },
  zoom: 12,
  tilt: 45,
  heading: 180
}, true);

Параметр true включает анимационный переход.

Связь со стилями проявляется в том, что:

  • при изменении zoom активируются разные правила отображения
  • здания могут “вырастать” при приближении
  • подписи плавно появляются при достижении порога масштаба

Масштабозависимые анимации стилей

Векторные стили поддерживают зависимость от zoom-уровня, что позволяет создавать псевдо-анимации без JavaScript.

Пример логики:

  • zoom 5–8: дороги тонкие, минимум подписей
  • zoom 9–12: дороги толще, появляются районы
  • zoom 13+: здания и POI становятся активными

Хотя это не временная анимация, визуально это воспринимается как постепенное “раскрытие” карты.


Цветовые переходы и тематические смены

Одним из самых заметных эффектов является смена темы карты (день/ночь, транспорт, спутник с наложением).

Плавность достигается через:

  • кросс-фейд между двумя стилями
  • постепенное изменение глобальных цветовых переменных
  • синхронное затемнение слоёв

Пример кросс-фейда:

const oldLayer = map.getBaseLayer();
const newLayer = platform.getMapTileService().createTileLayer(...);

newLayer.setOpacity(0);
map.addLayer(newLayer);

animateOpacity(oldLayer, 1, 0, 800);
animateOpacity(newLayer, 0, 1, 800);

Динамическое обновление стилей объектов

HERE Maps API позволяет изменять стиль отдельных объектов в runtime. Это используется для:

  • выделения маршрута
  • подсветки выбранных POI
  • отображения активности (например, транспорта)

Пример:

mapObject.setStyle({
  fillColor: 'rgba(255, 0, 0, 0.6)',
  strokeColor: '#ff0000',
  lineWidth: 4
});

При изменении этих параметров в цикле можно добиться эффекта пульсации или “дыхания” объекта.


Пульсирующие и временные эффекты

Для создания эффектов активности используется периодическая анимация:

  • увеличение/уменьшение радиуса маркера
  • изменение прозрачности
  • смена цвета по синусоиде

Пример пульсации:

function pulse(marker) {
  let start = performance.now();

  function animate(time) {
    const t = (time - start) / 1000;
    const scale = 1 + Math.sin(t * 3) * 0.3;

    marker.setScale(scale);

    requestAnimationFrame(animate);
  }

  requestAnimationFrame(animate);
}

Синхронизация анимаций с данными в реальном времени

При работе с движущимися объектами (например, транспортом или трекингом):

  • координаты обновляются по таймеру
  • стиль изменяется в зависимости от скорости
  • направление влияет на визуальную ориентацию

Пример зависимости стиля от скорости:

  • 0–10 км/ч: серый цвет
  • 10–50 км/ч: синий
  • 50+ км/ч: красный
function getColor(speed) {
  if (speed < 10) return '#888';
  if (speed < 50) return '#2a7fff';
  return '#ff3b3b';
}

Производительность и ограничения анимаций

Анимации в картографических приложениях критичны к производительности GPU.

Основные ограничения:

  • слишком частые setStyle вызывают repaint
  • большое количество анимированных объектов снижает FPS
  • сложные фильтры по слоям увеличивают нагрузку

Оптимизационные подходы:

  • группировка обновлений в один frame
  • использование opacity вместо пересоздания стиля
  • ограничение числа одновременно анимируемых объектов
  • отключение ненужных слоёв при зуме

Комбинирование камерных и стилевых анимаций

Максимальный визуальный эффект достигается при синхронизации:

  • плавного зума
  • изменения угла обзора
  • изменения насыщенности слоёв
  • появления подписей

Типичный сценарий — “погружение в карту”:

  1. камера приближается
  2. включаются здания
  3. увеличивается контраст дорог
  4. появляются подписи
  5. активируются POI-анимации

Практика построения сложных сцен

Сложные анимационные сцены строятся как последовательность таймлайнов:

  • этап 1: смена базового стиля
  • этап 2: появление объектов
  • этап 3: акцент маршрутов
  • этап 4: стабилизация сцены

Каждый этап реализуется через собственный интервал времени и независимые интерполяции, что позволяет избегать блокировок рендеринга и сохранять плавность интерфейса.