开发者问题收集

自定义 Google 地图中的滚轮缩放

2015-06-25
4445

您能自定义 Google 地图中的滚轮缩放功能吗?如果用户使用鼠标滚轮,我希望地图缩放 2 或 3 级。可以吗?

在此处查看我的 jsFiddle: http://jsfiddle.net/jj7ymt5c/1/

我在控制台中收到以下错误: Uncaught RangeError:超出最大调用堆栈大小

以下是代码:

function initializeMap() {
    map = new google.maps.Map(document.getElementById("map_canvas"), {
        zoom: 14,
        center: new google.maps.LatLng(42.35210605281608, -83.12983274459839),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });
    google.maps.event.addListener(map, 'zoom_changed', function () {
        map.setZoom(map.getZoom() + 2);
    });
}
3个回答

您可以禁用内置滚轮缩放并实现自己的处理程序:

function initializeMap() {
  var map = new google.maps.Map(document.getElementById("map_canvas"), {
      zoom: 14,
      scrollwheel: false,
      center: new google.maps.LatLng(42.35210605281608, -83.12983274459839),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    }),
    fx = function(e) {
      e.preventDefault();
      var z = (e.wheelDelta > 0 || e.detail < 0) ? 3 : -3;
      map.setZoom(Math.max(0, Math.min(22, map.getZoom() + z)));
      return false;
    };
  google.maps.event.addDomListener(map.getDiv(), 'mousewheel', fx);
  google.maps.event.addDomListener(map.getDiv(), 'DOMMouseScroll', fx);
  
}

google.maps.event.addDomListener(window, 'load', initializeMap);
html,
body,
#map_canvas {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<div id="map_canvas"></div>

与评论相关的修复(缩放到鼠标位置):

相关部分是 projection_changed 处理程序,在创建 google.maps.Map 实例后将其添加到某个位置


function initializeMap() {
  var map = new google.maps.Map(document.getElementById("map_canvas"), {
      zoom: 7,
      scrollwheel:false,
      center: new google.maps.LatLng(42.352, -83.129)
    });
  
  
  google.maps.event.addListenerOnce(map,'projection_changed',function(){
      
      var steps=3,//the desired zoom-steps on each mousescroll 
          goo = google.maps,
          map = this,
          div = map.getDiv();
      goo.event.addListener(map,'scrollwheel_changed',function(){
      
      var evs = this.get('wheelevents');
      if(this.get('scrollwheel')){
         if(evs){
            for(var k in evs){
              goo.event.removeListener(evs[k])
            }
         }
         this.set('wheelevents',{})
      }
      else{
         var fx = function(e) {
              e.preventDefault();
              var target  = e.target || e.srcElement;
              
              if(target.parentNode.parentNode.parentNode!==div){
                return;
              }        
              
              var rect    = target.getBoundingClientRect(),
                  dir     = ((e.wheelDelta > 0 || e.detail < 0) ? 1 : -1)*steps,
                  zoom    = Math.max(0, Math.min(25, map.getZoom() + dir)),
                  fz      = Math.pow(2,map.getZoom()),
                  mo      = { x:  e.clientX - rect.left,
                              y:  e.clientY - rect.top},
                  co      = { x:  div.offsetWidth/2,
                              y:  div.offsetHeight/2},
                  cp  = map.getProjection().fromLatLngToPoint(map.getCenter()),
                  mc  = map.getProjection()
                             .fromPointToLatLng(new google.maps.Point(
                             (cp.x*fz-(target.offsetWidth/2-mo.x))/fz
                             ,
                             (cp.y*fz-(target.offsetHeight/2-mo.y))/fz
                             )),
                  mp= map.getProjection().fromLatLngToPoint(mc),
                  __zoom,__fz,__cp;
              
              map.setZoom(zoom);
              __zoom=map.getZoom();
              __fz=Math.pow(2,__zoom)
              __cp=new google.maps.Point(
                (mp.x+(co.x-mo.x)/__fz)
                ,
                (mp.y+(co.y-mo.y)/__fz)
              );
              map.setCenter(map.getProjection().fromPointToLatLng(__cp))
              return false;
            };
            
         this.set('wheelevents',
                  {
                    mousewheel: goo.event.addDomListener(div, 
                                                        'mousewheel', fx),
                    mousescroll:goo.event.addDomListener(div, 
                                                        'DOMMouseScroll', fx)
                  }
                 );
      }
    });
    goo.event.trigger(map,'scrollwheel_changed')
  });  

}

google.maps.event.addDomListener(window, 'load', initializeMap);
html,
body,
#map_canvas {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}
<script src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<div id="map_canvas"></div>

注意: 这将观察地图的 scrollwheel 属性,要从一开始就应用所需的行为,请将地图的 scrollwheel 选项设置为 false 。当您稍后想要添加/删除行为时,请通过 set 设置滚轮属性:

map.set('scrollwheel',true);//or false
Dr.Molle
2015-06-26

因此存在 2 个问题,

1) 当前缩放级别 +2 可以超过 20,这是 Google 地图支持的最大缩放级别。您应该确保它不超过 20。

2) 设置缩放实际上会触发缩放更改监听器。因此您应该放置一个标志或其他东西,以指示此缩放是由用户触发还是由设置的缩放级别触发

kaho
2015-06-25

您可能超出了缩放尺寸范围。 因此,

  • 1.首先,请通过 ma​​pObject.getZoom() 了解可用的缩放范围,然后
  • 2.仅当当前缩放尺寸低于范围 2 时,才使用 if 条件将 setZoom() 增加 2。

例如,您的区域可用的缩放范围是 0-20, 然后使用 if 条件检查当前缩放尺寸,如果不超过 18,则设置缩放尺寸 = 当前缩放尺寸 +2
这将达到最大值 20....

if (map.getZoom() < 19) 
{
map.setZoom(map.getZoom() + 2); 
}
svik
2015-06-25