Google Mapsで地図の中心にCrosshair(十字)を描こうとすると、ちょっと面倒ですよね。
google maps crosshairなどでググると、OverlayViewに配置して、地図の中心が変わるたびに再描画する、という以下のような方法が紹介されています。
PCオンリーな方法
function Crosshair() {
this.setMap(map);
this.div_ = document.createElement('div');
this.div_.innerText = "+";
this.div_.id = "crosshair";
};
Crosshair.prototype = new google.maps.OverlayView;
Crosshair.prototype.onAdd = function() {
var pane = this.getPanes().overlayLayer;
pane.appendChild(this.div_);
var me = this;
this.listeners_ = [
google.maps.event.addListener(this.getMap(), 'center_changed',
function() { me.draw(); })
]
}
Crosshair.prototype.draw = function() {
var projection = this.getProjection();
var position = projection.fromLatLngToDivPixel(map.getCenter());
var div = this.div_;
div.style.left = position.x + 'px';
div.style.top = position.y + 'px';
}
crosshair = new Crosshair();
これをスマホなどの非力な端末でやると、地図の中心を変更するたびに、Crosshairが中心点からずれてしまってみっともないことになります。
この方法よりももっと簡単でスマホにも優しいのは、地図とは別の(Google Maps管轄外の)DOM要素を配置して、それを地図上に重ねる方法です。
具体的には、HTMLタグで地図キャンバスとCrosshairのDIVを以下のように配置し、
HTML
<div id="wrap">
<div id="map-canvas"></div>
<div id="cross"></div>
</div>
CSSで地図の上にDIVを配置します。
CSS
#wrap{
width: 300px;
height: 300px;
position: relative;
}
#map-canvas{
width: 100%;
height: 100%;
}
#cross{
position: absolute;
width: 2px;
height: 20px;
background: #000;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
pointer-events: none;
}
#cross::before{
content: "";
position: absolute;
width: 20px;
height: 2px;
background: #000;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
ポイントは、"pointer-events: none;" で、地図よりも手前(z-indexが上)にあるCrosshairのDIVをマウスやタッチ操作から無効化することです。
これでスマホにも優しいCrosshairの出来上がりです。
デモ