iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
0
Modern Web

《你的地圖會說話? WebGIS與JavaScript的情感交織》系列 第 24

[8-3] 讓Marker動起來! 實作Leaflet.MovingMarker與bouncemarker

本系列文章已出版實體書籍:
「你的地圖會說話?WebGIS 與 JavaScript 的情感交織」(博碩文化)
WebGIS啟蒙首選✖五家地圖API✖近百個程式範例✖實用簡易口訣✖學習難度分級✖補充ES6小知識


本系列文章為Leaflet Plugins介紹:
[8-1] 展點多到爆?那就試試看 Leaflet MarkerCluster吧!
[8-2] heatmap.js 熱區- 以Leaflet地圖實作


今天要來介紹幾個有趣的Leaflet Plugins的套件!
除了快速使用的程式碼供參考外,
每個範例都有一小段gif圖可以看呦!

前置作業: 初始化地圖

↓ 引入leaflet的css與js

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>

↓ 建立一個存放地圖的div

    <div id="lmap"></div>

↓ css讓地圖滿板

    <style>
        html,
        body {
            padding: 0;
            margin: 0;
            height: 100%;
        }

        #lmap {
            height: 100%;
        }
    </style>

↓ 初始化地圖

        const LMap = L.map(document.getElementById('lmap'), {
            center: [23.5, 121],
            zoom: 7,
            crs: L.CRS.EPSG3857,
        });
        L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
            maxZoom: 18,
            id: 'mapbox.streets'
        }).addTo(LMap);

https://ithelp.ithome.com.tw/upload/images/20201009/201306042ZcepLjv1a.jpg

Leaflet.fullscreen

先來小試身手。
相信大家都有把地圖用iframe到網頁裡的經驗,或是說地圖本身不是滿板的時候,
想要用全螢幕觀看時,只要使用Leaflet.fullscreen就可以自由切換全螢幕模式啦!

↓ 引入leaflet.fullscreen的css與js

<script src='https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/Leaflet.fullscreen.min.js'></script>
<link href='https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/leaflet.fullscreen.css'
        rel='stylesheet' />

有兩種方式可以讓地圖加入全螢幕按鈕

方式一、初始化地圖時加入設定fullscreenControl: true

        const LMap = L.map(document.getElementById('lmap'), {
            center: [23.5, 121],
            zoom: 7,
            crs: L.CRS.EPSG3857,
            fullscreenControl: true,
        });

方式二、為地圖加入全螢幕的控制項

        LMap.addControl(new L.Control.Fullscreen());

↓ 全螢幕
圖片

bouncemarker

想要讓你的地圖活起來?想讓你的marker不再是死綁綁的而是會跳動?
那就試試bouncemarker吧!

↓ 引入bouncemarker.js

<script src="http://maximeh.github.io/leaflet.bouncemarker/bouncemarker.js"></script>

↓ 在Marker建立時加入屬性bounceOnAdd及bounceOnAddOptions

        const marker = new L.Marker([23.5, 121], {
            bounceOnAdd: true,
            bounceOnAddOptions: { duration: 1500, height: 200, loop: 10 }
        }).addTo(LMap);

bouncemarker設定

  • bounceOnAdd: 標記點建立時是否彈跳,預設為false。
  • bounceOnAddOptions: 彈跳設定
  • bounceOnAddCallback: 彈跳結束後的回調函式

↓ 結果,marker建立時變成會彈跳進場了!
圖片

↓ 也可以讓marker點擊時彈跳

        marker.on('click', function () {
            marker.bounce({ duration: 500, height: 200, loop: 10 });
        });

bounce彈跳設定(bounceOnAddOptions)

  • duration: 彈跳時間(毫秒),預設為1000毫秒(1秒)
  • height: 彈跳高度,預設從y座標最高處開始落下
  • loop: 動畫重複播放次數,預設為1次

↓ 點擊示範
圖片

Leaflet.MovingMarker

Marker: 「我會彈跳還不夠!我還要會動!」
就讓我們用Leaflet.MovingMarker來完成Marker的心願吧!

↓ 引入MovingMarker.js

<script src="http://ewoken.github.io/Leaflet.MovingMarker/MovingMarker.js"></script>

↓ 等會兒MovingMarker要使用的路徑格式為一個二維陣列

        // 移動路徑的格式
        const route = [[23, 120.3508], [25.15, 121.523333]];

↓ 為了取得移動路徑,為地圖建立一個click事件,點擊地圖後加入arr做為等等要移動的路徑。

        let arr = [];
        LMap.on('click', function (e) {
            arr.push([e.latlng.lat, e.latlng.lng])
        });

↓ 點擊地圖建立路徑
https://ithelp.ithome.com.tw/upload/images/20201009/20130604Pd5sN0WzJQ.jpg

↓ 新增一個Move函式,傳入要移動的路徑,

        function Move(arr) {
            const marker = L.Marker.movingMarker(arr,
                [1000, 3000, 500, 100], { autostart: true }).addTo(LMap);
            L.polyline(arr, { color: 'red' }).addTo(LMap);
            LMap.fitBounds(arr);

            // 移動結束時觸發事件
            marker.on('end', function () {
                marker.bindPopup('<p>環島結束囉!</p>', { closeOnClick: false }).openPopup();
            });
        }

movingMarker參數

  1. latlngs: 移動路徑的二維陣列
  2. durations: 每段路徑移動的時間,格式為陣列,單位毫秒
  3. Options: 詳見下方Options

Options

  • autostart: 若為true時,當標記點加入地圖後自動開始移動,預設為false。
  • loop: 若為true時,標記點到達終點後會自動回到起點,重複播放,預設為false。

movingMarker事件

  • start: 於起點開始移動時觸發
  • end: 到達終點時觸發
  • loop: 每次循環開始時觸發

↓ 呼叫

        Move(arr);

↓ 環島路線
圖片

我們也可以讓marker由事件來觸發,點擊後才開始移動。

↓ 建立一個會移動的marker

        const route = [[23, 120.3508], [25.15, 121.523333]];
        const marker = L.Marker.movingMarker(route, [4000]).addTo(LMap);
        L.polyline(route).addTo(LMap);

↓ 外層給它一次性的點擊事件,讓marker開始移動,並且內層在綁定事件,讓每次點擊可以讓它暫停或是繼續移動。

        marker.once('click', function () {
            marker.start();
            marker.on('click', function () {
                if (marker.isRunning()) {
                    marker.pause();
                } else {
                    marker.start();
                }
            });
        });

marker.isRunning()可以判斷標記點是否正在移動中

↓ 點擊之後開始移動!
圖片

↓ 再次點擊可以停止或繼續移動
圖片


GIS除了空間分析外,還有一個重要的環節就是把資料視覺化,
讓決策者一目了然,並且採取最佳的決策。

今天介紹了Leaflet Plugins的幾個套件,
把它們活用後,建立出來的地圖會更加生動有活力!
現在就讓我們加入這些元素,讓地圖的Marker通通會動!/images/emoticon/emoticon62.gif
讓地圖活起來吧!/images/emoticon/emoticon37.gif


上一篇
[8-2] heatmap.js 熱區- 以Leaflet地圖實作
下一篇
[Vue2Leaflet系列一] 從vue-cli安裝到建置地圖
系列文
《你的地圖會說話? WebGIS與JavaScript的情感交織》30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言