Deck класс

Класс Deck является центральной точкой управления рендерингом в библиотеке Deck.gl и выступает как контейнер верхнего уровня для всех визуализаций. Он связывает WebGL-контекст, набор слоёв, параметры камеры, обработку событий и цикл обновления сцены.

Архитектурно Deck можно рассматривать как тонкий управляющий слой над WebGL, который координирует работу отдельных визуальных слоёв (Layer), управляет состоянием вида (viewState) и обеспечивает реактивный рендеринг при изменениях входных данных.


Инициализация экземпляра Deck

Создание экземпляра Deck выполняется через конструктор, принимающий конфигурационный объект. Этот объект определяет всю сцену рендеринга.

import {Deck} from '@deck.gl/core';

const deck = new Deck({
  initialViewState: {
    longitude: 37.6173,
    latitude: 55.7558,
    zoom: 10,
    pitch: 0,
    bearing: 0
  },
  controller: true
});

Ключевые параметры конструктора

container DOM-элемент, в который будет встроен canvas WebGL. Если не указан, Deck создаёт собственный canvas.

layers Массив экземпляров слоёв, описывающих визуальные данные сцены.

views Описание представлений (View), например MapView, FirstPersonView, OrthographicView.

initialViewState Начальное состояние камеры. Используется только при первом создании экземпляра.

viewState Текущее состояние камеры. При его изменении происходит перерасчёт матрицы проекции и перерисовка сцены.

controller Включение интерактивного управления камерой (панорамирование, зум, вращение).


Роль Deck в рендеринговом цикле

Внутри Deck.gl реализован реактивный цикл обновления. Любое изменение входных данных приводит к перерасчёту и повторному рендеру.

Основные этапы:

  1. Обновление состояния (setProps)
  2. Пересборка слоёв
  3. Компиляция шейдеров при необходимости
  4. Обновление uniform-параметров
  5. Рендер в WebGL контекст

Ключевая особенность заключается в дифференциальном обновлении: пересоздаются только те слои, чьи свойства изменились.


Метод setProps

Метод setProps является основным механизмом динамического обновления состояния Deck.

deck.setProps({
  layers: newLayers,
  viewState: {
    longitude: 30,
    latitude: 50,
    zoom: 5
  }
});

Поведение setProps

  • Производит shallow merge новых свойств
  • Запускает reconciliation слоёв
  • Триггерит перерасчёт view state
  • Вызывает повторный render

Важно, что setProps не пересоздаёт WebGL контекст, а только обновляет сцену.


Управление слоями через Deck

Deck не хранит данные напрямую — он оперирует слоями как декларативными объектами.

import {ScatterplotLayer} from '@deck.gl/layers';

const layers = [
  new ScatterplotLayer({
    id: 'points',
    data: [
      {position: [37.6, 55.7], size: 1000}
    ],
    getPosition: d => d.position,
    getRadius: d => d.size,
    getFillColor: [255, 0, 0]
  })
];

deck.setProps({layers});

Особенности работы с слоями

  • Каждый слой имеет уникальный id
  • Deck использует id для дифференциации изменений
  • При изменении данных слой может быть переинициализирован или обновлён частично
  • Слои рендерятся в порядке массива

Работа с viewState

viewState определяет положение и ориентацию камеры.

deck.setProps({
  viewState: {
    longitude: 10,
    latitude: 20,
    zoom: 4,
    pitch: 45,
    bearing: 30
  }
});

Компоненты viewState

  • longitude / latitude — центр карты
  • zoom — уровень приближения
  • pitch — наклон камеры
  • bearing — вращение вокруг оси Z

Deck пересчитывает матрицы преобразования при каждом изменении этих параметров, что влияет на все слои одновременно.


Подсистема контроллера

Контроллер (controller) отвечает за интерактивность сцены.

const deck = new Deck({
  controller: {
    scrollZoom: true,
    dragPan: true,
    doubleClickZoom: true,
    touchRotate: true
  }
});

Поведение контроллера

Контроллер преобразует пользовательские события в изменения viewState. Внутри происходит:

  • Обработка DOM событий
  • Перевод координат экрана в географические координаты
  • Интерполяция движения камеры
  • Ограничение диапазонов (minZoom, maxZoom)

