В библиотеке Deck.gl система переходов свойств слоёв предназначена для плавной интерполяции между старым и новым состоянием визуализации при изменении входных параметров слоя. Это ключевой механизм для создания анимаций при обновлении данных без ручного управления кадрами и временными циклами.
Переходы применяются к любым свойствам слоя, которые поддерживают интерполяцию: координаты, цвета, размеры, углы поворота, прозрачность и другие числовые или векторные параметры.
Основная идея заключается в том, что при обновлении props слоя Deck.gl не заменяет значения мгновенно, а вычисляет промежуточные состояния на протяжении заданного времени.
Механизм transitions активируется через свойство
transitions, передаваемое в конфигурации слоя.
new ScatterplotLayer({
id: 'points',
data,
getPosition: d => d.position,
getRadius: d => d.radius,
getFillColor: d => d.color,
transitions: {
getPosition: 1000,
getRadius: 800,
getFillColor: 1200
}
});
Каждое свойство в объекте transitions определяет
длительность анимации в миллисекундах для соответствующего
accessor-поля.
Если новое значение приходит при обновлении слоя, Deck.gl автоматически интерполирует между предыдущим и новым состоянием.
Внутри Deck.gl переходы реализуются как состояние между двумя версиями props:
Для каждого кадра вычисляется промежуточное значение:
value(t) = interpolate(oldValue, newValue, easing(t))
Интерполяция зависит от типа данных:
Наиболее часто анимируются координаты:
getPositiongetSourcePosition / getTargetPosition (в
линейных слоях)getElevationПереходы координат используются для морфинга геометрии и перемещения объектов на карте.
К ним относятся параметры внешнего вида:
getFillColorgetLineColorgetRadiusgetWidthopacityЭти свойства позволяют создавать эффекты плавного изменения визуального состояния без пересоздания слоя.
Некоторые слои поддерживают более сложные параметры:
В этих случаях интерполяция выполняется поэлементно внутри структуры данных.
Переход запускается при изменении props слоя. Важное условие: Deck.gl сравнивает новое значение с предыдущим.
layer = new ScatterplotLayer({
id: 'points',
data: newData,
getPosition: d => d.position,
transitions: {
getPosition: 1000
}
});
При каждом обновлении:
По умолчанию используется линейная интерполяция, но Deck.gl поддерживает кастомные easing-функции.
transitions: {
getPosition: {
duration: 1200,
easing: t => t * t * (3 - 2 * t)
}
}
Easing влияет на скорость изменения параметров во времени:
Помимо числового значения длительности, допускается расширенная конфигурация:
transitions: {
getPosition: {
duration: 1000,
easing: t => t,
enter: 0,
onStart: () => {},
onEnd: () => {}
}
}
Особое поведение наблюдается при динамическом изменении массива
data.
Для новых объектов применяется состояние enter, которое
определяет начальное значение анимации.
transitions: {
getPosition: {
duration: 700,
enter: 0
}
}
Новые элементы могут появляться из:
Удалённые элементы не исчезают мгновенно. Вместо этого они переходят в состояние выхода, если слой поддерживает это поведение.
Некоторые слои используют внутренние механизмы diffing, чтобы сохранить предыдущие атрибуты до завершения анимации.
Переходы напрямую связаны с обновлением GPU-атрибутов. Основная нагрузка распределяется следующим образом:
Оптимизации:
При большом количестве объектов предпочтительно ограничивать число одновременно анимируемых атрибутов.
Deck.gl использует updateTriggers для определения, когда
пересчитывать атрибуты.
getPosition: d => d.position,
updateTriggers: {
getPosition: dataVersion
}
Если updateTriggers изменяется, происходит пересчёт
атрибутов, после чего может быть запущен переход.
Важно различать:
updateTriggers → пересчёт данныхtransitions → анимация между состояниямиПри частом обновлении props возможны ситуации, когда переход прерывается.
Поведение:
Это важно при потоковых данных, где обновления приходят с высокой частотой.
Для многокомпонентных атрибутов применяется рекурсивная интерполяция:
rgba1 → rgba2
Каждый канал интерполируется отдельно.
Для линий и полигонов:
Если структуры несовместимы, Deck.gl может пропускать анимацию или применять мгновенное переключение.
Промежуточные значения передаются в GPU через attribute buffers. В вершинных шейдерах используется уже интерполированное состояние.
Это означает:
Разделение позволяет поддерживать высокую частоту кадров даже при сложных сценах.
Плавное изменение радиусов и позиций точек при смене уровня агрегации данных.
Изменение getWidth и getColor для
отображения интенсивности потоков.
Переход между различными представлениями одного и того же набора данных через одновременную анимацию нескольких свойств.
При слишком частых обновлениях визуальная плавность снижается из-за постоянного перезапуска интерполяции.
При наличии нескольких слоёв с общими данными переходы могут быть синхронизированы через одинаковые durations.
transitions: {
getPosition: 1000,
getColor: 1000,
getRadius: 1000
}
Это обеспечивает согласованное визуальное поведение всех слоёв сцены.