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



我正在尝试实现一个自定义的信息气泡,该气泡的框开口位于标记的一侧,而不是顶部的默认位置。事实证明,这比预期的要难。

使用普通的信息窗口,您可以使用像素偏移量。有关文档,请参见此处

使用infoBubble似乎并非如此。有没有在infoBubble中使用pixelOffset,或者可以做同样的事情?

我发现这很难搜索,因为使用这样的谷歌搜索不会返回相关的结果谷歌搜索

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

  • 信息气泡的例子在这里。

  • 我的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>

更新

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

更新 2

为了获得赏金,我需要查看一个信息气泡的示例,该示例位于标记上方的默认位置之外。最好在标记的右侧。

更新 3

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

这是我

的解决方案。

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;
  }
};

然后你可以使用它

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
});

最后我们必须使用此方法setBubbleOffset(x,y);设置信息气泡位置

infoBubble.setBubbleOffset(0,-32);

似乎 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 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);来更改位置后,我不工作。相反,在 DOM 加载后声明infoBubble.getPosition();给了我 infoBubble 绑定到的标记的当前位置。所以setPosition() 可能在 js 库中有一个错误,因为我相信它仍在处理中(我可能是错的,也许它只是有问题)。


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

consitent_screen_dist = initial_dist * (2 ^ (21 - zoomlevel))

在我们的例子中,初始距离的合理值是 0.00003 度(在标记和 infoBubble 之间)。因此,基于此逻辑,我添加了以下部分来查找标记和infoBubble之间的初始纵向距离:

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

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

    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));                
    });

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

不幸的是,

InfoBubble中没有pixelOffset这样的选项。但是,如果您只想在示例中将气泡向上移动标记上方,则不应在气泡初始化时设置 map 参数。考虑以下小提琴(我为您修复了它):

http://jsfiddle.net/ssrP9/5/


附言您的小提琴不起作用,因为您没有正确添加资源http://doc.jsfiddle.net/basic/introduction.html#add-resources

我刚刚遇到了完全相同的问题,但在任何地方都找不到答案。通过一些试验和错误,我解决了它。

您将使用Google JS文件进行"infoBubble"。进入此文件并搜索...

InfoBubble.prototype.buildDom_ = function() {

对我来说,这是在第 203 行(但这可能是之前洗牌和编辑的结果)。

在该函数中,您将看到位置"绝对"声明。在新行上,您可以添加边距顶部、边距右边距、边距底部和边距左边距。这将推动气泡从其默认位置(这也取决于配置中的箭头位置声明)...

这是我在气泡 JS 文件中的代码调整,它将气泡放置在标记的顶部(由于设计功能)......

var bubble = this.bubble_ = document.createElement('DIV');
bubble.style['position'] = 'absolute';
bubble.style['marginTop'] = this.px(21);
bubble.style['marginLeft'] = this.px(1);
bubble.style['zIndex'] = this.baseZIndex_;

希望有帮助。

在 InfoBubble buildDom 函数中,添加:

bubble.className = 'bubble-container';

现在,每个InfoBubble都有一个CSS类,您可以使用CSS边距移动它。

您还可以使用定义的锚点高度;

var anchorHeight = YOURNUMBER;

874行信息气泡.js

相关内容

  • 没有找到相关文章

最新更新