Google Maps API - 多個地圖標記
前一篇介紹了如何在地圖裡放入地圖標記 ( Marker ),這篇將透過 Google Maps API,做出地圖標記、標籤與動畫,甚至實現在地圖上放入多個標記,並且透過簡單的動畫依序載入這些標記。
放入多個地圖標記
如果有多個地圖標記,可以用個陣列來裝載對應的標籤、經緯度...等資訊,舉例來說,這裡使用一個名為 position 的陣列,將五個地圖標記的資訊用物件的方式放在裡頭,同時建立一個空的 markers 陣列,用這個陣列的內容來宣告一個個新的地圖標記。
在這裡有個比較需要注意的地方,就是addMarker(e)
這個 function,如果把這個 function 放在initMap()
的外面,會發生地圖還沒載入就執行addMarker(e)
而發生錯誤,所以要放在裡頭。
範例:放入多個地圖標記
var map;
var markers = [];
var position = [
{label:'A',lat:25.0336962,lng:121.5643673},
{label:'B',lat:25.0333698,lng:121.5641564},
{label:'C',lat:25.033899,lng:121.564329},
{label:'D',lat:25.0338407,lng:121.5645269},
{label:'E',lat:25.0336377,lng:121.5645727}
];
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 19,
center: {
lat: 25.0336962,
lng: 121.5643673
}
});
for (var i = 0; i < position.length; i++) {
addMarker(i);
}
}
function addMarker(e) {
markers[e] = new google.maps.Marker({
position: {
lat: position[e].lat,
lng: position[e].lng
},
map: map,
label: position[e].label
});
}
點擊按鈕,依序放入地圖標記
已經知道如何放入多個標記後,接著就來試著做個按鈕,搭配地圖標記的 DROP 動畫效果,就能在點擊按鈕的當下,讓地圖標記依序落下並且載入。
首先在 html 裡放入一個 button,撰寫一點 CSS 讓這個按鈕可以置中並且浮在地圖上方,同時用滑鼠按下去的時候,也可以透過active
來設定壓下去的感覺,此外在 HTML 的按鈕標籤裡,增加一個onclick
的事件,讓點擊按鈕的時候,執行go()
這個 function。
HTML
<button id="btn" onclick="go()">放置地圖標記</button>
CSS
#btn{
position:fixed;
z-index:99;
top:20px;
left:calc(50% - 150px);
font-size:30px;
width:80%;
max-width: 300px;
box-shadow:rgba(0,0,0,.5) 0 5px 10px;
border-radius: 5px;
padding:10px;
outline: none;
border:1px solid #999;
}
#btn:active{
box-shadow:rgba(0,0,0,.5) 0 3px 5px;
}
再來看到初始化地圖的程式,其實跟剛剛的程式一模一樣,差別只在於不要在一開始的時候不要先把地圖標記放進去。
var map;
var markers = [];
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 19,
center: {
lat: 25.0336962,
lng: 121.5643673
}
});
}
var position = [
{label:'A', lat:25.0336962, lng:121.5643673},
{label:'B', lat:25.0333698, lng:121.5641564},
{label:'C', lat:25.033899, lng:121.564329},
{label:'D', lat:25.0338407, lng:121.5645269},
{label:'E', lat:25.0336377, lng:121.5645727}
];
接著撰寫go()
這個 function,裡面可以看到有另外兩個 function 分別是clearMarkers()
和addMarker(i)
,因為我們會把每個標記,宣告到 markers 的陣列元素裡,所以在一開始執行go()
的時候,透過clearMarkers()
來清除標記,這裡清除標記的方法為markers[i].setMap(null);
。然而有清除就有新增,新增的方法額外使用了setTimeout
和animation: google.maps.Animation.DROP
來產生延遲的動畫效果,因此在執行的當下就會看到地圖標記依序落下。
不過很可惜的,經過長時間的查詢,發現 label 並不會有動畫效果,所以只好忍痛把 label 給 marker 起來...
function go() {
clearMarkers();
for (var i = 0; i < position.length; i++) {
addMarker(i);
}
}
function addMarker(e) {
setTimeout(function() {
markers[e] = new google.maps.Marker({
position: {
lat: position[e].lat,
lng: position[e].lng
},
map: map,
//label: position[e].label,
animation: google.maps.Animation.DROP
});
}, e * 150);
}
function clearMarkers() {
for (var i = 0; i < markers.length; i++) {
if(markers[i]){
markers[i].setMap(null);
}
}
markers = [];
}
雖然到這邊好像完成,但是實際上操作起來會有問題!實際上操作起來會有問題!實際上操作起來會有問題!( 很重要所以說三次 ) 因為使用順序宣告的關係,可能會造成點擊按鈕清空標記的時候,還沒有宣告完成標記,結果就造成快速連點按鈕時,會出現地圖標記卡在地圖上的狀況。
範例:連點會有問題的地圖標記
所以如果要解決這個狀況,就變成要把 marker 的部分改成用push
的,就可以一勞永逸地解決這問題。
function addMarker(e) {
setTimeout(function() {
markers.push(new google.maps.Marker({
position: {
lat: position[e].lat,
lng: position[e].lng
},
map: map,
//label: position[e].label,
animation: google.maps.Animation.DROP
}));
}, e * 150);
}