Keeping the InfoWindow in view when zooming map in

2019-08-07 02:09发布

问题:

Just started converting our maps from V2 of the API to v3.

Got one issue so far in that when an InfoWindow is open, and the map is zoomed in, the InfoWindow will move off the map and eventually not be visible, this is different behaviour than in V2. In V2 the InfoWindow remains in view all the time.

V2 map: http://www.stroud.gov.uk/docs/housing/tenant_map_v2.asp

V3 map: http://www.stroud.gov.uk/docs/housing/tenant_map_v3.asp

Simply click on any marker to open it's InfoWindow, then zoom the map in with the normal zoom controls.

Is there a way to keep the behaviour as in the V2 map?

Thanks, Mike


I've come up with a solution that works. URL as above but use tenant_map.asp

var currentInfoWindow = null; // new global scope variable to hold current open infoWindow

In the google.maps.event.addListener(newMarker, "click" function I've added:

currentInfoWindow = this;

Add a zoom_changed listener:

google.maps.event.addListener(theMap, "zoom_changed", function () {
    if (currentInfoWindow != null) {
        infoWindow.open(theMap, currentInfoWindow);
    }
});

and an infoWindow closeclick listener:

google.maps.event.addListener(infoWindow, "closeclick", function () {
    currentInfoWindow = null;
});

Seems to work ok, do get a little bit of panning when zooming, but this has been the only thing that I've got to work so far.

It doesn't look as good as the V2 map, so if anyone else has a better solution, please post.

回答1:

It seems to me because the V2 map, when you zoom, zooms directly onto the last highlighted marker. V3 just zooms onto wherever the map is currently centred. What about making the marker click event handler re-centre the map on that marker?



回答2:

Here is a zoom function that keeps the info window in place. I'm using my own zoom controls and calling zoomBy(1) to zoom in one level or zoomBy(-2) to zoom out two levels.

var helperOverlay = new google.maps.OverlayView();
helperOverlay.draw = function(){};
helperOverlay.setMap(map);

function zoomBy(delta) {
  var newZoom = map.getZoom() + delta;
  if ( newZoom < 0 ) return;
  var projection = helperOverlay.getProjection();
  if ( projection ) { // projection may be undefined (if the overlay is not ready I guess)
    var center = projection.fromLatLngToContainerPixel(map.getCenter());
    var focus  = projection.fromLatLngToContainerPixel(infoWindow.getPosition());
    for (var i = Math.abs(delta); i > 0; i--)
      center = (delta > 0) ?
        new google.maps.Point((center.x + focus.x)/2, (center.y + focus.y)/2) :
        new google.maps.Point(center.x * 2 - focus.x, center.y * 2 - focus.y);
    map.setCenter(projection.fromContainerPixelToLatLng(center));
  }
  map.setZoom(newZoom);
}

The math is borrowed from this scroll wheel zoom implementation. It would be nice if we could just call the built in scroll wheel zoom implementation passing in the position of the info window.