Google Maps InfoBubble pixelOffset(从标记上方的默认位置移动)

Und*_*ned 14 javascript google-maps google-maps-api-3 infobubble

我正在尝试实现一个自定义的infoBubble,其中的框打开到标记的一侧而不是顶部的默认位置.事实证明这比预期更难.

使用普通的infoWindow,您可以使用pixelOffset.请参阅此处获取文档

使用infoBubble似乎并非如此.无论如何在infoBubble中使用pixelOffset,还是会做同样的事情?

我发现这很难搜索,因为使用Google这样的搜索会返回Google搜索没有相关结果

以下是我一直使用的所有资源.

  • 这里有infoBubble的例子.

  • 在这里设置地图和infoBubble的JavaScript .

现在我的javascript就在这里jsfiddle链接被破坏了.

<script type="text/javascript">

    $(document).ready(function () {
        init();
    });

    function init() {

        //Setup the map
        var googleMapOptions = {
            center: new google.maps.LatLng(53.5167, -1.1333),
            zoom: 13,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };

        //Start the map
        var map = new google.maps.Map(document.getElementById("map_canvas"),
        googleMapOptions);

        var marker = new google.maps.Marker({
            position: new google.maps.LatLng(53.5267, -1.1333),
            title: "Just a test"
        });

        marker.setMap(map);

        infoBubble = new InfoBubble({
            map: map,
            content: '<div class="phoneytext">Some label</div>',
            //position: new google.maps.LatLng(-35, 151),
            shadowStyle: 1,
            padding: '10px',
            //backgroundColor: 'rgb(57,57,57)',
            borderRadius: 5,
            minWidth: 200,
            arrowSize: 10,
            borderWidth: 1,
            borderColor: '#2c2c2c',
            disableAutoPan: true,
            hideCloseButton: false,
            arrowPosition: 7,
            backgroundClassName: 'phoney',
            pixelOffset: new google.maps.Size(130, 120),
            arrowStyle: 2
        });
        infoBubble.open(map, marker);

    }
</script>
Run Code Online (Sandbox Code Playgroud)

更新

为了帮助回答这个问题,我在这里整理了一个测试用例.重要的是第38和39行,它们应指定标签的位置.

更新2

对于要奖励的赏金,我需要查看infoBubble远离其在标记上方的默认位置的示例.优选地在标记的右手侧.

更新3

我已从更新1中删除了测试用例,因为它托管在我旧公司的服务器上.

Suv*_*jah 9

好像infoBubble库本身默认将气泡定位在它所绑定的标记之上.请查看它们包含在库中的示例文件:http://code.google.com/p/google-maps-utility-library-v3/source/browse/trunk/infobubble/examples/example.html.具体请注意从第99行到第122行以及使用两个信息.第一个绑定到标记,但第二个是独立的,因此如果您看到第106行,则可以为其定义位置.现在,基于这种理解,我在这个小提琴http://jsfiddle.net/pDFc3/中为你创造了一个例子.infoBubble位于标记的右侧.

这很奇怪,因为infoBubble js库有一个setPosition函数(http://code.google.com/p/google-maps-utility-library-v3/source/browse/trunk/infobubble/src/infobubble.js? r = 206)参见1027行.但由于某种原因,在我等待DOM加载并尝试通过转换来改变位置后,infoBubble.setPosition(newLatLng);我无法正常工作.相反,infoBubble.getPosition();在DOM加载后声明给出了infoBubble绑定的标记的当前位置.因此setPosition()可能在js库中有一个错误,因为我相信它仍在处理(我可能错了也许它只是错误).


我已经修复了我的jsFiddle以解决你在放大和缩小时的问题,并相应地定位infoBubble(http://jsfiddle.net/pDFc3/).让我先解释一下逻辑.首先,Google地图上道路地图类型的最大缩放级别为21 - 此值与卫星图像不一致,但用户可以进行的最大缩放为21.从21开始,每次缩小两点之间的差异即可基于以下逻辑保持"在屏幕上"的一致性:

consitent_screen_dist = initial_dist * (2 ^ (21 - zoomlevel))
Run Code Online (Sandbox Code Playgroud)

在我们的例子中,初始距离的合理值是0.00003度(在marker和infoBubble之间).所以,基于这个逻辑,我添加了以下部分来找到marker和infoBubble之间的初始纵向距离:

var newlong = marker.getPosition().lng() + (0.00003 * Math.pow(2, (21 - map.getZoom())));
Run Code Online (Sandbox Code Playgroud)

同样,为了确保距离在每个缩放级别更改时保持一致,我们只需在侦听缩放级别更改时声明新的经度:

    google.maps.event.addListener(map, "zoom_changed", function() {
        newlong = marker.getPosition().lng() + (0.00003 * Math.pow(2, (21 - map.getZoom())));
        infoBubble.setPosition(new google.maps.LatLng(marker.getPosition().lat(), newlong));                
    });
Run Code Online (Sandbox Code Playgroud)

请记住,通过声明marker.getPosition的变量和通过方法调用的其他值,可以使此代码更有效.这样就不会重复方法调用并减慢代码速度.


Anu*_*pta 9

这是我的解决方案.

InfoBubble图书馆

更换

整个InfoBubble.prototype.draw 方法

/*
 * 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;
  }
};
Run Code Online (Sandbox Code Playgroud)

然后你可以使用它

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

});
Run Code Online (Sandbox Code Playgroud)

最后我们必须使用此方法setBubbleOffset(x,y);来设置InfoBubble位置

infoBubble.setBubbleOffset(0,-32);
Run Code Online (Sandbox Code Playgroud)