谷歌地图JS:捏紧缩放谷歌地图而不移动标记(即Uber& Lyft)

时间:2015-03-18 19:39:15

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

我目前正在使用Google的Map JS API构建Phonegap应用。

我有一张地图可以拖动以选择您的下车位置。这是通过在“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());
    });
}

3 个答案:

答案 0 :(得分:2)

对于这个问题,有两种可能的解决方案,从我读过你曾尝试过使用原生标记,但它是滞后的,这本身就是另一个我有建议的问题:

  1. 使用crosswalk构建你的应用程序,这将极大地提升你的应用程序性能,我自己经历过,并且对结果非常满意(我使用intel xdk,但我相信这适用于phonegap同样)。

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

  3. 有意义的第三个解决方案是使用像 this this 这样的夹点检测器库,甚至是提到的解决方案<强> here here ,选择最适合您的方法,因为性能是一个值得关注的问题,之前的解决方案必须尝试,但是一旦检测到捏合手势,就将地图拖动设置为false,在结束后再将其设置为true。

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

答案 1 :(得分:1)

编辑: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/我在桌面上测试过,所以我稍微调整了小提琴,因为地图没有为我加载 - 假设这是由于window.load在$(document).ready(function() { ... }之后没有被触发。如果在缩放事件之前拖动星形,您将不得不看看它的行为方式。

答案 2 :(得分:1)

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

在地图对象中添加custom control div。示例是here。而不是&#34;中心地图&#34;示例中的div,使您的引脚成为控制div。收听dragend事件并将中心设置在销的位置。

Haven没有真正测试过这个解决方案,但似乎它可以解决问题。