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 expected.
Using the normal infoWindow you can use pixelOffset. See here for the documentation
Using infoBubble this does not seem to be the case. Is there anyway of using pixelOffset in an infoBubble, or something that will do the same thing?
I have found this very difficult to search for, as using a google search such as this returns no relevant results Google Search
Below is all my resources I have been using.
And now my javascript here just in-case the jsfiddle link is broken.
<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>
Update
To help with answering this question i have put together a test case here. The important lines are lines 38 & 39, which should specify where to position the label.
Update 2
For the bounty to be awarded i need to see an example of the infoBubble positioned away from its default position above the marker. Preferably to the right hand side of the marker.
Update 3
I have removed the testcase from update 1 because it is hosted on my old company's servers.
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);