Создание проекта на основе Deck.gl обычно начинается с подготовки окружения JavaScript-приложения и выбора сборщика модулей. На практике чаще всего используется связка Node.js, npm (или yarn) и современного бандлера — Vite, Webpack или Parcel.
Базовая структура проекта формируется через инициализацию:
npm init -y
После создания package.json устанавливаются основные
зависимости:
npm install deck.gl react react-dom
npm install @deck.gl/core @deck.gl/layers
При использовании интеграции с картами дополнительно подключается Mapbox:
npm install mapbox-gl
Для проектов с Vite установка выполняется иначе:
npm create vite@latest deckgl-app
cd deckgl-app
npm install
Deck.gl представляет собой слой над WebGL, где основная концепция строится вокруг слоёв (layers). Каждый слой отвечает за отрисовку определённого типа данных: точек, линий, полигонов, облаков точек, сеток и кастомных WebGL-объектов.
Ключевые элементы архитектуры:
Минимальная HTML-структура для подключения приложения:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>Deck.gl проект</title>
<style>
body {
margin: 0;
overflow: hidden;
}
#app {
width: 100vw;
height: 100vh;
}
</style>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
Контейнер #app используется как поверхность для
WebGL-рендеринга.
Основная точка входа приложения — создание экземпляра
Deck.
import {Deck} from '@deck.gl/core';
import {ScatterplotLayer} from '@deck.gl/layers';
const data = [
{position: [37.78, -122.41], size: 100},
{position: [37.79, -122.42], size: 200},
{position: [37.77, -122.43], size: 150}
];
const deckgl = new Deck({
initialViewState: {
longitude: -122.41,
latitude: 37.78,
zoom: 11,
pitch: 0,
bearing: 0
},
controller: true,
layers: [
new ScatterplotLayer({
id: 'scatter',
data,
getPosition: d => d.position,
getRadius: d => d.size,
getFillColor: [255, 140, 0]
})
],
getTooltip: ({object}) => object && `size: ${object.size}`
});
ViewState определяет поведение виртуальной камеры. Он
включает ключевые параметры:
Пример изменения состояния:
const viewState = {
longitude: -73.935242,
latitude: 40.73061,
zoom: 10,
pitch: 45,
bearing: 30
};
При необходимости динамического управления используется обработчик:
onViewStateChange: ({viewState}) => {
deckgl.setProps({viewState});
}
Deck.gl использует систему слоёв, где каждый слой отвечает за собственный тип визуализации.
import {ScatterplotLayer} from '@deck.gl/layers';
new ScatterplotLayer({
id: 'points',
data,
getPosition: d => d.position,
getRadius: d => d.size,
getFillColor: [0, 128, 255],
radiusUnits: 'meters'
});
import {PathLayer} from '@deck.gl/layers';
new PathLayer({
id: 'paths',
data: [
{path: [[-122.4, 37.7], [-122.5, 37.8]]}
],
getPath: d => d.path,
getColor: [255, 0, 0],
widthMinPixels: 2
});
import {PolygonLayer} from '@deck.gl/layers';
new PolygonLayer({
id: 'polygons',
data: [
{
contour: [
[-122.4, 37.7],
[-122.5, 37.7],
[-122.5, 37.8],
[-122.4, 37.8]
]
}
],
getPolygon: d => d.contour,
getFillColor: [0, 200, 100, 150]
});
Deck.gl часто используется поверх Mapbox-карт, что позволяет комбинировать векторные тайлы и WebGL-слои.
import mapboxgl from 'mapbox-gl';
import {MapboxOverlay} from '@deck.gl/mapbox';
import {ScatterplotLayer} from '@deck.gl/layers';
mapboxgl.accessToken = 'TOKEN';
const map = new mapboxgl.Map({
container: 'app',
style: 'mapbox://styles/mapbox/dark-v11',
center: [-122.41, 37.78],
zoom: 11
});
const overlay = new MapboxOverlay({
layers: [
new ScatterplotLayer({
id: 'scatter',
data,
getPosition: d => d.position,
getRadius: d => d.size,
getFillColor: [255, 200, 0]
})
]
});
map.addControl(overlay);
Deck.gl работает с различными форматами данных: массивы объектов, GeoJSON, бинарные форматы.
GeoJSON пример:
import {GeoJsonLayer} from '@deck.gl/layers';
new GeoJsonLayer({
id: 'geojson',
data: '/data/regions.geojson',
filled: true,
stroked: true,
getFillColor: [200, 0, 80, 120],
getLineColor: [255, 255, 255]
});
Deck.gl поддерживает обновление слоёв через пересоздание конфигурации:
function updateData(newData) {
deckgl.setProps({
layers: [
new ScatterplotLayer({
id: 'scatter',
data: newData,
getPosition: d => d.position,
getRadius: d => d.size
})
]
});
}
При потоковых данных часто используется паттерн immutability: новый массив данных заменяет старый без мутаций.
Производительность в Deck.gl зависит от структуры данных и количества отрисовываемых объектов.
Основные подходы оптимизации:
binary attributes вместо JS-объектовupdateTriggersinstanced renderingПример updateTriggers:
new ScatterplotLayer({
id: 'optimized',
data,
getColor: d => d.color,
updateTriggers: {
getColor: [data]
}
});
Deck.gl поддерживает обработку событий:
new ScatterplotLayer({
id: 'interactive',
data,
pickable: true,
onClick: info => {
console.log(info.object);
}
});
Дополнительно доступны:
Deck.gl часто используется вместе с React через DeckGL
компонент.
import DeckGL from '@deck.gl/react';
import {ScatterplotLayer} from '@deck.gl/layers';
function App() {
const layers = [
new ScatterplotLayer({
id: 'scatter',
data,
getPosition: d => d.position,
getRadius: d => d.size
})
];
return (
<DeckGL
initialViewState={{
longitude: -122.41,
latitude: 37.78,
zoom: 11
}}
controller={true}
layers={layers}
/>
);
}
Типичная структура приложения:
deckgl-app/
├── src/
│ ├── layers/
│ ├── data/
│ ├── utils/
│ ├── main.js
├── index.html
├── package.json
├── vite.config.js
Разделение логики по слоям и данным упрощает масштабирование визуализаций.
Deck.gl использует форматы:
[longitude, latitude][x, y, z] в кастомных слояхПример преобразования:
function normalizeCoordinates(d) {
return {
position: [d.lon, d.lat]
};
}
При необходимости реализуются WebGL-слои:
import {Layer} from '@deck.gl/core';
class CustomLayer extends Layer {
initializeState() {}
draw({uniforms}) {
// WebGL rendering logic
}
}
Кастомные слои позволяют выходить за пределы стандартных визуализаций Deck.gl и реализовывать специализированные графические системы.
Состояние карты отделяется от данных. Это позволяет строить предсказуемые визуализации:
const state = {
viewState: {
longitude: 0,
latitude: 0,
zoom: 1
},
data: []
};
Обновления происходят через замену состояния, что упрощает синхронизацию UI и WebGL-слоя.