В Deck.gl вся логика отображения сцены напрямую связана с понятием
viewport (окна просмотра), которое определяется через
объект viewState. Он описывает положение камеры, масштаб,
угол наклона и ориентацию сцены.
Ключевая идея: любое движение карты или 3D-сцены — это изменение
viewState, которое может происходить мгновенно или с
анимацией.
Основные параметры viewState для
MapView:
longitude — долгота центраlatitude — широта центраzoom — уровень приближенияbearing — поворот картыpitch — наклон камерыПример базового состояния:
const INITIAL_VIEW_STATE = {
longitude: 37.6173,
latitude: 55.7558,
zoom: 10,
bearing: 0,
pitch: 0
};
Любое изменение этих параметров может быть интерпретировано как мгновенное или анимированное перемещение камеры.
DeckGL использует реактивную модель: каждый кадр сцена
пересчитывается на основе текущего viewState. Управление
осуществляется через:
<DeckGL
initialViewState={INITIAL_VIEW_STATE}
controller={true}
onViewStateCha nge={({ viewState }) => {
// обновление состояния
}}
/>
При включённом controller, пользовательские действия
(панорамирование, зум, вращение) автоматически генерируют новые
viewState.
Анимация появляется тогда, когда изменения состояния интерполируются во времени, а не применяются напрямую.
Анимация в Deck.gl основана на интерполяции параметров камеры между начальным и конечным состоянием.
Общая модель:
viewState(t) = interpolate(startViewState, endViewState, easing(t))
где:
t — прогресс анимации от 0 до 1easing(t) — функция сглаживанияinterpolate — линейная или специализированная
интерполяцияДля разных параметров применяются разные стратегии:
Deck.gl предоставляет встроенный механизм анимации через свойства переходов:
const viewState = {
longitude: 37.6173,
latitude: 55.7558,
zoom: 12,
transitionDuration: 2000,
transitionInterpolator: new FlyToInterpolator(),
transitionEasing: t => t
};
Ключевые параметры:
transitionDuration
transitionInterpolator
transitionEasing
FlyToInterpolator реализует анимацию, имитирующую “полёт
камеры” над поверхностью карты.
Он учитывает:
Математически движение делится на этапы:
Пример использования:
import {FlyToInterpolator} from '@deck.gl/core';
const nextViewState = {
longitude: 2.3522,
latitude: 48.8566,
zoom: 11,
bearing: 20,
pitch: 45,
transitionDuration: 3000,
transitionInterpolator: new FlyToInterpolator()
};
Функции сглаживания определяют поведение анимации во времени.
Наиболее распространённые формы:
Пример:
transitionEasing: t => t * t * (3 - 2 * t)
Эта функция создаёт плавное ускорение и торможение без резких скачков.
Изменение viewState вручную позволяет создавать сложные
сценарии навигации:
function moveToParis() {
setViewState({
longitude: 2.3522,
latitude: 48.8566,
zoom: 12,
transitionDuration: 2500,
transitionInterpolator: new FlyToInterpolator()
});
}
Каждое новое состояние автоматически запускает анимацию, если задан
transitionDuration.
Если во время анимации приходит новое viewState, текущий
переход прерывается, и начинается новый.
Это создаёт модель:
state_n → transition → state_n+1 → transition → state_n+2
Без промежуточных фиксаций, что позволяет реализовать динамическую навигацию.
При включённом controller пользовательские действия и
программные переходы смешиваются в единую систему.
Особенности:
viewStateDeck.gl позволяет создавать собственные интерполяторы, переопределяя логику перехода.
Структура интерполятора:
class CustomInterpolator {
interpolateViewStates(from, to, t) {
return {
longitude: from.longitude + (to.longitude - from.longitude) * t,
latitude: from.latitude + (to.latitude - from.latitude) * t,
zoom: from.zoom + (to.zoom - from.zoom) * t
};
}
}
Это даёт полный контроль над траекторией камеры.
При использовании View-системы (например,
MapView, OrthographicView,
FirstPersonView) каждый viewport имеет собственное
состояние.
Пример:
const views = [
new MapView({id: 'map'}),
new FirstPersonView({id: 'fp'})
];
Каждый view может иметь независимую анимацию viewState,
но синхронизация возможна через общий state store.
Анимация viewport в Deck.gl можно описать как систему кинематики:
Обобщённая модель движения:
C(t) = C0 + (C1 - C0) * s(t)
где s(t) — функция сглаживания траектории.
Для углов используется нормализация:
Δangle = ((end - start + 180) % 360) - 180
что предотвращает “длинные” вращения.
Анимация выполняется на каждом кадре render loop, поэтому критичны:
viewStateDeck.gl оптимизирует вычисления через WebGL pipeline, оставляя CPU только для расчёта состояния камеры.
Изменение viewport влияет на:
Каждый кадр анимации фактически является новым состоянием сцены, а не только перемещением камеры.