Цвет, толщина и прозрачность

В Leaflet все векторные примитивы — линии, полигоны, окружности и маркеры-круги — наследуют единый набор параметров стиля. Эти параметры передаются через объект options, который применяется при создании слоя или изменяется динамически через setStyle.

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


Цвет линии и обводки

Основной параметр, определяющий внешний вид линий и контуров, — color. Он задаёт цвет обводки для:

  • L.polyline
  • L.polygon
  • L.circle
  • L.circleMarker

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

L.polyline([[55.75, 37.61], [55.76, 37.64]], {
    color: '#3388ff'
}).addTo(map);

Цвет может быть задан в любом допустимом CSS-формате:

  • hex (#ff0000)
  • rgb (rgb(255,0,0))
  • именованные цвета (red)

Для полигонов цвет применяется к границе, а не к заливке. Это важно учитывать при визуальном проектировании слоёв.


Толщина линий и контуров

Параметр weight управляет толщиной обводки. Он задаётся в пикселях и влияет на все векторные примитивы с линиями:

L.polyline(coords, {
    color: 'blue',
    weight: 8
}).addTo(map);

Поведение weight различается в зависимости от типа слоя:

  • у polyline — толщина линии
  • у polygon — толщина границы
  • у circle — толщина окружности
  • у circleMarker — влияет на размер обводки маркера

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


Прозрачность линий

Параметр opacity регулирует прозрачность обводки. Значение находится в диапазоне от 0.0 до 1.0:

  • 1.0 — полностью непрозрачная линия
  • 0.5 — полупрозрачная
  • 0.0 — полностью скрытая

Пример:

L.polyline(coords, {
    color: 'green',
    weight: 4,
    opacity: 0.6
}).addTo(map);

Важно, что opacity применяется только к линии (stroke), но не к заливке.


Заливка полигонов

Для полигонов и кругов существует отдельная группа параметров, отвечающих за внутреннюю область:

  • fillColor — цвет заливки
  • fillOpacity — прозрачность заливки
L.polygon(coords, {
    color: 'black',
    weight: 2,
    fillColor: '#ffcc00',
    fillOpacity: 0.4
}).addTo(map);

Если fillColor не задан, используется значение color.

Если fillOpacity равен 0, заливка визуально отсутствует, но геометрия остаётся интерактивной.


Разделение stroke и fill

Leaflet использует классическую модель SVG:

  • stroke — обводка
  • fill — заливка

Эта модель позволяет независимо управлять визуальными слоями объекта.

Типичное сочетание параметров:

{
    color: '#000',
    weight: 3,
    opacity: 0.8,
    fillColor: '#00aaff',
    fillOpacity: 0.3
}

Такое разделение особенно важно при работе с административными границами и тепловыми картами на основе полигонов.


Пунктирные и нестандартные линии

Параметр dashArray управляет шаблоном линии. Он задаёт чередование сегментов и пробелов:

L.polyline(coords, {
    color: 'purple',
    weight: 3,
    dashArray: '10 5'
}).addTo(map);

Формат строки:

"длина_штриха пробел длина_штриха пробел ..."

Примеры:

  • "5 5" — равномерный пунктир
  • "10 2 2 2" — сложный ритмический узор
  • "1 0" — почти сплошная линия с визуальными разрывами отсутствующими

Круги и circleMarker: особенности стиля

L.circle и L.circleMarker используют один и тот же набор стилей, но различаются по логике размеров:

  • circle — радиус в метрах (географическая величина)
  • circleMarker — радиус в пикселях (экранная величина)

Пример circle:

L.circle([55.75, 37.61], {
    radius: 500,
    color: 'red',
    fillColor: '#f03',
    fillOpacity: 0.3
}).addTo(map);

Пример circleMarker:

L.circleMarker([55.75, 37.61], {
    radius: 10,
    color: '#3388ff',
    weight: 2,
    fillOpacity: 0.5
}).addTo(map);

В случае circleMarker толщина обводки визуально влияет на общий размер элемента сильнее, чем у географических кругов.


Динамическое изменение стилей

Leaflet позволяет изменять стили уже добавленных объектов через метод setStyle:

const line = L.polyline(coords, {
    color: 'blue',
    weight: 4
}).addTo(map);

line.setStyle({
    color: 'red',
    weight: 6,
    opacity: 0.9
});

Метод применим ко всем векторным слоям, кроме marker (иконок), которые используют отдельную систему обновления.


Наследование и переопределение стилей

При создании сложных слоёв с несколькими геометриями (например, FeatureGroup) стиль может задаваться:

  • на уровне группы
  • на уровне отдельных элементов

При конфликте приоритет получает стиль конкретного слоя.

L.featureGroup([
    L.polyline(coords, { color: 'blue' }),
    L.polygon(coords2, { color: 'green' })
], {
    color: 'black'
}).addTo(map);

Здесь глобальный цвет группы не переопределяет локальные значения.


Прозрачность как инструмент визуальной иерархии

Комбинация opacity и fillOpacity часто используется для построения визуальной иерархии слоёв:

  • более важные объекты — высокая непрозрачность
  • фоновые слои — сниженная прозрачность
  • перекрывающиеся области — разные уровни alpha

Типичный паттерн:

{
    color: '#444',
    weight: 2,
    opacity: 0.7,
    fillColor: '#66ccff',
    fillOpacity: 0.2
}

Такое сочетание позволяет одновременно сохранять читаемость границ и не перегружать карту.


Влияние SVG-рендеринга на визуальные параметры

Leaflet использует SVG для векторных слоёв (или Canvas в режиме preferCanvas). Это влияет на интерпретацию стилей:

  • opacity применяется через SVG-атрибут stroke-opacity
  • fillOpacity — через fill-opacity
  • weight — через stroke-width

При Canvas-рендеринге возможны небольшие различия в антиалиасинге и восприятии прозрачности, особенно при наложении нескольких слоёв.


Комбинирование параметров для сложных визуальных эффектов

Сочетание всех параметров позволяет создавать сложные стили:

L.polygon(coords, {
    color: '#000',
    weight: 1,
    opacity: 0.4,
    fillColor: '#ff6600',
    fillOpacity: 0.15,
    dashArray: '4 6'
}).addTo(map);

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

  • карт плотности
  • административных границ
  • маршрутов с альтернативными состояниями
  • интерактивных слоёв с подсветкой

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

Стили часто изменяются в ответ на события:

layer.on('mouseover', function () {
    this.setStyle({
        weight: 5,
        fillOpacity: 0.6
    });
});

layer.on('mouseout', function () {
    this.setStyle({
        weight: 2,
        fillOpacity: 0.3
    });
});

Такой механизм позволяет визуально выделять активные объекты без изменения геометрии или структуры слоя.