我正在使用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/)和requestAnimationFrame。
我是这样的但是在这段代码中,新动画直到上一个动画结束才开始。您可以尝试自己解决此问题。

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

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并将其设置为mapbox Source对象。对于指定的距离,您可以使用传递的参数(在页面加载时间之后),对于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>

关于javascript - 如何为Mapbox上的每个坐标设置标记动画?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60466142/

10-11 12:43
查看更多