简体   繁体   中英

how to animate marker to every coordinates on Mapbox?

I am using mapbox draw and i am trying to animate the marker to every coordinates, this the code i am using to get coordinates.

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);

       };
    });
 });

This is the code i made to animate the marker to every coordinates and i clicked on the map and there is a marker but instead i am trying to to animate the marker to move to every point i clicked that's why i added an button.

   var marker = new mapboxgl.Marker();

              function animateMarker(timestamp) 
           {
              var radius = 20;

              marker.setLngLat([lon,lat]);

              marker.addTo(map);

              requestAnimationFrame(animateMarker);
            }

        requestAnimationFrame(animateMarker);

modified code i added a button with an onclick function

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

You need to use TurfJS ( https://turfjs.org/ ) and requestAnimationFrame. I do it like this. But in this code a new animation cannot start until the previous one ends. You can try fix this for yourself.

First of all, you need to add a marker source and marker object after first click like this:

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'
        }
    });
);

After this you call requestAnimationFrame with callback function that animate marker and make recursion. The callback method is passed a single argument which indicates the current time after page loaded. At callback use Turf.along, it takes a LineString and returns a Point at a specified distance along the line and set it to mapbox Source object. For the specified distance you can use passed argument (after page loaded time), for LineString use starting and destination points.

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;
    }

}

This is my full code. Don't forget paste your 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM