Saturday, July 13, 2013

Bing Maps Module: InfoboxAutoPan

I've just created a very, very simple Bing Maps module. I'll jump ahead to the demo before any explanation.


Basically there are two maps, both with a pushpin near the edge and a click handler to display an infobox.

After clicking the pushpins this is the end-result:

The first one shows the default behavior: the infobox is displayed, although outside the map boundaries.
The second one, using my module, pans the map so that the infobox is fully visible.

Using this module is incredibly simple. Just load it as usual and run the InitInfoboxAutoPanModule command:
MM.registerModule("InfoboxAutoPanModule", "js/InfoboxAutoPanModule.js");
MM.loadModule("InfoboxAutoPanModule", { callback: function () {

    //Rest of the code

Then, just create an infobox, using the typical infobox.setOptions({visible: true}) to display it.

Now, here's the detail: I've created an additional parameter called "autoPan". Just add it to the previous command and the map should automatically pan if required:
infobox.setOptions({visible: true, autoPan: true});

And that's mostly it :)

I've also added an optional argument to the module initialization which allows the margin to the edge to be configured (default: 5x5). Thus, if for instance the module would be initialized as:
InitInfoboxAutoPanModule(map,{horizontalPadding:50, verticalPadding:20});

The end-result after panning would be:


The implementation is also simple. I just copy the original setOptions function to a new field inside the infobox and redefine setOptions to include some extra code. Basically it's just an hook on the existing function:

if(arguments.autoPan == true && arguments.visible == true) {

    var infobox = this;
    var mapWidth = _map.getWidth();
    var mapHeight = _map.getHeight();
    var point = _map.tryLocationToPixel(infobox.getLocation());
    var remainderX = (mapWidth / 2) - point.x;
    var remainderY = (mapHeight / 2) + point.y;

    //Empirical values based on the current infobox implementation
    var xExtraOffset = 33;
    var yExtraOffset = 37;

    var pixelsOutsideX = infobox.getWidth() + 
                         infobox.getOffset().x - remainderX - xExtraOffset + 
    var pixelsOutsideY = infobox.getHeight() + 
                         infobox.getOffset().y + yExtraOffset - remainderY + 

    var newPoint = new Microsoft.Maps.Point(0, 0);

    if (pixelsOutsideX > 0) {
        newPoint.x += pixelsOutsideX;

    if (pixelsOutsideY > 0) {
        newPoint.y -= pixelsOutsideY;

    var newLocation = _map.tryPixelToLocation(newPoint);

        center: new MM.Location(newLocation.latitude, newLocation.longitude)



  1. This comment has been removed by the author.

  2. This comment has been removed by the author.

  3. Pedro I have a question on this - I am confused as to where to place the code for the autopan? Can you email me? Or can I email you my code? Sorry to bother you but I am new to JS. Thank you.

    1. Hi,

      Just check my example above. It's quite simple: