Прозрачность и opacity

В основе рендеринга MapLibre GL JS лежит WebGL, где каждый пиксель формируется с учётом альфа-канала. Прозрачность в этом контексте — это не единая настройка, а совокупность параметров, влияющих на смешивание (blending) фрагментов в каждом слое карты.

Ключевая особенность модели: каждый слой управляет собственной прозрачностью через paint-свойства, а итоговая картинка формируется в порядке от нижних слоёв к верхним.


Модель прозрачности в WebGL-рендеринге

MapLibre GL JS использует стандартный альфа-композитинг:

  • каждый пиксель имеет значение RGBA
  • альфа определяет вклад слоя в итоговый цвет
  • результат зависит от порядка отрисовки слоёв

Формально смешивание можно представить как:

C_{out} = _s C_s + (1 - _s) C_d

где:

  • (C_s) — цвет источника (слоя)
  • (C_d) — цвет фона/нижнего слоя
  • (_s) — прозрачность слоя

Важно: в WebGL часто используется premultiplied alpha, что влияет на интерпретацию значений при кастомных шейдерах и источниках данных.


Paint-свойства прозрачности по типам слоёв

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

Fill-слои

Используется для полигонов:

map.setPaintProperty('land', 'fill-opacity', 0.6);

Особенности:

  • влияет на заливку полигона
  • не затрагивает обводку (если она задана отдельно)
  • поддерживает выражения

Line-слои

Для линий применяется:

map.setPaintProperty('road', 'line-opacity', 0.4);

Дополнительно доступны:

  • line-color
  • line-width
  • line-dasharray

Прозрачность влияет на толщину визуального восприятия сети дорог, маршрутов и границ.


Circle-слои

map.setPaintProperty('points', 'circle-opacity', 0.8);

Используется для точечных данных:

  • маркеры
  • кластеры
  • аналитические точки

Symbol-слои

map.setPaintProperty('labels', 'text-opacity', 0.7);
map.setPaintProperty('labels', 'icon-opacity', 0.7);

Особенность symbol-слоёв — раздельная прозрачность текста и иконок, что позволяет независимо управлять читаемостью и визуальной плотностью.


Raster-слои

map.setPaintProperty('satellite', 'raster-opacity', 0.5);

Применяется к тайлам изображений:

  • спутниковые слои
  • растровые карты
  • тепловые изображения

Heatmap-слои

map.setPaintProperty('heat', 'heatmap-opacity', 0.6);

Часто используется совместно с:

  • heatmap-weight
  • heatmap-intensity
  • heatmap-radius

3D и sky-слои

Для 3D-моделей и неба:

map.setPaintProperty('buildings-3d', 'fill-extrusion-opacity', 0.7);
map.setPaintProperty('sky', 'sky-opacity', 0.5);

Динамическая прозрачность через выражения

Opacity в MapLibre GL JS может зависеть от масштаба, свойств объектов и любых выражений стиля.

Масштаб-зависимая прозрачность

map.setPaintProperty('roads', 'line-opacity', [
  'interpolate',
  ['linear'],
  ['zoom'],
  5, 0.2,
  10, 0.8
]);

Логика:

  • при малом масштабе слой почти скрыт
  • при увеличении — становится более выраженным

Прозрачность на основе данных

map.setPaintProperty('points', 'circle-opacity', [
  'case',
  ['>', ['get', 'importance'], 5],
  1,
  0.3
]);

Такой подход используется для:

  • фильтрации значимости объектов
  • визуальной иерархии данных
  • уменьшения визуального шума

Переходы прозрачности (transitions)

MapLibre поддерживает плавные изменения paint-свойств:

map.setPaintProperty('land', 'fill-opacity-transition', {
  duration: 300,
  delay: 0
});

Итог:

  • изменения opacity происходят без резких скачков
  • используется для интерактивных сценариев (hover, selection, zoom)

Влияние порядка слоёв

Прозрачность не является изолированным параметром — она зависит от порядка рендеринга.

  • нижние слои влияют на визуальный фон
  • верхние могут полностью перекрывать нижние даже при низкой opacity
  • пересечение полупрозрачных слоёв приводит к накоплению альфа-эффекта

При сложных стилях часто возникает эффект многослойного затемнения, особенно при большом количестве перекрывающихся полигонов.


CSS opacity контейнера карты

Дополнительно к WebGL-прозрачности существует уровень DOM:

.map-container {
  opacity: 0.5;
}

Особенности:

  • влияет на всю карту целиком
  • затрагивает интерфейсные элементы (если не вынесены отдельно)
  • не рекомендуется для интерактивных сценариев

Причина: применяется после рендеринга WebGL-контента.


Смешивание цветов и визуальные артефакты

При работе с прозрачностью возникают характерные эффекты:

  • затемнение при наложении нескольких слоёв
  • изменение насыщенности цветов
  • визуальное «засорение» карты
  • потеря контраста текста

Особенно заметно при:

  • raster + vector overlay
  • heatmap поверх базовой карты
  • плотных polygon-слоях

Оптимизация прозрачности

Прозрачность влияет не только на визуал, но и на производительность.

Рекомендации:

  • избегать чрезмерного количества полупрозрачных слоёв
  • минимизировать пересечения сложных polygon-объектов
  • использовать opacity вместо фильтрации через сложные шейдеры
  • комбинировать слои через visibility при полном скрытии

Типовые паттерны использования opacity

Подсветка выбранного объекта

map.setPaintProperty('areas', 'fill-opacity', [
  'case',
  ['==', ['get', 'id'], selectedId],
  1,
  0.2
]);

Затемнение фона при активации слоя

map.setPaintProperty('background', 'fill-opacity', 0.3);
map.setPaintProperty('focus-layer', 'fill-opacity', 0.9);

Реакция на hover

map.setPaintProperty('points', 'circle-opacity', [
  'case',
  ['boolean', ['feature-state', 'hover'], false],
  1,
  0.4
]);

Плавное появление данных

map.setPaintProperty('data-layer', 'fill-opacity', 0);
map.setPaintProperty('data-layer', 'fill-opacity-transition', {
  duration: 500
});
map.setPaintProperty('data-layer', 'fill-opacity', 0.8);

Взаимодействие с фильтрацией и видимостью

Opacity часто путается с visibility:

  • opacity управляет прозрачностью
  • visibility полностью исключает слой из рендера
map.setLayoutProperty('layer-id', 'visibility', 'none');

Комбинация подходов:

  • opacity — для анимаций и акцентов
  • visibility — для жёсткого включения/выключения

Итоговые принципы работы с прозрачностью

  • opacity всегда применяется на уровне слоя
  • итоговый эффект зависит от порядка рендеринга
  • выражения позволяют динамически управлять прозрачностью
  • WebGL-композиция усиливает эффект наложения
  • неправильное использование приводит к деградации читаемости карты