【问题标题】:Google Maps JS: pinch to zoom Google Maps without moving marker (ie. Uber & Lyft)Google Maps JS:在不移动标记的情况下缩放 Google 地图(例如 Uber 和 Lyft)
【发布时间】:2015-03-18 19:39:15
【问题描述】:

我目前正在构建一个 Phonegap 应用以及 Google 的 Map JS API。

我有一张地图,您可以拖动它来选择您的下车地点。这是通过在“dragend”事件上收集地图的中心地理位置来完成的。然后,我在地图顶部(JS 地图之外)设置了一个图钉,以便您知道中心点在哪里。

一切正常,直到您捏合缩放然后大头针移位。这是由于您在捏屏幕时同时缩放和拖动地图。

有什么方法可以防止拖动缩放以将地图保持在其中心点?

Please view the JSfiddle here.

var map;
google.maps.event.addDomListener(window, 'load', onMapReady);


function onMapReady() {

    var center = new google.maps.LatLng(30.267153, -97.743061);
    var mapOptions = {
        center: center,
        zoom: 13,
        styles: [{"featureType": "poi", "stylers": [{ "visibility": "off" }]},{"featureType": "transit","stylers": [{ "visibility": "off" }]}],
        disableDefaultUI: true,
    };

    map = new google.maps.Map(document.getElementById('map'), mapOptions);

    google.maps.event.addListener(map, 'dragend', function() {
        center = map.getCenter();        
        $('#log').html('Lat: ' + center.lat() + ' Lng: ' + center.lng());
    });
}

【问题讨论】:

  • 问题:1) 为什么不使用google.map.Marker 来保持相同的位置? 2) 这应该只发生一次还是每次用户停止拖动地图时发生?
  • 我使用 getCenter();使用叠加标记而不是实际标记,因为如果在拖动地图时将标记位置更新到地图中心,标记会滞后/跳跃。
  • 标记滞后/跳跃?我看不出为什么会发生这种情况。
  • @MrUpsidown 这是一个例子:jsfiddle.net/pLq8s4xt 它在移动设备上的性能更差,并且在您捏合缩放时遇到相同的标记移动问题。

标签: javascript google-maps cordova google-maps-api-3


【解决方案1】:

这个问题有两种可能的解决方案,从我读到的你已经尝试使用本机标记但它是滞后的,这本身就是我有一个建议的另一个问题:

  1. 使用crosswalk 构建您的应用程序,这将极大地提高您的应用程序性能,我亲身体验过,并且对结果非常满意(我使用英特尔 xdk,但我相信这也适用于 phonegap )。

  2. 使用 UX 解决方案:您会感觉标记滞后,因为毕竟它是可见的!我建议在拖动事件开始时隐藏标记,然后在拖动事件结束时将其显示回来。

  3. 第三种有意义的解决方案是使用像 thisthis 这样的夹点检测器库,甚至是提到的解决方案 @987654324 @here ,选择最适合您的,因为性能是一个关注点,并且必须尝试以前的解决方案,但是一旦您检测到捏合手势,您将地图拖动设置为 false ,在捏合结束后再次将其设置回 true 。

我通常不会在我的解决方案中提供太多编码,而是提供正确的算法来帮助解决指定的问题。

【讨论】:

    【解决方案2】:

    编辑:ProllyGeek 是对的,zoom_changed 事件在拖动已经发生后触发。您可以检测触摸事件是否在地图中心附近(在您的标记上方)并在缩放后重新居中地图:

    google.maps.event.addListener(map, 'dragend', function() {
        if (center && center != map.getCenter()) {
            map.setCenter(center);
            center = null;
        }
    });
    
    //we should recenter the map if the click/mousedown was within the centerRadius of the center of the map
    google.maps.event.addListener(map, 'mousedown', function(clickMouseEvent) {
        var mapDiv = document.getElementById('map');
    
        if (pointInCircle(clickMouseEvent.pixel.x, 
                          clickMouseEvent.pixel.y, 
                          mapDiv.offsetWidth/2, 
                          mapDiv.offsetHeight/2, 
                          centerRadius)) { 
            //map.setOptions({draggable: false}); //disables zoom and dragging
            center = map.getCenter(); //save the current center point so we can recenter later.
        }
    });
    
    //handy function to see if a x,y coordinate is within z radius of another x,y coordinate
    //from https://stackoverflow.com/a/16819053/1861459
    function pointInCircle(x, y, cx, cy, radius) {
        var distancesquared = (x - cx) * (x - cx) + (y - cy) * (y - cy);
        return distancesquared <= radius * radius;
    }
    

    http://jsfiddle.net/bxfn499f/11/

    原答案:

    您是否尝试在触发缩放事件时在地图上将 draggable 设置为 false?

    google.maps.event.addListener(map, 'zoom_changed', function() {
        map.setOptions({draggable: false});
        //heavy handed re-enabling of draggable
        //setTimeout(function() { map.setOptions({draggable: true}); }, 5000); //cant drag for five seconds
    });
    

    您可以通过 mouseup 事件 (which should fire in lieu of the touchend event) 或在您的用例中有意义的任何内容 (map.setOptions({draggable: true});) 以编程方式重新启用拖动。例如:

    google.maps.event.addListener(map, 'mouseup', function() {
        map.setOptions({draggable: true});
    });
    

    http://jsfiddle.net/bxfn499f/6/ 我在桌面上进行了测试,所以我稍微调整了小提琴,因为地图没有为我加载——假设这是由于在$(document).ready(function() { ... } 之后没有触发 window.load。如果在缩放事件之前拖动星号,您将必须查看其行为方式。

    【讨论】:

    • 嘿,投票者 - 请帮助我理解这不能回答“有没有办法防止拖动缩放以将地图保持在其中心点?”的问题?
    • 我在我的代码中弹出了这个,但它没有按预期执行。好主意,只是在实践中行不通。
    • 您能解释一下您遇到的问题吗?我正在做一个编辑,它使用 mouseup 事件重新启用可拖动属性 - 你可能想检查一下。仅供参考:“每当你遇到一个非常草率、不费吹灰之力的帖子,或者一个明显不正确且可能危险地不正确的答案时,请使用你的反对票。”
    • 我没有对你投反对票。我只评论了你的代码。很抱歉造成误解。
    • 别担心!有人想要那个赏金;) - 无论如何,让我知道你对建议的方法有什么问题,以及 mouseup 方法是否适用于重新启用地图的可拖动属性。
    【解决方案3】:

    我有一个可行的解决方案。假设您希望地图居中回到图钉。

    在您的地图对象中添加custom control div。示例是here。代替示例中的“中心地图”div,将您的 pin 设置为控制 div。收听dragend 事件并将中心设置在引脚的位置。

    尚未真正测试解决方案,但似乎可以解决问题。

    【讨论】:

      猜你喜欢
      • 2013-09-21
      • 2014-01-25
      • 2012-11-16
      • 1970-01-01
      • 1970-01-01
      • 2019-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多