How to create a text overlay in Google Maps API v3 that does not pan?

I'm using Google Maps API v3. I would like to create a text overlay on a map that does not move when the map is panned. Is the best approach to manipulate the DOM elements accessible from the MapPanes object or is it best to create a custom control even though it would not do much other than display text?

Answers


The simplest way that I found worked for me was a few lines of JavaScript added after I created a new map. So, after this:

map = new google.maps.Map('myMapDivId', mapOptions);

add this:

var myTitle = document.createElement('h1');
myTitle.style.color = 'white';
myTitle.innerHTML = 'Hello World';
var myTextDiv = document.createElement('div');
myTextDiv.appendChild(myTitle);

map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(myTextDiv);

You will probably want to style the text to look nicer.

An alternative is to put the div in your HTML:

<div id="myTextDiv" style="color: white; position: absolute;">
    <h1>Hello World</h1>
</div>

and then do this in your JavaScript:

var myControl = document.getElementById('myTextDiv');
map.controls[google.maps.ControlPosition.TOP_CENTER].push(myControl);

NOTE an important difference: If you use the HTML route to define your div, you must set the position style to absolute in the HTML to avoid rendering problems.


From you're describing, the best approach would be a custom control. Docs for that are here. Custom controls can be as simple or a complicated as you want.

One reason why you would want to muck around with the map panes is if you wanted such a 'control' to lie underneath the markers / shadows / polylines etc. I'm doing this right now to show a crosshairs in the center of the map at all times. But because I keep it as an overlay, I choose the panes in such a way that the markers are above it, so they can continue to be clicked and interacted with - using the mapPane. Here's how I'm doing it:

var CrosshairOverlay = function(map){
    this._holder = null;
    this.setMap(map);
};
CrosshairOverlay.prototype = new google.maps.OverlayView();
CrosshairOverlay.prototype.onAdd = function(){
    var map = this.getMap();
    var holder = this._holder = $('<div>').attr('id', 'crosshair')[0];

    var crosshairPaper = this._paper = R(holder, 150, 150);
    // ... all your drawing and rendering code here.
    var projection = this.getProjection();
    var wrappedHolder = $(holder);

    var updateCrosshairPosition = function(){
        var center = projection.fromLatLngToDivPixel(map.getCenter());
        wrappedHolder.css({left:center.x-75, top:center.y-75});
    }
    _.each(['drag','dragend','bounds_changed','center_changed','zoom_changed','idle','resize'], function(event){            
        google.maps.event.addListener(map, event, updateCrosshairPosition);
    });
    google.maps.event.addListener(map, 'maptypeid_changed', function(){
        _.defer(updateCrosshairPosition);
    });

    this.getPanes().mapPane.appendChild(holder);
};
CrosshairOverlay.prototype.draw = function(){
};
CrosshairOverlay.prototype.onRemove = function(){
    this._holder.parentNode.removeChild(this._holder);
    this._holder = null;
};

The reason the maptypeid_changed has its own handler with a defer is because that event is fired before the map properly sets itself up when changing the type. Just run your function after the current event loop.


Need Your Help

Remove underline from links in TextView - Android

android hyperlink textview underline

I am using two textview to display links from database, I managed to change link colors but I want to remove the underline

TensorFlow - Importing data from a TensorBoard TFEvent file?

python tensorflow tensorboard

I've run several training sessions with different graphs in TensorFlow. The summaries I set up show interesting results in the training and validation. Now, I'd like to take the data I've saved in ...