Цветовые градиенты в Mapbox GL JS строятся на основе системы выражений (expressions), которая позволяет вычислять визуальные свойства динамически, в зависимости от данных, масштаба и других параметров карты. Градиенты применяются не как статическая заливка, а как функция интерполяции между значениями, что обеспечивает плавные переходы цвета на линиях, полигонах, тепловых слоях и 3D-объектах.
Основой градиентных эффектов в Mapbox GL JS являются свойства
paint, поддерживающие выражения interpolate,
step, match, а также специализированные
параметры вроде line-gradient и
heatmap-color.
Градиенты в Mapbox GL JS почти всегда опираются на интерполяцию числовых значений в цветовое пространство.
interpolatey = interpolate(linear, x, x_0, c_0, x_1, c_1, )
Функция interpolate принимает входное значение
(например, плотность объектов, zoom или высоту) и преобразует его в
цвет, плавно переходя между контрольными точками.
Пример использования:
map.setPaintProperty('layer-id', 'fill-color', [
'interpolate',
['linear'],
['get', 'value'],
0, '#2DC4B2',
50, '#3BB3C3',
100, '#669EC4',
200, '#8B88B6',
300, '#A2719B'
]);
Здесь значение value из данных управляет цветом
полигона, создавая непрерывный градиент.
Одним из наиболее мощных инструментов является свойство
line-gradient, которое позволяет создавать градиент вдоль
геометрии линии, а не только на основе атрибутов данных.
Для его работы требуется использование источника geojson
с параметром lineMetrics: true.
map.addSource('route', {
type: 'geojson',
lineMetrics: true,
data: {
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: [
[37.62, 55.75],
[37.64, 55.76],
[37.66, 55.77]
]
}
}
});
Далее применяется выражение:
map.addLayer({
id: 'route-line',
type: 'line',
source: 'route',
paint: {
'line-width': 6,
'line-gradient': [
'interpolate',
['linear'],
['line-progress'],
0, '#00c6ff',
1, '#0072ff'
]
}
});
Ключевой момент заключается в использовании
line-progress, который нормализует положение точки вдоль
линии от 0 до 1. Это позволяет создавать эффект “движущегося” или плавно
меняющегося цвета.
Heatmap-слои используют градиенты для отображения плотности точек. Здесь цвет зависит от “веса” и концентрации данных.
map.addLayer({
id: 'heat',
type: 'heatmap',
source: 'points',
paint: {
'heatmap-weight': ['get', 'weight'],
'heatmap-intensity': 1,
'heatmap-color': [
'interpolate',
['linear'],
['heatmap-density'],
0, 'rgba(33,102,172,0)',
0.2, 'rgb(103,169,207)',
0.4, 'rgb(209,229,240)',
0.6, 'rgb(253,219,199)',
0.8, 'rgb(239,138,98)',
1, 'rgb(178,24,43)'
],
'heatmap-radius': 20
}
});
Здесь heatmap-density автоматически вычисляется движком
Mapbox и нормализуется в диапазон от 0 до 1, что делает его идеальной
осью для градиентных интерполяций.
Помимо плавной интерполяции, применяются дискретные переходы.
'fill-color': [
'step',
['get', 'value'],
'#2DC4B2',
10, '#3BB3C3',
50, '#669EC4',
100, '#8B88B6'
]
step разбивает диапазон на зоны, каждая из которых имеет
фиксированный цвет, создавая “ступенчатый” градиент.
Используется для категориальных данных:
'circle-color': [
'match',
['get', 'type'],
'park', '#2DC4B2',
'water', '#3BB3C3',
'road', '#669EC4',
'#CCCCCC'
]
Хотя это не градиент в математическом смысле, комбинация большого числа категорий может имитировать сложные цветовые переходы.
Градиенты могут изменяться в зависимости от zoom, что позволяет визуализировать разные уровни детализации.
'fill-color': [
'interpolate',
['linear'],
['zoom'],
5, '#2DC4B2',
10, '#3BB3C3',
15, '#8B88B6'
]
Такой подход применяется для адаптации цветовой схемы под плотность отображаемых данных: на низком масштабе используются более обобщённые оттенки, на высоком — детализированные.
Mapbox GL JS поддерживает несколько типов интерполяции, влияющих на визуальное восприятие градиента:
['linear'] — равномерный переход['exponential', base] — ускоряющийся или замедляющийся
переход['cubic-bezier', x1, y1, x2, y2] — управляемая
криваяПример экспоненциальной интерполяции:
'fill-color': [
'interpolate',
['exponential', 2],
['get', 'value'],
0, '#2DC4B2',
100, '#8B88B6'
]
Экспонента усиливает различия в верхней части диапазона, что часто используется для данных с неравномерным распределением.
Сложные визуальные эффекты создаются за счёт наложения нескольких слоёв с различными градиентами.
Например:
'fill-opacity': 0.6,
'fill-outline-color': '#000'
Композиция слоёв позволяет создавать эффекты глубины, свечения и тепловой визуализации без использования постобработки.
Для fill-extrusion градиенты используются для передачи
высоты и плотности объектов.
'fill-extrusion-color': [
'interpolate',
['linear'],
['get', 'height'],
0, '#2DC4B2',
50, '#3BB3C3',
100, '#8B88B6'
]
Дополнительно применяется освещение:
'fill-extrusion-opacity': 0.8,
'fill-extrusion-height': ['get', 'height']
Цвет становится дополнительным измерением поверх геометрии, усиливая восприятие объёма.
Градиенты в Mapbox GL JS требуют нормализации входных данных. Без этого цветовые переходы становятся непропорциональными.
Типичная схема построения:
interpolateДля стабильных шкал часто используется логарифмическое преобразование:
genui{“math_block_widget_always_prefetch_v2”:{“content”:“y = (x + 1)”}}
Это позволяет сгладить влияние выбросов и сделать градиенты более читаемыми при больших разбросах значений.
Градиентные выражения вычисляются на GPU через стильный пайплайн Mapbox GL JS. Однако сложные выражения могут влиять на производительность.
К факторам нагрузки относятся:
interpolateget в выражениях на больших наборах
данныхОптимизация достигается за счёт: