Библиотека построена вокруг иерархии классов, где базовые сущности задают общие механизмы рендеринга, управления состоянием и взаимодействия с WebGL-контекстом. Основной принцип — расширение функциональности через наследование, а не через композицию функций в процедурном стиле.
Ключевым элементом системы является класс слоя, от которого происходят все визуальные компоненты. Он инкапсулирует жизненный цикл, работу с данными и взаимодействие с GPU.
deck.gl реализует фундаментальную абстракцию слоя через класс
Layer. Любой визуальный примитив — это наследник данного
класса.
Основные задачи базового класса:
data)props)AttributeManagerНаследники Layer переопределяют ключевые методы:
class CustomLayer extends Layer {
initializeState() {
// создание атрибутов и буферов
}
updateState({ props, oldProps, changeFlags }) {
// реакция на изменения свойств или данных
}
draw({ uniforms }) {
// отрисовка через WebGL шейдеры
}
finalizeState() {
// освобождение ресурсов
}
}
initializeState вызывается один раз при создании слоя. Здесь создаются GPU-ресурсы, регистрируются атрибуты и выполняется первичная настройка.
updateState реагирует на изменения входных данных и
свойств. Механизм changeFlags позволяет точно определить,
что изменилось: данные, геометрия, параметры отрисовки.
draw отвечает за рендеринг. На этом этапе формируются uniform-параметры и вызываются шейдерные программы.
finalizeState освобождает WebGL-ресурсы и очищает память.
Наследование Layer предполагает строгую модель
состояния. Состояние слоя хранится отдельно от props и управляется через
внутренний объект state.
initializeState() {
const { gl } = this.context;
this.state = {
model: this._createModel(gl)
};
}
Состояние используется для хранения:
Важно, что прямое изменение props недопустимо. Все
вычисления производных данных выполняются внутри
updateState.
Одним из ключевых компонентов является AttributeManager.
Он автоматизирует работу с vertex attributes и минимизирует ручное
управление буферами.
Наследники слоя регистрируют атрибуты:
this.state.attributeManager.add({
positions: {
size: 3,
accessor: 'getPosition'
}
});
Механизм обеспечивает:
CompositeLayer — специализированный класс,
предназначенный для композиции других слоёв. Он не выполняет прямой
WebGL-рендеринг, а управляет набором дочерних слоёв.
Иерархия:
Layer → CompositeLayer → пользовательский составной слой
Основной метод:
renderLayers() {
return [
new ScatterplotLayer(...),
new ArcLayer(...)
];
}
CompositeLayer автоматически проксирует свойства дочерним слоям:
propsМетод _subLayerProps позволяет модифицировать
параметры:
_getSubLayerProps() {
return {
opacity: this.props.opacity * 0.5
};
}
При расширении CompositeLayer переопределяется не
draw, а renderLayers. Это ключевое отличие
архитектуры:
class CustomCompositeLayer extends CompositeLayer {
renderLayers() {
const { data } = this.props;
return data.map(item =>
new SomeLayer({
id: item.id,
data: item.points
})
);
}
}
Такой подход позволяет:
Помимо слоёв, в архитектуре присутствуют классы представлений
(View, Viewport). Они также используют
наследование, но в другом контексте — управления камерой и
проекцией.
Пример:
class CustomView extends View {
makeViewport({ width, height }) {
return new WebMercatorViewport({
width,
height,
longitude: this.props.longitude,
latitude: this.props.latitude,
zoom: this.props.zoom
});
}
}
Здесь наследование используется для:
Иерархия Deck.gl строится вокруг повторного использования логики:
Layer — базовая графикаCompositeLayer — композиция слоёвScatterplotLayer,
PathLayer, PolygonLayer) — конкретные
реализацииКаждый уровень наследования добавляет:
Наследники обязаны соблюдать контракт базового класса:
super при необходимостиПример корректного расширения:
updateState(params) {
super.updateState(params);
if (params.changeFlags.dataChanged) {
this._rebuildGeometry();
}
}
Нарушение модели наследования приводит к проблемам производительности и утечкам памяти:
initializeStatefinalizeStateprops вместо вычисления производных
данныхAttributeManager и ручное управление
буферамиОсобенно критично создание моделей вне жизненного цикла слоя, что приводит к неконтролируемому росту GPU-ресурсов.
Сложные визуализации строятся через цепочку наследников:
Layer
→ CompositeLayer
→ CustomVisualizationLayer
→ Domain-specific Layer
Каждый уровень добавляет:
Такой подход позволяет строить масштабируемые сцены с минимальной дубликацией кода.
Несмотря на использование классов, Deck.gl сохраняет декларативную модель описания сцены. Наследование служит механизмом реализации, а не основным способом управления логикой.
Слой описывается как функция от props, где:
Иерархия классов лишь структурирует эту модель, обеспечивая единый жизненный цикл и оптимизацию обновлений.