[GIS] Infobox not fixed to marker when Google Map is wrapped (on zoom 0,1,2)

google maps

I use a custom infobox that is fixed to the marker's position. Everything is good (see screenshot 1) until the map reaches the zoom 3 or lower, precisely, when the map is wrapped. The infobox is no more fixed to the marker and it's moved some pixels to the left of the marker (see screenshot 2).

Screenshot 1

enter image description here

Screenshot 2

enter image description here

I use the following code to convert the marker's position (LatLng) to "XY" points (See the code) and to fix the custom infobox to the marker.

           
var scale = Math.pow(2, map.getZoom());

var nw = new google.maps.LatLng(
    map.getBounds().getNorthEast().lat(),
    map.getBounds().getSouthWest().lng()
);

var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);

/**
 * [@marker_position] - The position (LatLng) of the marker */

var worldCoordinate = map.getProjection().fromLatLngToPoint(marker_position);

var pixelOffset = new google.maps.Point(
    Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
    Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale)
);

/**
 * [@mapPosition] - This will get the position of the map on the screen */

var mapPosition = jQuery('div.mapContainer').position();

var infobox_half_width = jQuery('div.infobox').width() / 2;
var margin_top = marker_icon_height + jQuery('div.infobox').height();       

/**
 * Set the position of the infobox on the map.
 * [@left] - The position of the marker (Horizontaly) ACCORING to the map's left position on the screen.
 * [@top] - The position of the marker (Verticaly) ACCORING to the map's top position on the screen. 
 * [@margin-left] - Move the infobox 50% of its size to the left. 
 * [@margin-top] - Move the map to the top of the marker (According to the marker image size). */

jQuery('div.infobox').css({'left':(pixelOffset.x + mapPosition.left + 'px'),
                 'top':(pixelOffset.y + mapPosition.top + 'px'), 
                 'margin-left':('-' + infobox_half_width + 'px'),
                 'margin-top':('-'+margin_top+'px')
               }).fadeIn('slow');                                                                 

What i want is to keep the infobx fixed to its marker even when the map is wrapped.

I think the problem is in this part of the code (see code bellow) but i don't know how to adapt it to maintain the infobox fixed to its marker when the map is wrapped. The code needs something (in the calculations) to tell the map to calculate the infobox's position related to the bounds of the completely visible part of the world. Does anyone have an idea on how to resolve this issue?

           
var scale = Math.pow(2, map.getZoom());

var nw = new google.maps.LatLng(
    map.getBounds().getNorthEast().lat(),
    map.getBounds().getSouthWest().lng()
);

var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);

/**
 * [@marker_position] - The position (LatLng) of the marker */

var worldCoordinate = map.getProjection().fromLatLngToPoint(marker_position);

var pixelOffset = new google.maps.Point(
    Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale),
    Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale)
);

Note: I didn't want to use the GMaps overlay to create the infobox just to prevent the slow loading of the map when there's too many markers. I've tried it already with 600+ markers (markers + overlays displayed by default) and it takes too much time to load. Creating the custom infoboxes outside of the map and using that code to fix each infobox to its marker had a positive impact on the loading speed.

Best Answer

With the Set pixelOffset you can move in pixels your infobox from top-left but it won't be same for every infobox.

So if you set alignBottom to true, pixelOffset will be move from bottom-left and all infobox will have the same displacement.

Keep in mind that if the width of your infoboxes are different, you'll need to calculate your pixelOffset in a dynamic way.

Example:

var htmlInfoWindow = new InfoBox({
      content: "",
      closeBoxURL: "",
      position: marker.getPosition(),
      pixelOffset: new google.maps.Size(-100, -250),
      alignBottom: true
});