В Mapbox GL JS композиция слоёв выполняется на уровне WebGL, где каждый слой карты может участвовать в финальном изображении через режимы смешивания цветов. Эти режимы определяют, как пиксели одного слоя взаимодействуют с пикселями нижележащих слоёв.
Ключевое свойство, отвечающее за поведение смешивания:
{
id: 'layer-id',
type: 'fill',
source: 'source-id',
paint: {
'fill-color': '#ff0000',
'fill-opacity': 0.8,
'fill-outline-color': '#000000'
},
'layout': {},
'paint': {
'fill-color': '#ff0000',
'fill-opacity': 0.7
},
'metadata': {},
'source-layer': 'layer-name',
'minzoom': 0,
'maxzoom': 22,
'mix-blend-mode': 'multiply'
}
Свойство mix-blend-mode применяется к слою и влияет на
то, как он композитится с уже отрисованной сценой. Поддерживаемые
значения включают multiply, screen,
overlay и другие режимы из спецификации CSS Compositing and
Blending Level 1.
Режим Multiply основан на умножении цветовых каналов верхнего и нижнего слоёв. В результате изображение становится темнее, а белый цвет фактически становится прозрачным по смыслу композиции.
Математическая модель:
Где:
Multiply применяется для создания эффекта затемнения территорий, наложения плотности данных и визуализации градиентных зон.
Типичные сценарии:
map.addLayer({
id: 'heat-overlay',
type: 'fill',
source: 'regions',
paint: {
'fill-color': 'rgba(255, 0, 0, 0.6)'
},
'mix-blend-mode': 'multiply'
});
Режим Screen является противоположностью Multiply по визуальному эффекту. Он осветляет изображение, комбинируя значения каналов так, что тёмные области становятся менее заметными.
Математическая модель:
Screen используется для визуализаций, где необходимо подчеркнуть яркие зоны поверх тёмного фона.
Типичные сценарии:
map.addLayer({
id: 'routes',
type: 'line',
source: 'routes-source',
paint: {
'line-color': '#00ffff',
'line-width': 3
},
'mix-blend-mode': 'screen'
});
Режим Overlay комбинирует свойства Multiply и Screen в зависимости от яркости базового слоя. Он усиливает контраст, сохраняя детали как в светлых, так и в тёмных областях.
Логика поведения:
Overlay используется для сложных визуализаций, где важно сохранить структуру карты и одновременно усилить данные поверх неё.
Типичные сценарии:
map.addLayer({
id: 'terrain-overlay',
type: 'raster',
source: 'terrain-source',
paint: {
'raster-opacity': 0.6
},
'mix-blend-mode': 'overlay'
});
Режимы смешивания работают строго в контексте порядка слоёв. Mapbox GL JS рендерит слои последовательно, и каждый последующий слой композитится поверх уже отрисованного изображения.
Ключевые факторы влияния:
addLayer)opacity)Пример комбинирования:
map.addLayer({
id: 'base-data',
type: 'fill',
source: 'data',
paint: {
'fill-color': '#ffcc00',
'fill-opacity': 0.5
},
'mix-blend-mode': 'multiply'
});
map.addLayer({
id: 'highlight',
type: 'line',
source: 'data',
paint: {
'line-color': '#ffffff',
'line-width': 2
},
'mix-blend-mode': 'screen'
});
Использование mix-blend-mode переводит слой в режим
дополнительной композиции на GPU. Это увеличивает нагрузку на рендеринг,
особенно при большом количестве слоёв с высокой плотностью
геометрии.
Факторы влияния:
Особенности оптимизации:
mix-blend-mode тесно связан с opacity. При
изменении прозрачности меняется вклад слоя в итоговую композицию.
Пример:
paint: {
'fill-color': '#ff0000',
'fill-opacity': 0.4
}
В сочетании с multiply:
В сочетании с screen:
В аналитических картах blend modes часто используются для наложения данных поверх базовой подложки.
Пример структуры:
mapbox-streetsmap.addLayer({
id: 'event-density',
type: 'circle',
source: 'events',
paint: {
'circle-radius': 6,
'circle-color': '#ff3300',
'circle-opacity': 0.6
},
'mix-blend-mode': 'overlay'
});
Overlay позволяет сохранить читаемость карты, не уничтожая детали подложки.
Режимы смешивания влияют не только на визуальную эстетику, но и на интерпретацию данных.
Multiply:
Screen:
Overlay:
Некоторые особенности поведения:
В сложных визуализациях допускается комбинация разных blend modes в одном проекте.
Пример:
map.addLayer({
id: 'analysis',
type: 'fill',
source: 'data',
paint: {
'fill-color': '#3366ff',
'fill-opacity': 0.5
},
'mix-blend-mode': 'multiply'
});
map.addLayer({
id: 'points',
type: 'circle',
source: 'points',
paint: {
'circle-color': '#ffffff',
'circle-radius': 4
},
'mix-blend-mode': 'screen'
});