В спецификации стилей Mapbox GL JS значения свойств описываются через строго типизированные конструкции, где ключевое различие проходит между статическими литералами и динамическими выражениями. Это разделение определяет поведение слоя на этапе рендеринга и влияет на производительность, гибкость и возможность адаптации карты к данным и масштабу.
Литерал представляет собой неизменяемое значение, которое интерпретируется движком рендеринга напрямую, без вычислений и контекстной логики. В Mapbox GL JS литералы используются как базовая форма описания свойств стиля.
К числу литералов относятся:
"#ff0000", "road",
"Arial"12, 0.5, 3true, false[1, 2, 3]Пример использования литералов в стиле слоя:
map.addLayer({
id: "roads",
type: "line",
source: "vector-source",
"source-layer": "transportation",
paint: {
"line-color": "#ff6600",
"line-width": 2
}
});
В этом случае свойства line-color и
line-width являются статическими. Они не зависят ни от
данных, ни от масштаба. Результат вычисляется один раз на этапе
применения стиля.
Литералы применяются там, где отсутствует необходимость в изменяемом поведении: фоновые цвета, базовая типографика, фиксированные отступы, декоративные элементы.
В выражениях Mapbox GL JS существует отдельная форма явного литерала,
оформляемая через оператор "literal". Он используется для
предотвращения интерпретации массива как выражения.
Структура:
["literal", value]
Пример:
"circle-color": ["literal", "#00ff00"]
Без "literal" массив может быть интерпретирован как
выражение, что изменит семантику. Это особенно критично при работе с
вложенными структурами.
Использование "literal" гарантирует, что значение
останется неизменным независимо от контекста вычисления.
В классическом смысле переменные отсутствуют, однако функционально их роль выполняют динамические источники данных, параметры состояния и системные атрибуты карты. Эти элементы выступают в роли контекстных переменных, влияющих на вычисление выражений.
Основные категории:
zoom)feature properties)feature-state)Каждая категория интегрируется в выражения через специальный синтаксис.
Уровень масштаба карты является одной из ключевых динамических
величин. Он доступен через выражение "zoom" и используется
для адаптивной стилизации.
Пример:
"line-width": [
"interpolate",
["linear"],
["zoom"],
5, 1,
10, 4,
15, 10
]
Здесь zoom выступает как переменная, определяющая
текущий уровень приближения. Значение line-width изменяется
непрерывно в зависимости от масштаба.
Такой подход заменяет традиционные условные конструкции и обеспечивает плавную интерполяцию.
Каждый объект в источнике данных Mapbox GL JS содержит набор свойств (properties), которые могут использоваться в выражениях как динамические переменные.
Доступ осуществляется через:
["get", "property_name"]
Пример:
"circle-color": ["get", "color"]
В этом случае значение цвета берётся непосредственно из GeoJSON или векторного источника.
Допустим, объект имеет структуру:
{
"type": "Feature",
"properties": {
"color": "#3366ff",
"priority": 3
}
}
Тогда стиль будет индивидуальным для каждого объекта.
Свойства могут участвовать в более сложных выражениях:
"circle-radius": [
"interpolate",
["linear"],
["get", "priority"],
1, 4,
5, 20
]
Здесь priority выступает как переменная, влияющая на
визуальное масштабирование.
Механизм feature-state представляет собой динамическое
хранилище состояния, которое может изменяться без пересоздания источника
данных.
Доступ:
["feature-state", "state_key"]
Пример:
"circle-opacity": [
"case",
["boolean", ["feature-state", "hover"], false],
1,
0.5
]
Здесь состояние hover функционирует как переменная,
управляющая прозрачностью.
Установка состояния выполняется программно:
map.setFeatureState(
{
source: "points",
id: 42
},
{
hover: true
}
);
Такая модель позволяет реализовывать интерактивность без пересоздания слоя и без изменения GeoJSON.
Переменные в Mapbox GL JS часто используются через условные конструкции:
["case", ...]["match", ...]Пример case:
"line-color": [
"case",
["==", ["get", "type"], "highway"],
"#ff0000",
"#999999"
]
Здесь type функционирует как переменная, определяющая
результат выбора.
Пример match:
"circle-color": [
"match",
["get", "category"],
"park", "#00ff00",
"water", "#0000ff",
"#cccccc"
]
Такие конструкции заменяют традиционные if-else и
switch.
В реальных стилях литералы и переменные используются совместно, образуя вычислительные цепочки.
Пример:
"line-opacity": [
"interpolate",
["linear"],
["zoom"],
0, 0.2,
10, ["get", "baseOpacity"],
15, 1
]
Здесь:
0.2 и 1 являются литераламиbaseOpacity является переменнойzoom является системной переменнойТакое сочетание позволяет формировать гибридные модели визуализации.
Mapbox GL JS строго типизирует значения в выражениях. Литералы должны соответствовать ожидаемому типу свойства слоя:
Несоответствие типов приводит к игнорированию свойства или ошибке компиляции стиля.
Пример некорректного использования:
"line-width": "large"
Корректный вариант:
"line-width": 5
или
"line-width": ["get", "width"]
Переменные могут участвовать во вложенных выражениях, формируя многоуровневую логику.
Пример:
"circle-radius": [
"interpolate",
["linear"],
["zoom"],
5,
["*", ["get", "importance"], 2],
10,
["*", ["get", "importance"], 5]
]
Здесь значение радиуса зависит одновременно от масштаба и атрибута объекта.
Такие конструкции превращают стиль в декларативную вычислительную модель.
Литералы принадлежат статическому контексту стиля. Они вычисляются один раз при загрузке слоя.
Переменные принадлежат динамическому контексту. Их значения могут изменяться:
Это разделение формирует основу архитектуры рендеринга Mapbox GL JS.
Чрезмерное использование динамических выражений увеличивает нагрузку на GPU и CPU. Литералы остаются наиболее дешёвым с точки зрения вычислений вариантом.
Оптимизационный принцип:
Пример неэффективного подхода:
"line-color": ["get", "staticColor"]
если значение никогда не меняется.
В таком случае предпочтительнее:
"line-color": "#3366ff"
Система стилей Mapbox GL JS фактически представляет собой декларативный язык, где литералы задают константную основу, а переменные формируют адаптивное поведение.
Взаимодействие этих элементов формирует три уровня:
Такая структура позволяет описывать сложные визуальные сцены без императивного кода, сохраняя предсказуемость и масштабируемость стилей.