在MapBox中的两个标记之间绘制线性动画线

时间:2018-10-23 06:17:21

标签: javascript mapbox mapbox-gl react-map-gl mapbox-gl-draw

我在mapbox上没有看到动画线的示例,但是我还没有找到在两个点之间创建线性线的示例。我可以在地图上创建标记,也可以在这些标记之间画一条线。但是,我想慢慢地从起点(起点)到终点(终点)创建那条线。这是在两个坐标之间画线的代码。我只是想慢慢地(动画地)制作它,然后重复该动画。

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title>Animate a line</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
    #route {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  animation: dash 1s linear alternate infinite;
}

@keyframes dash {
  from {
    stroke-dashoffset: 1000;
  }
  to {
    stroke-dashoffset: 0;
  }
}
    </style>
</head>
<body>

<div id='map'></div>
<script>
mapboxgl.accessToken =
  "pk.eyJ1IjoiaHllb25namlua2ltIiwiYSI6ImNpZXh4dXp5eDA2YjFzaGtyOGR2dnBza2oifQ.a5K673tSr0cOcYoX1rpPhg";

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v9',
    center: [-122.486052, 37.830348],
    zoom: 5
});

map.on('load', function () {

    map.addLayer({
        "id": "route",
        "type": "line",

        "source": {
            "type": "geojson",
            "data": {
                "type": "Feature",
                "properties": {},
                "geometry": {
                    "type": "LineString",
                    "coordinates": [
                        [-122.414, 37.776],
                        [-77.032, 38.913]
                    ]
                }
            }
        }
    });

});
</script>

</body>
</html>

1 个答案:

答案 0 :(得分:0)

这是用于计算源和目标之间的点(纬度,经度),然后在这两个点之间创建动画的完整代码。

<!DOCTYPE html>
<html>

  <head>
    <meta charset='utf-8' />
    <title>Animate a line</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css' rel='stylesheet' />
    <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 = 'pk.eyJ1IjoiYWhtZWRraGFuMTAzOSIsImEiOiJjam5iZDgwejYwMnlpM3FyNzJvMDZhZHdoIn0.pcOWSRI2xzY_oMX0mVsLjg';
      var map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/mapbox/dark-v9',
        center: [0.11256, 52.201733],
        zoom: 15
      });

      // Create a GeoJSON source with an empty lineString.
      var geojson = {
        "type": "FeatureCollection",
        "features": [{
          "type": "Feature",
          "geometry": {
            "type": "LineString",
            "coordinates": []
          }
        }]
      };

      var startPoint = [0.108266, 52.202758];
      var endPoint = [0.11556, 52.201733];

      var framesPerSecond = 20;
      var initialOpacity = 1
      var opacity = initialOpacity;
      var initialRadius = 4;
      var radius = initialRadius;
      var maxRadius = 15;

      var speedFactor = 100 // number of frames per longitude degree
      var animation; // to store and cancel the animation

      map.on('load', function() {

        // Point 1
        map.addSource('point1', {
          "type": "geojson",
          "data": {
            "type": "Point",
            "coordinates": [
              startPoint[0], startPoint[1]
            ]
          }
        });
        map.addLayer({
          "id": "circle1",
          "source": "point1",
          "type": "circle",
          "paint": {
            "circle-radius": initialRadius,
            "circle-radius-transition": {
              duration: 0
            },
            "circle-opacity-transition": {
              duration: 0
            },
            "circle-color": "#007cbf"
          }
        });
        map.addLayer({
          "id": "point1",
          "source": "point1",
          "type": "circle",
          "paint": {
            "circle-radius": initialRadius,
            "circle-color": "#007cbf"
          }
        });

        // Point 2
        map.addSource('point2', {
          "type": "geojson",
          "data": {
            "type": "Point",
            "coordinates": [
              endPoint[0], endPoint[1]
            ]
          }
        });
        map.addLayer({
          "id": "circle2",
          "source": "point2",
          "type": "circle",
          "paint": {
            "circle-radius": initialRadius,
            "circle-radius-transition": {
              duration: 0
            },
            "circle-opacity-transition": {
              duration: 0
            },
            "circle-color": "#007cbf"
          }
        });
        map.addLayer({
          "id": "point2",
          "source": "point2",
          "type": "circle",
          "paint": {
            "circle-radius": initialRadius,
            "circle-color": "#007cbf"
          }
        });

        //Line
        map.addLayer({
          'id': 'line-animation',
          'type': 'line',
          'source': {
            'type': 'geojson',
            'data': geojson
          },
          'layout': {
            'line-cap': 'round',
            'line-join': 'round'
          },
          'paint': {
            'line-color': '#ffffff',
            'line-width': 2
          }
        });

        var diffX = endPoint[0] - startPoint[0];
        var diffY = endPoint[1] - startPoint[1];

        var sfX = diffX / speedFactor;
        var sfY = diffY / speedFactor;

        var i = 0;
        var j = 0;

        var lineCoordinates = [];

        while (i < diffX || Math.abs(j) < Math.abs(diffY)) {
          lineCoordinates.push([startPoint[0] + i, startPoint[1] + j]);

          if (i < diffX) {
            i += sfX;
          }

          if (Math.abs(j) < Math.abs(diffY)) {
            j += sfY;
          }
        }

        console.log(lineCoordinates);

        var animationCounter = 0;

        function animateLine() {
          if (animationCounter < lineCoordinates.length) {
            geojson.features[0].geometry.coordinates.push(lineCoordinates[animationCounter]);
            map.getSource('line-animation').setData(geojson);

            requestAnimationFrame(animateLine);
            animationCounter++;
          } else {
            var coord = geojson.features[0].geometry.coordinates;
            coord.shift();
            console.log(coord);

            if (coord.length > 0) {
              geojson.features[0].geometry.coordinates = coord;
              map.getSource('line-animation').setData(geojson);

              //-------------- Point2 Animation End ---------------
              requestAnimationFrame(animateLine);
            }
          }

        }

        animateLine();


      });

    </script>

  </body>

</html>