核心代码:
// 开始动画
let lastTime = Date.now();
let distance = 0;
function moveFeature(event) {
const speed = 100;
const time = event.frameState.time;
const elapsedTime = time - lastTime;
distance = (distance + (speed * elapsedTime) / 1e6) % 2;
lastTime = time;
const currentCoordinate = polyline.getCoordinateAt(
distance > 1 ? 2 - distance : distance
);
position.setCoordinates(currentCoordinate);
const vectorContext = ol.render.getVectorContext(event);
vectorContext.setStyle(styles.geoMarker);
vectorContext.drawGeometry(position);
map.render();
}
vectorLayer.on('postrender', moveFeature);
完整代码:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>点沿线动画</title>
<!--
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/css/ol.css" type="text/css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
-->
<link rel="stylesheet" href="./js/ol.css" />
<script type="text/javascript" src="./js/ol.js"></script>
<style type="text/css">
html,
body,
#map {
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
</body>
<script type="text/javascript">
function transform(pois) {
return ol.proj.transform(pois, 'EPSG:4326', 'EPSG:3857')
}
var tileLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
})
});
var map = new ol.Map({
controls: [],
target: 'map',
layers: [tileLayer],
view: new ol.View({
center: transform([103.584297498027, 36.119086450265]),
zoom: 4,
})
});
// 线
var lineCoord = [
[79.78351732091059, 38.26132508806543],
[91.24445696667777, 40.75626733863021],
[95.39289017514336, 33.53665615186689],
[101.72101517514338, 38.866081722355915],
[106.7132069666778, 33.18429652688876],
[115.29132982091058, 36.190051824120644]
];
var polyline = new ol.geom.LineString(lineCoord);
polyline.transform('EPSG:4326', 'EPSG:3857');
const routeFeature = new ol.Feature({
type: 'route',
geometry: polyline,
});
const startMarker = new ol.Feature({
type: 'icon',
geometry: new ol.geom.Point(polyline.getFirstCoordinate()),
});
const endMarker = new ol.Feature({
type: 'icon',
geometry: new ol.geom.Point(polyline.getLastCoordinate()),
});
const position = startMarker.getGeometry().clone();
const geoMarker = new ol.Feature({
type: 'geoMarker',
geometry: position,
});
const styles = {
'route': new ol.style.Style({
stroke: new ol.style.Stroke({
width: 6,
color: [237, 212, 0, 0.8],
}),
}),
'icon': new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 1],
src: './summary/node_blue.gif',
}),
}),
'geoMarker': new ol.style.Style({
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: 'black'
}),
stroke: new ol.style.Stroke({
color: 'white',
width: 2,
}),
}),
}),
};
const vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: [routeFeature, geoMarker, startMarker, endMarker],
}),
style: (feature) => {
return styles[feature.get('type')];
},
})
map.addLayer(vectorLayer);
// 开始动画
let lastTime = Date.now();
let distance = 0;
function moveFeature(event) {
const speed = 100;
const time = event.frameState.time;
const elapsedTime = time - lastTime;
distance = (distance + (speed * elapsedTime) / 1e6) % 2;
lastTime = time;
const currentCoordinate = polyline.getCoordinateAt(
distance > 1 ? 2 - distance : distance
);
position.setCoordinates(currentCoordinate);
const vectorContext = ol.render.getVectorContext(event);
vectorContext.setStyle(styles.geoMarker);
vectorContext.drawGeometry(position);
map.render();
}
vectorLayer.on('postrender', moveFeature);
</script>
</html>