Google Maps InfoBubble pixelOffset (Moving from default position above marker)

前端 未结 5 1279
情歌与酒
情歌与酒 2021-02-04 07:11

I am trying to implement a custom infoBubble that has the box opening to the side of a marker rather than the default position of on top. This has turned out to be harder than e

5条回答
  •  离开以前
    2021-02-04 07:41

    This is my solution.

    In InfoBubble library

    replace

    entire InfoBubble.prototype.draw method

    with

    /*
     * Sets InfoBubble Position
     * */
    InfoBubble.prototype.setBubbleOffset = function(xOffset, yOffset) {
      this.bubbleOffsetX = parseInt(xOffset);
      this.bubbleOffsetY = parseInt(yOffset);
    }
    
    
    /*
     * Gets InfoBubble Position
     * */
    InfoBubble.prototype.getBubbleOffset = function() {
      return {
        x: this.bubbleOffsetX || 0,
        y: this.bubbleOffsetY || 0
      }
    }
    
    /**
     * Draw the InfoBubble
     * Implementing the OverlayView interface
     */
    InfoBubble.prototype.draw = function() {
      var projection = this.getProjection();
    
      if (!projection) {
        // The map projection is not ready yet so do nothing
        return;
      }
    
      var latLng = /** @type {google.maps.LatLng} */ (this.get('position'));
    
      if (!latLng) {
        this.close();
        return;
      }
    
      var tabHeight = 0;
    
      if (this.activeTab_) {
        tabHeight = this.activeTab_.offsetHeight;
      }
    
      var anchorHeight = this.getAnchorHeight_();
      var arrowSize = this.getArrowSize_();
      var arrowPosition = this.getArrowPosition_();
    
      arrowPosition = arrowPosition / 100;
    
      var pos = projection.fromLatLngToDivPixel(latLng);
      var width = this.contentContainer_.offsetWidth;
      var height = this.bubble_.offsetHeight;
    
      if (!width) {
        return;
      }
    
      // Adjust for the height of the info bubble
      var top = pos.y - (height + arrowSize) + this.getBubbleOffset().y;
    
      if (anchorHeight) {
        // If there is an anchor then include the height
        top -= anchorHeight;
      }
    
      var left = pos.x - (width * arrowPosition) + this.getBubbleOffset().x;
    
      this.bubble_.style['top'] = this.px(top);
      this.bubble_.style['left'] = this.px(left);
    
      var shadowStyle = parseInt(this.get('shadowStyle'), 10);
    
      switch (shadowStyle) {
        case 1:
          // Shadow is behind
          this.bubbleShadow_.style['top'] = this.px(top + tabHeight - 1);
          this.bubbleShadow_.style['left'] = this.px(left);
          this.bubbleShadow_.style['width'] = this.px(width);
          this.bubbleShadow_.style['height'] =
            this.px(this.contentContainer_.offsetHeight - arrowSize);
          break;
        case 2:
          // Shadow is below
          width = width * 0.8;
          if (anchorHeight) {
            this.bubbleShadow_.style['top'] = this.px(pos.y);
          } else {
            this.bubbleShadow_.style['top'] = this.px(pos.y + arrowSize);
          }
          this.bubbleShadow_.style['left'] = this.px(pos.x - width * arrowPosition);
    
          this.bubbleShadow_.style['width'] = this.px(width);
          this.bubbleShadow_.style['height'] = this.px(2);
          break;
      }
    };
    

    and then you can use this by

    var infoBubble = new InfoBubble({
      map: map,
      content: "My Content",
      position: new google.maps.LatLng(1, 1),
      shadowStyle: 1,
      padding: 0,
      backgroundColor: 'transparent',
      borderRadius: 7,
      arrowSize: 10,
      borderWidth: 1,
      borderColor: '#2c2c2c',
      disableAutoPan: true,
      hideCloseButton: true,
      arrowPosition: 50,
      backgroundClassName: 'infoBubbleBackground',
      arrowStyle: 2
    
    });
    

    Then finally we have to use this method setBubbleOffset(x,y); to set InfoBubble position

    infoBubble.setBubbleOffset(0,-32);
    

提交回复
热议问题