如何设置Mapbox上每个坐标的标记动画



我正在使用mapbox绘制,并尝试将标记设置为每个坐标的动画,这是我用来获取坐标的代码。

map.on('draw.modechange', function(e) { 
map.on('click', function(e) {
if (draw.getMode() == 'draw_polygon') {
lon = e.lngLat.lng;
lat = e.lngLat.lat;
//var gps = {};
//var gps = JSON.stringify(e.lngLat.wrap());
var marker = new mapboxgl.Marker();
function animateMarker(timestamp) {
var radius = 20;

marker.setLngLat([lon,lat]);
marker.addTo(map);

requestAnimationFrame(animateMarker);
}
requestAnimationFrame(animateMarker);
};
});
});

这是我制作的代码,用于将标记动画化到每个坐标,我点击了地图上的一个标记,但我试图将标记动画化成移动到我点击的每个点,这就是我添加按钮的原因。

var marker = new mapboxgl.Marker();
function animateMarker(timestamp) 
{
var radius = 20;
marker.setLngLat([lon,lat]);
marker.addTo(map);
requestAnimationFrame(animateMarker);
}
requestAnimationFrame(animateMarker);

修改后的代码我添加了一个带有onclick功能的按钮

<button id="anim" onclick="animateMarker()">subimit</button>

您需要使用TurfJS(https://turfjs.org/)并请求AnimationFrame。我是这样做的。但是在这个代码中,一个新的动画在前一个动画结束之前不能开始。你可以试着自己解决这个问题。

首先,你需要在第一次点击后添加一个标记源和标记对象,如下所示:

map.on('click', function(event) {
map.addSource('point_source', {
'type': 'geojson',
'data': {
'type': 'Point',
'coordinates': [event.lngLat.lng, event.lngLat.lat]
}
});
map.addLayer({
'id': 'point',
'source': 'point_source',
'type': 'circle',
'paint': {
'circle-radius': 10,
'circle-color': '#007cbf'
}
});
);

在此之后,您可以使用回调函数调用requestAnimationFrame,该函数将标记设置为动画并进行递归。回调方法传递一个参数,该参数指示页面加载后的当前时间。在回调时使用Turf.along,它获取一个LineString,并在沿线指定距离处返回一个Point,并将其设置为mapboxSource对象。对于指定的距离,可以使用传递的参数(在页面加载时间之后(,对于LineString,可以使用起点和终点。

var start_data = null;
var destination_data = null;
var start_time = null;
function animateMarker(tm) {
if(start_time === null) {
start_time = tm;
}

var speed = 2; //change this for make animation faster of slower
distance = (tm - start_time) / speed;
var newPoint = turf.along(turf.lineString([start_data.coordinates,destination_data.coordinates]), distance);
if(!(newPoint.geometry.coordinates == destination_data.coordinates)){
//set new position and do recursion
map.getSource('point_source').setData(newPoint);
requestAnimationFrame(animateMarker);
} else {
start_time = null;
}
}

这是我的完整代码。不要忘记粘贴您的accessToken。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Animate a point</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.8.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.8.1/mapbox-gl.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/Turf.js/5.1.5/turf.js" integrity="sha256-YcmHZHyXpKYagiKb3z5qKGALna6dDVK4NP+4GTOzh6k=" crossorigin="anonymous"></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
mapboxgl.accessToken = '*API_KEY*';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [0, 0],
zoom: 2
});
var start_data = null;
var current_data = null;
var destination_data = null;
var start_time = null;
var isAnimated = false;
function getPointData(lngLat) {
return {
'type': 'Point',
'coordinates': [lngLat.lng, lngLat.lat]
};
}
function animateMarker(tm) {
if(start_time === null) {
start_time = tm;
}
zero_time = tm - start_time;
var newPoint = turf.along(turf.lineString([start_data.coordinates,destination_data.coordinates]), (zero_time / 2));
if(!(newPoint.geometry.coordinates == destination_data.coordinates)){
current_data = newPoint.geometry;
map.getSource('point_source').setData(newPoint);
requestAnimationFrame(animateMarker);
} else {
isAnimated = false;
start_time = null;
}
}
map.on('click', function(event) {
var coordsClick = getPointData(event.lngLat);
if(map.getSource('point_source') && !isAnimated){
isAnimated = true;
start_data = current_data;
destination_data = coordsClick;
requestAnimationFrame(animateMarker);
}
if(map.getSource('point_source') === undefined) {
current_data = coordsClick;
destination_data = coordsClick;
map.addSource('point_source', {
'type': 'geojson',
'data': coordsClick
});
map.addLayer({
'id': 'point',
'source': 'point_source',
'type': 'circle',
'paint': {
'circle-radius': 10,
'circle-color': '#007cbf'
}
});
}
})
</script>
</body>
</html>

最新更新