开发者

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

I'm usi开发者_StackOverflow中文版ng 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?


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