效果图

<!DOCTYPE html>
<html lang="zh" style="width: 100%; height: 100%;margin: 0;padding: 0">
<head>
<meta charset="UTF-8">
<title>mapbox管线流动</title>
<!-- mapbox-->
<script src='https://api.mapbox.com/mapbox-gl-js/v2.4.1/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v2.4.1/mapbox-gl.css' rel='stylesheet' />
<!-- turf-->
<script src='https://unpkg.com/@turf/turf@6/turf.min.js'></script>
</head>
<body style="width: 100%; height: 100%;margin: 0;padding: 0">
<div id="map" style="width: 100%; height: 100%;"></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiZXRlcm5pdHkteHlmIiwiYSI6ImNqaDFsdXIxdTA1ODgycXJ5czdjNmF0ZTkifQ.zN7e588TqZOQMWfws-K0Yw';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/satellite-streets-v11',
zoom: 15.6,
center: [114.18088588361525, 30.55405768340087]
})
map.on('load',()=>{
// 改变颜色实现流向
const loadRouteLayerByChangeColor = points => {
// 添加数据源
map.addSource('routeSource', {
type: 'geojson',
lineMetrics: true,
data: {
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: points
},
properties: {}
}
})
// 添加外轮廓的线
map.addLayer({
id: 'outerRouteLayer',
source: 'routeSource',
type: 'line',
layout: {
visibility: 'visible',
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': '#ffffff',
'line-width': 4
}
})
// 创建一条线
const lineCount = turf.lineString(points)
// 分割线段
const chunk = turf.lineChunk(lineCount, 0.02, { units: 'kilometers' })
// 绘制渐变的线
const chunkSourceData = {
type: 'FeatureCollection',
features: []
}
map.addSource('chunkSource', {
type: 'geojson',
lineMetrics: true, // 线渐变必须条件
data: chunkSourceData
})
map.addLayer({
id: 'chunkLayer',
source: 'chunkSource',
type: 'line',
layout: {
visibility: 'visible',
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': ['get', 'color'],
'line-width': 3
}
})
let colorNum = 0
const colorList = ['red', 'rgba(255,255,255,0)', 'blue', 'rgba(255,255,255,0)', 'green', 'rgba(255,255,255,0)']
for (let i = 0; i < chunk.features.length; i++) {
chunk.features[i].properties.color = colorList[i % 6]
chunkSourceData.features.push({
type: 'Feature',
geometry: chunk.features[i].geometry,
properties: {
name: `chunk_line_${i}`,
color: colorList[i % 6]
}
})
}
map.getSource('chunkSource').setData(chunkSourceData)
// 定时器动态修改线的颜色
setInterval(() => {
colorNum++
for (let i = 0; i < chunkSourceData.features.length; i++) {
const countNumShow = colorNum % 6
const pageNum = i % 6
const totalNum = pageNum - countNumShow
if (totalNum <= 0) {
chunkSourceData.features[i].properties.color = colorList[5 - Math.abs(totalNum)]
}
if (totalNum > 0) {
chunkSourceData.features[i].properties.color = colorList[totalNum - 1]
}
}
map.getSource('chunkSource').setData(chunkSourceData)
// 触发一个显示框的渲染。使用自定义图层时,当图层发生改变,使用此方法去重渲染。在下一个显示框渲染前多次调用此方法也只会渲染一次
map.triggerRepaint()
}, 300)
}
loadRouteLayerByChangeColor([[114.17074370960319, 30.55753403888717], [114.17365645694883, 30.553236257578007], [114.17810131301661, 30.55236780983222]])
// -------------------------
// 改变geometry实现流向
const loadRouteLayerByChangeGeometry = points => {
// 创建一条线
const lineCount = turf.lineString(points)
// 添加数据源
map.addSource('outerRouteLayer2', {
type: 'geojson',
data: lineCount
})
// 添加外轮廓的线
map.addLayer({
id: 'outerRouteLayer2',
source: 'outerRouteLayer2',
type: 'line',
layout: {
visibility: 'visible',
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': '#ffffff',
'line-width': 4
}
})
const sourceData = {
type: 'FeatureCollection',
features: []
}
// 添加数据源
map.addSource('routeSource2', {
type: 'geojson',
lineMetrics: true,
data: sourceData
})
// 添加线图层
map.addLayer({
id: 'routeLayer2',
source: 'routeSource2',
type: 'line',
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': 'red',
'line-width': 5,
// "line-dasharray": [10,1000],
'line-gradient': [
'interpolate',
['linear'],
['line-progress'],
0,
'blue',
0.1,
'royalblue',
0.3,
'cyan',
0.5,
'lime',
0.7,
'yellow',
1,
'red'
]
}
})
// 分割线段
const chunk = turf.lineChunk(lineCount, 0.02, { units: 'kilometers' })
const offsetPointCount = 3
let offsetIndex = 0
// 定时器动态修改线的颜色
setInterval(() => {
sourceData.features = chunk.features.slice(offsetIndex, chunk.features.length - offsetPointCount + offsetIndex)
map.getSource('routeSource2').setData(sourceData)
offsetIndex += 1
if(offsetIndex>offsetPointCount){
offsetIndex = 0
}
}, 300)
}
loadRouteLayerByChangeGeometry([[114.18074370960319, 30.55753403888717], [114.18365645694883, 30.553236257578007], [114.18810131301661, 30.55236780983222]])
})
</script>
</body>
</html>