Javascript 要切换的传单地图 "Show Your Location"

Javascript leaflet map to toggle "Show Your Location"

我有一张传单地图,上面显示了此人当前所在的区域(当前位置),通常我希望地图 'follow' 这个人在旅行时。我为此使用 mymap.panTo 命令。这么多工作正常。它每 5 秒更新一次地图,并以当前人为中心完美平移。

偶尔,人们可能想将地图滚动到更远的地方以查看某些内容。这有效......直到 5 秒计数器开始并将地图再次平移回他们的位置。烦人。

我在各种地图应用程序上看到地图上有一个 button/toggle,人们可以点击它来停止地图跟随他们。事实上,如果地图是手动移动的,它通常会关闭,然后他们会点击切换键平移回他们当前的位置。请查看 google 地图的附件图片,突出显示了他们所谓的“显示您的位置”按钮。这就是我想要的。

但是这是怎么做到的呢?这是我找不到的某种自定义传单控件吗?或者它是以某种方式完全以编程方式完成的(以及任何示例代码片段?)。

感谢任何帮助。

下面是我用来显示地图的代码。

var streetmap = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
      attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
      id: 'mapbox/streets-v11',
      accessToken: 'token code here' //redacted token
   }),
   satellite = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
      attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
      id: 'mapbox/satellite-v9',
      accessToken: 'token code here' //redacted token   });
var baseMaps = {
     "Streetmap": streetmap,
     "Satellite": satellite
};
    
var mymap = L.map('mapid', { 
   center: [latitude,longitude],
   zoom: 17,
   layers: [streetmap] //default layer
}); 

var personicon = L.icon({
    iconUrl: '/js/personicon.png',
    iconSize: [20, 20]
    });
var playerLoc = new L.marker([latitude,longitude], {icon: personicon}) // set player location marker as a declared variable but don't put it on the map yet

在其他地方我有启动地图的代码(一旦变量被填充)然后继续更新位置

   const interval = setInterval(function() {
         if (is_running) { // we need to know that there is data populated before showing or updating the map with it
         if (!map_started) {  //start the map only once 
        L.control.layers(baseMaps).addTo(mymap); //show choice of layer views
            L.control.scale().addTo(mymap); //show scale bar
        console.log("Create current player marker:",MYID,latitude,longitude); 
            playerLoc.setLatLng([latitude,longitude]).addTo(mymap).bindPopup(MYID); //update current player marker, and now show it on the map
                map_started=true;
             }; //start the map only once
         updatemap(); // for current player location and circle colour.
      }; //update only if is_running
          mymap.invalidateSize(); //reset map view
    }, 5000); // update map every 5 seconds 
function updatemap() {  // Update the current player location on map
    playerLoc.setLatLng([latitude,longitude]); //update current player marker instead of creating new ones
    mymap.panTo([latitude,longitude]); // pan the map to follow the player (TODO: Can we toggle pan mode?)
}; // end updatemap

此代码一切正常。 mymap.panTo([latitude,longitude]); 行需要包含在条件“如果允许平移,则执行 mymap.panTo([latitude,longitude]);”但肯定有标准的传单控制或方法吗?我在别处经常看到这个东西

您需要监听 movestart 事件,以检测用户是否移动了地图。但是这个事件也是从 panTo 函数触发的,所以你需要一个标志来指示 movestart 是由间隔触发还是由用户触发。


var currentAutoMove = false; // needed to check in `movestart` event-listener if moved from interval or by user
var pauseAutoMove = false; // if true -> Stops moving map

var latitude,longitude;
setInterval(()=>{
    latitude = playerLoc.getLatLng().lat + 0.001;
    longitude = playerLoc.getLatLng().lng + 0.001;
    updatemap();
}, 1000)


function updatemap() {  // Update the current player location on map
    playerLoc.setLatLng([latitude,longitude]);
    
    if(!pauseAutoMove){
       currentAutoMove = true; // Set flag, that currently map is moved by interval
       map.panTo([latitude,longitude]);
       currentAutoMove = false; // Remove flag, that currently map is moved by interval
   }
}


map.on('movestart',(e)=>{
    console.log(e, currentAutoMove);
  if(!currentAutoMove){ // Check if map is moved by interval or by user
    pauseAutoMove = true; // set flag, to stop moving map
  }
})

// Start auto move again, if button clicked
L.DomEvent.on(document.getElementById('toPos'),'click',(e)=>{
    pauseAutoMove = false; // reset flag, to stop moving map -> start moving map
  map.panTo([latitude,longitude]);
})

要创建一个控件/按钮来启动自动移动你只需要在Google中搜索有很多例子,否则你可以使用L.easybutton。

演示:https://jsfiddle.net/falkedesign/8akw3ust/

非常感谢 Falke Design,我使用了上面答案中的建议。对于我想要的按钮,我的代码现在看起来像这样:

var panbtn = L.easyButton({
  states: [{
    stateName: 'pauseAutoMove',      
    icon:      'fa-sign-in fa-lg',               
    title:     'Centre display at current Player', //Tooltip
    onClick: function(btn, map) {
      console.log("AutoMoveButton pressed");
      panbtn.state('AutoMove');                               
      mymap.panTo([latitude,longitude]); 
    }
  }, {
    stateName: 'AutoMove',
    icon:      'fa-crosshairs fa-lg',
  }]
}).addTo(mymap);

mymap.on("zoomstart", function (e) { currentAutoMove = true }); //Set flag, that currently map is moved by a zoom command
mymap.on("zoomend", function (e) { currentAutoMove = false }); //Remove flag again

mymap.on('movestart',(e)=>{ //Check if map is being moved
    if(!currentAutoMove){ //ignore if it was a natural PlayerLoc Auto update
        pauseAutoMove = true; //set flag to stop Auto moving map 
            console.log("Map moved");
        panbtn.state('pauseAutoMove'); //change button style to remove crosshairs
    }
});

在updatemap函数中代码:

    if(!pauseAutoMove){ //pan the map to follow the player unless it is on pause
            currentAutoMove = true; //Set flag, that currently map is moved by a normal PlayerLoc Auto update
            mymap.panTo([latitude,longitude]); 
            currentAutoMove = false; //Remove flag again
    };

非常感谢。