Градиентные и визуальные эффекты в HERE Maps JavaScript API формируют слой восприятия поверх географических данных, позволяя переходить от строгой картографической геометрии к выразительным визуализациям. Векторная модель карты, слоистая архитектура и поддержка пользовательских оверлеев дают возможность комбинировать нативные стили платформы с программно создаваемыми эффектами на Canvas и WebGL.
В HERE Maps API основа визуального представления строится на объекте карты:
const platform = new H.service.Platform({
apikey: 'YOUR_API_KEY'
});
const layers = platform.createDefaultLayers();
const map = new H.Map(
document.getElementById('mapContainer'),
layers.vector.normal.map,
{
center: { lat: 50.4501, lng: 30.5234 },
zoom: 10,
pixelRatio: window.devicePixelRatio
}
);
Система рендеринга разделяет:
Именно пользовательские слои позволяют реализовывать градиенты и эффекты, выходящие за рамки стандартного стиля.
Векторные тайлы HERE поддерживают стилевые выражения, где цвет может задаваться через интерполяцию значений.
Типичный подход — использование шкалы значений:
const style = {
layers: {
'water': {
fillColor: '#a0d8ef'
},
'road': {
color: [
'interpolate',
['linear'],
['zoom'],
5, '#cccccc',
10, '#888888',
15, '#444444'
]
}
}
};
Ключевой механизм — интерполяция:
linear) — плавный переход,step) — резкие переходы.Градиент здесь применяется не как CSS-градиент, а как функция зависимости цвета от масштаба или атрибутов объекта.
Для более гибких эффектов используется слой Canvas:
const canvasLayer = new H.map.layer.CanvasLayer(function (ctx, renderParams) {
const canvas = ctx.canvas;
const width = canvas.width;
const height = canvas.height;
const gradient = ctx.createLinearGradient(0, 0, width, 0);
gradient.addColorStop(0, 'rgba(0, 150, 255, 0.2)');
gradient.addColorStop(1, 'rgba(0, 50, 200, 0.6)');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width, height);
});
map.addLayer(canvasLayer);
Характерные сценарии:
Линейные градиенты часто применяются как фон для аналитических визуализаций.
Радиальные градиенты используются для выделения центральных точек интереса:
const radialLayer = new H.map.layer.CanvasLayer(function (ctx) {
const centerX = ctx.canvas.width / 2;
const centerY = ctx.canvas.height / 2;
const gradient = ctx.createRadialGradient(
centerX, centerY, 10,
centerX, centerY, 300
);
gradient.addColorStop(0, 'rgba(255, 200, 0, 0.5)');
gradient.addColorStop(1, 'rgba(255, 200, 0, 0)');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
});
map.addLayer(radialLayer);
Такие эффекты используются для:
Полилинии в HERE Maps стандартно имеют один цвет, но градиент реализуется через разбиение линии на сегменты.
const points = [
{ lat: 50.45, lng: 30.52 },
{ lat: 50.46, lng: 30.53 },
{ lat: 50.47, lng: 30.55 }
];
for (let i = 0; i < points.length - 1; i++) {
const segment = new H.map.Polyline(
new H.geo.LineString().pushPoint(points[i]).pushPoint(points[i + 1]),
{
style: {
strokeColor: `rgba(0, 100, 255, ${i / points.length})`,
lineWidth: 5
}
}
);
map.addObject(segment);
}
Более сложный вариант — вычисление цветовой шкалы по скорости, высоте или времени.
Heatmap — один из наиболее прямых способов отображения градиента плотности данных.
const dataPoints = [
{ lat: 50.45, lng: 30.52, value: 10 },
{ lat: 50.46, lng: 30.53, value: 30 },
{ lat: 50.47, lng: 30.55, value: 80 }
];
const heatmapProvider = new H.data.heatmap.Provider({
colors: new H.data.heatmap.Colors({
'0': 'blue',
'0.5': 'yellow',
'1': 'red'
})
});
dataPoints.forEach(p => {
heatmapProvider.addDataPoint(p.lat, p.lng, p.value);
});
const heatmapLayer = new H.map.layer.TileLayer(heatmapProvider);
map.addLayer(heatmapLayer);
Ключевые параметры:
Heatmap фактически является динамическим радиальным градиентом, наложенным на множество точек.
Маркерные эффекты часто реализуются через SVG или Canvas-иконки.
const svg = `
<svg width="40" height="40">
<defs>
<radialGradient id="grad">
<stop offset="0%" stop-color="red"/>
<stop offset="100%" stop-color="transparent"/>
</radialGradient>
</defs>
<circle cx="20" cy="20" r="15" fill="url(#grad)"/>
</svg>
`;
const icon = new H.map.Icon(svg);
const marker = new H.map.Marker(
{ lat: 50.45, lng: 30.52 },
{ icon }
);
map.addObject(marker);
Такие маркеры применяются для:
Эффекты часто строятся на изменении alpha-канала:
const circle = new H.map.Circle(
{ lat: 50.45, lng: 30.52 },
1000,
{
style: {
fillColor: 'rgba(0, 150, 255, 0.2)',
strokeColor: 'rgba(0, 150, 255, 0.8)',
lineWidth: 2
}
}
);
map.addObject(circle);
Комбинация прозрачностей позволяет:
Динамика достигается через перерисовку Canvas слоя:
let alpha = 0;
let direction = 1;
const animatedLayer = new H.map.layer.CanvasLayer(function (ctx) {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
const gradient = ctx.createRadialGradient(
200, 200, 10,
200, 200, 150
);
gradient.addColorStop(0, `rgba(0, 200, 255, ${alpha})`);
gradient.addColorStop(1, 'rgba(0, 200, 255, 0)');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
});
setInterval(() => {
alpha += 0.02 * direction;
if (alpha >= 0.6 || alpha <= 0.1) {
direction *= -1;
}
animatedLayer.getProvider().refresh();
}, 50);
map.addLayer(animatedLayer);
Анимационные градиенты применяются для:
Сложные визуализации строятся как стек слоёв:
Порядок наложения критичен, так как влияет на читаемость данных.
Градиентные эффекты чувствительны к нагрузке GPU и CPU:
Практика оптимизации:
requestAnimationFrame вместо
setInterval),