简体   繁体   中英

Google Maps click on marker pan to bottom of screen

I'm working on a google maps project. We are using custom overlays as the marker pop up. The pop ups are meant to be kind of large. So i want to, on click of the marker, have the map pan so the marker is around 50 pixels from the bottom of the viewport to allow for room for the pop up.

Currently, I just have it panning to the lat/long of the marker.

google.maps.event.addDomListener(div, "click", function(e) {
            var x = e.x,
                y = $(div).offset(),
                windowHeight = $(window).height(),
                windowWidth = $(window).width();
            if(!$(div).find('.ryan').hasClass("scaleUp")){
                map.panTo({lat: args.location.lat, lng: args.location.lng})
                var top = $(div).offset().top, mapHeight = $('#content-wrapper').height();



                $(div).append(buildBubble(self.getHcpCount())).css("z-index", markerZindex++)
                var bubble = $(this).find('.ryan');
                var windowPercentage = .5;
                bubble.css({
                    "width": windowWidth * windowPercentage,
                    "height": windowHeight * windowPercentage,
                    "top": 0,
                    "left": 0,
                    "margin-top": -1 * windowWidth * windowPercentage / 2,
                    "margin-left": -1 * windowWidth * windowPercentage / 2 + $(this).width() / 2
                });

                bubble.find('.bubble-body').css({
                    "height": bubble.height() - bubble.find('.bubble-header').height()
                });

                bubble.find('.bubble-section').css({
                    "width": (bubble.width() /*- arrowLeft - arrowRight*/) / 2 - 5
                });

                bubble.find('.hcps-wrapper').css({
                    "width": (bubble.width() /*- arrowLeft - arrowRight*/)
                })

                attachBubbleHandler($(div));

                map.setOptions({disableDoubleClickZoom: true });
            }else{
                map.setOptions({disableDoubleClickZoom: false });
            }   
            $(div).find('.ryan').toggleClass("scaleUp", function(){
                if(!$(this).hasClass('scaleUp')){
                    $(this).unbind().remove();
                }
            });
        });

        //this handles the zIndex problem with clusters being over marker bubbles
        this.getPanes().floatPane.appendChild(div);

    }

    var point = this.getProjection().fromLatLngToDivPixel(this.latlng);

    //LOCATION OF THE TOP AND LEFT POINTS OF THE BUBBLE
    if (point) {
        div.style.left = (point.x - 20) + 'px';
        div.style.top = (point.y) + 'px';
    }

};//END DRAW MARKER

The simple solution 1:
If you don't mind aligning the marker horizontally center: First set the map center to the marker's position then pan the map by the half of the map's div height minus the offset from bottom:

marker.addListener('click', function(){
  var divHeightOfTheMap = document.getElementById('map').clientHeight;
  var offSetFromBottom = 50;
  map.setCenter(marker.getPosition());
  map.panBy(0, -(divHeightOfTheMap / 2 - offSetFromBottom));
});

The simple solution 2:
If you don't want to aligning the marker horizontally center: First set the map center to the marker's latitude and the map's center longitude then pan the map by the half of the map's div height minus the offset from bottom:

marker.addListener('click', function(){
  var divHeightOfTheMap = document.getElementById('map').clientHeight;
  var offSetFromBottom = 50;
  map.setCenter(new google.maps.LatLng(marker.getPosition().lat(), map.getCenter().lng()));
  map.panBy(0, -(divHeightOfTheMap / 2 - offSetFromBottom));
});

Solution 3:

Use an empty overlay to calculate the pixel position:

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Pan to bottom</title>
    <style>
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        height: 100%;
      }
    </style>
    <script src="https://maps.googleapis.com/maps/api/js"></script>
    <script>
        var marker;
        var map;
        var overlay;
        divOverlay.prototype = new google.maps.OverlayView();
        function initMap() {
            var mLatLng = {lat: 40.758984, lng: -73.985131};
            map = new google.maps.Map(document.getElementById('map'), {
              zoom: 15,
              center: mLatLng
            });

            var marker = new google.maps.Marker({
              position: mLatLng,
              map: map
            });

            overlay = new divOverlay(map, marker);
            overlay.setMap(map);

            marker.addListener('click', function(){
                overlay.panMarkerToBottom(50, true); // (Offset from bottom, want horizontally center?)
            });
        }
        function divOverlay(map, marker) {
            this.bounds_ = map.getBounds();
            this.map_ = map;
            this.div_ = null;
            this.marker_ = marker;
        }
        divOverlay.prototype.onAdd = function() {
            this.div_ = document.createElement('div');
            this.getPanes().overlayLayer.appendChild(this.div_);
        };
        divOverlay.prototype.onRemove = function() {
            this.div_.parentNode.removeChild(this.div_);
            this.div_ = null;
        };      
        divOverlay.prototype.draw = function() {
        };

        divOverlay.prototype.panMarkerToBottom = function(offSetFromBottom, isCenter) {
            if (offSetFromBottom){
                var overlayProjection = this.getProjection();
                var mPos = overlayProjection.fromLatLngToContainerPixel(this.marker_.getPosition());
                var mapDiv = this.map_.getDiv();
                var mapWidth = mapDiv.offsetWidth;
                var mapHeight = mapDiv.offsetHeight;
                var panX = 0;
                if (isCenter) {
                    panX = -(mapWidth / 2 - mPos.x);
                }; 
                var panY = -(mapHeight - mPos.y - offSetFromBottom);
                this.map_.panBy(panX , panY);
            }
        };      
        google.maps.event.addDomListener(window, 'load', initMap);
    </script>
  </head>
  <body>
    <div id="map"></div>
  </body>
</html>

I hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM