【问题标题】:Dashed line animations in Mapbox GL JSMapbox GL JS 中的虚线动画
【发布时间】:2017-03-27 22:26:11
【问题描述】:

有没有办法在 Mapbox 中使用 LineString 执行类似的操作?

【问题讨论】:

    标签: mapbox-gl-js


    【解决方案1】:

    这是我在setInterval 函数中使用Map#setPaintProperty(xx, 'line-dasharray', yy) 制作虚线动画的初步尝试。

    通过一些创意和数据预处理可以消除一些渲染伪影。

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset='utf-8' />
        <title></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.34.0/mapbox-gl.js'></script>
        <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.34.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.eyJ1IjoibHVjYXN3b2oiLCJhIjoiY2l5Nmg4cWU1MDA0ejMzcDJtNHJmZzJkcyJ9.WhcEdTYQH6sSw2pm0RSP9Q';
    var map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/mapbox/streets-v9',
        center: [-122.486052, 37.830348],
        zoom: 15
    });
    
    map.on('load', function () {
    
        map.addLayer({
            "id": "route",
            "type": "line",
            "source": {
                "type": "geojson",
                "data": {
                    "type": "Feature",
                    "properties": {},
                    "geometry": {
                        "type": "LineString",
                        "coordinates": [
                            [-122.48369693756104, 37.83381888486939],
                            [-122.48348236083984, 37.83317489144141],
                            [-122.48339653015138, 37.83270036637107],
                            [-122.48356819152832, 37.832056363179625],
                            [-122.48404026031496, 37.83114119107971],
                            [-122.48404026031496, 37.83049717427869],
                            [-122.48348236083984, 37.829920943955045],
                            [-122.48356819152832, 37.82954808664175],
                            [-122.48507022857666, 37.82944639795659],
                            [-122.48610019683838, 37.82880236636284],
                            [-122.48695850372314, 37.82931081282506],
                            [-122.48700141906738, 37.83080223556934],
                            [-122.48751640319824, 37.83168351665737],
                            [-122.48803138732912, 37.832158048267786],
                            [-122.48888969421387, 37.83297152392784],
                            [-122.48987674713133, 37.83263257682617],
                            [-122.49043464660643, 37.832937629287755],
                            [-122.49125003814696, 37.832429207817725],
                            [-122.49163627624512, 37.832564787218985],
                            [-122.49223709106445, 37.83337825839438],
                            [-122.49378204345702, 37.83368330777276]
                        ]
                    }
                }
            },
            "layout": {
                "line-join": "round",
                "line-cap": "butt"
            },
            "paint": {
                "line-color": "#888",
                "line-width": 8
            }
        });
      
        var dashLength = 1;
        var gapLength = 3;
     
        // We divide the animation up into 40 steps to make careful use of the finite space in
        // LineAtlas
        var steps = 40;
        // A # of steps proportional to the dashLength are devoted to manipulating the dash
        var dashSteps = steps * dashLength / (gapLength + dashLength);
        // A # of steps proportional to the gapLength are devoted to manipulating the gap
        var gapSteps = steps - dashSteps;
      
        // The current step #
        var step = 0;
      
        setInterval(function() {
            step = step + 1;
            if (step >= steps) step = 0;
        
            var t, a, b, c, d;
            if (step < dashSteps) {
              t = step / dashSteps;
              a = (1 - t) * dashLength;
              b = gapLength;
              c = t * dashLength;
              d = 0;
            } else {
              t = (step - dashSteps) / (gapSteps);
              a = 0;
              b = (1 - t) * gapLength;
              c = dashLength;
              d = t * gapLength;          
            }
            
            map.setPaintProperty("route", "line-dasharray", [a, b, c, d]);
        }, 25);
    });
    </script>
    
    </body>
    </html>

    【讨论】:

    • 如何定义方向?还是随机的?不幸的是,如果出于任何原因将“line-cap”设置为四舍五入,脚本就会崩溃。
    • 我刚刚想出了如何反转方向。我以不同的顺序排列字母:[d, c, b, a] 并且它起作用了:) 但是对于一些 LineStrings,CPU 负载非常高,达到 100%。有办法减少吗?
    • 对于发现此问题的任何人,此解决方案都很棒,但由于地图重新渲染而导致 CPU 使用率很高。我在我的网站中使用过它,但由于网站性能不佳而不得不将其删除...
    • 为了获得更好的性能,请利用 requestAnimationFrame 而不是 setTimeout。
    【解决方案2】:

    我在这个jsfiddle中准备了一个简单的动画:

    https://jsfiddle.net/2mws8y3q/

    var animationStep = 50;
    var step = 0;
    let dashArraySeq = [
        [0, 4, 3],
        [1, 4, 2],
        [2, 4, 1],
        [3, 4, 0],
        [0, 1, 3, 3],
        [0, 2, 3, 2],
        [0, 3, 3, 1]
    ];
    setInterval(() => {
      step = (step + 1) % dashArraySeq.length;
      map.setPaintProperty(layerId, 'line-dasharray', dashArraySeq[step]);
    }, animationStep);
    

    【讨论】:

      【解决方案3】:

      不直接。我能想到的最接近的是将line-dasharray 设置为10,5,0 之类的东西,然后稍后再将其更改为9,5,1,然后是8,5,2 等。

      不过,我还没有尝试过。它可能会以一种看起来不太好的奇怪方式重绘。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-26
        • 2016-06-05
        • 2020-07-17
        • 2017-04-24
        • 1970-01-01
        • 2022-11-17
        相关资源
        最近更新 更多