Рендеринг и WebGL контекст

Deck создаёт и управляет WebGL2 контекстом (или WebGL1 при отсутствии поддержки).

Основные задачи рендерера:

  • Управление фреймбуфером
  • Очистка буфера кадра
  • Настройка blending-режимов
  • Передача uniform-параметров в шейдеры
const deck = new Deck({
  glOptions: {
    preserveDrawingBuffer: true,
    antialias: true,
    stencil: true
  }
});

Жизненный цикл Deck

Экземпляр Deck проходит несколько стадий:

Инициализация

  • Создание canvas
  • Инициализация WebGL контекста
  • Создание базового состояния

Активная фаза

  • Приём setProps
  • Обновление слоёв
  • Рендер кадров

Обновление сцены

  • Diff слоёв
  • Обновление атрибутов
  • Пересчёт матриц

Уничтожение

deck.finalize();

Удаляются:

  • WebGL ресурсы
  • Buffers
  • Textures
  • Event listeners

Взаимодействие Deck и Layer системы

Deck является координатором, но не выполняет вычисления геометрии напрямую. Это делегируется слоям.

Поток данных:

  1. Deck получает props
  2. Передаёт данные слоям
  3. Слои создают attributes
  4. Attributes передаются в GPU
  5. Шейдеры выполняют отрисовку

Поддержка multiple views

Deck поддерживает мульти-вью композицию.

import {MapView, FirstPersonView} from '@deck.gl/core';

const deck = new Deck({
  views: [
    new MapView({id: 'map'}),
    new FirstPersonView({id: 'fp'})
  ]
});

Каждый view имеет собственную:

  • камеру
  • viewport
  • область рендеринга

Deck разделяет canvas на несколько областей рендера.


Обработка событий picking

Deck реализует систему picking для интерактивного взаимодействия с объектами.

deck.pickObject({
  x: 100,
  y: 150
});

Процесс picking

  • Рендер в offscreen buffer
  • Кодирование объектов в цветовые ID
  • Чтение пикселя под курсором
  • Декодирование ID слоя и объекта

Оптимизация производительности

Внутри Deck применяются несколько стратегий оптимизации:

Батчинг рендера

Слои группируются для минимизации draw calls.

Ленивая пересборка

Геометрия пересоздаётся только при изменении данных.

Кэширование шейдеров

Шейдерные программы переиспользуются между слоями.

Attribute invalidation

Изменяются только затронутые атрибуты:

  • position
  • color
  • size
  • instance data

Обновление и реактивность

Deck работает по модели декларативного обновления.

deck.setProps({
  layers: updatedLayers
});

Любое изменение props запускает pipeline:

  • diff предыдущего состояния
  • обновление затронутых слоёв
  • перерасчёт uniforms
  • перерисовка сцены

Внутренние события Deck

Deck может генерировать события:

  • onViewStateChange
  • onHover
  • onClick
  • onLoad
const deck = new Deck({
  onClick: info => {
    console.log(info.object);
  }
});

События проходят через систему picking и привязываются к конкретным объектам сцены.


Работа с анимациями

Deck поддерживает плавные переходы состояний.

Изменение viewState может быть интерполировано:

  • easing функции
  • duration
  • transition interpolation

Deck синхронизирует анимацию с render loop, обеспечивая стабильный FPS.


Взаимодействие с внешним циклом рендера

Deck может работать как в автономном режиме, так и встраиваться в внешний render loop.

function animate() {
  deck.redraw();
  requestAnimationFrame(animate);
}
animate();

Метод redraw принудительно инициирует отрисовку текущего состояния без изменения props.


Управление ресурсами WebGL

Deck автоматически управляет:

  • буферами вершин
  • индексными буферами
  • текстурами
  • framebuffer objects

Каждый слой может создавать собственные GPU ресурсы, которые освобождаются при:

  • удалении слоя
  • вызове finalize
  • замене props

Поведение при изменении размеров контейнера

Deck отслеживает resize контейнера и пересчитывает:

  • viewport
  • projection matrix
  • aspect ratio

Это гарантирует корректное отображение сцены при адаптивной верстке.