Google MapV3のコンテキストメニューライブラリを探しています。ここでいくつかのコード例を見つけました
スタックオーバーフローの質問 Googleマップv3-コンテキストメニューが利用可能ですか? 4月も上記の例を思いついたところです。そうだった Gmap3は簡単なコンテキストメニューを追加する 。
しかし、誰かが例を再利用可能なライブラリにカプセル化したか、その間に何かを見つけた可能性があります。明らかに、V2には 何か がありました。
-2012年5月31日更新-
別のものを見つけました http://googlemapsmania.blogspot.de/2012/04/create-google-maps-context-menu.html ですが、まだテストする時間がありませんでした。
このためのライブラリは必要ないと思います。私は試すことから始めます:
var contextMenu = google.maps.event.addListener(
map,
"rightclick",
function( event ) {
// use JS Dom methods to create the menu
// use event.pixel.x and event.pixel.y
// to position menu at mouse position
console.log( event );
}
);
これは、マップが次のもので作成されていることを前提としています。
var map = new google.maps.map( { [map options] } );
コールバック内のevent
オブジェクトには4つのプロパティがあります
latLng
ma
pixel
どこ pixel.x
およびpixel.y
は、クリックイベントがトリガーされたオフセットです-マップオブジェクトを保持しているキャンバスの左上隅から数えます。
コンテキストメニューを表示するための実用的なJS Fiddleと、このコンテキストメニューにクリック可能なアイテムを表示する機能を作成しました。
Googleマップでマーカーを右クリックすると、クリック可能なコンテキストメニューが表示されます。基本的には、マップ上のOverlayViewを利用します。ところで、それは単なるデモです。
var loc, map, marker, contextMenu;
ContextMenu.prototype = new google.maps.OverlayView();
/**
* onAdd is called when the map's panes are ready and the overlay has been
* added to the map.
*/
ContextMenu.prototype.onAdd = function() {
$("<div id='cMenu' class='context-menu-marker'></div>").appendTo(document.body);
var divOuter = $("#cMenu").get(0);
for(var i=0;i < this.menuItems.length;i++) {
var mItem = this.menuItems[i];
$('<div id="' + mItem.id + '" class="options-marker">' +
mItem.label + '</div>').appendTo(divOuter);
}
this.div_ = divOuter;
// Add the element to the "overlayLayer" pane.
var panes = this.getPanes();
//panes.overlayLayer.appendChild();
panes.overlayMouseTarget.appendChild(this.div_);
var me = this;
for(var i=0;i < this.menuItems.length;i++) {
var mItem = this.menuItems[i];
var func = function() {
me.clickedItem = this.id;
google.maps.event.trigger(me, 'click');
};
google.maps.event.addDomListener($("#" + mItem.id).get(0), 'click', $.proxy(func, mItem));
}
google.maps.event.addListener(me, 'click', function() {
alert(me.clickedItem);
});
};
ContextMenu.prototype.draw = function() {
var div = this.div_;
div.style.left = '0px';
div.style.top = '0px';
div.style.width = '100px';
div.style.height = '50px';
};
// The onRemove() method will be called automatically from the API if
// we ever set the overlay's map property to 'null'.
ContextMenu.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
};
// Set the visibility to 'hidden' or 'visible'.
ContextMenu.prototype.hide = function() {
if (this.div_) {
// The visibility property must be a string enclosed in quotes.
this.div_.style.visibility = 'hidden';
}
};
ContextMenu.prototype.show = function(cpx) {
if (this.div_) {
var div = this.div_;
div.style.left = cpx.x + 'px';
div.style.top = cpx.y + 'px';
this.div_.style.visibility = 'visible';
}
};
function ContextMenu(map,options) {
options = options || {}; //in case no options are passed to the constructor
this.setMap(map); //tells the overlay which map it needs to draw on
this.mapDiv = map.getDiv(); //Div container that the map exists in
this.menuItems = options.menuItems || {}; //specific to context menus
this.isVisible = false; //used to hide or show the context menu
}
function initialize() {
loc = new google.maps.LatLng(62.323907, -150.109291);
var options = {};
var menuItems=[];
menuItems.Push({id:"zoomIn", className:'context_menu_item', eventName:'zoom_in_click', label:'Zoom in'});
menuItems.Push({id:"zoomOut", className:'context_menu_item', eventName:'zoom_out_click', label:'Zoom out'});
options.menuItems = menuItems;
//=========================================
map = new google.maps.Map(document.getElementById("map"), {
zoom: 12,
center: loc,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
marker = new google.maps.Marker({
map: map,
position: loc,
visible: true
});
contextMenu = new ContextMenu(map, options);
google.maps.event.addListener(marker, 'rightclick', function(mouseEvent){
contextMenu.hide();
this.clickedMarker_ = this;
var overlayProjection = contextMenu.getProjection();
var cpx = overlayProjection.fromLatLngToContainerPixel(mouseEvent.latLng);
contextMenu.show(cpx);
map.setOptions({ draggableCursor: 'pointer' });
});
// Hide context menu on several events
google.maps.event.addListener(map,'click', function(){
map.setOptions({ draggableCursor: 'grab' });
contextMenu.hide();
});
}
google.maps.event.addDomListener(window, 'load', initialize);
フィドルリンク:
このデモ目的のWebサイトにアクセスします: http://easysublease.org/mapcoverjs/
コンテキストメニューの場合、Google MapsAPIによって提供されるoverlayViewクラスの1つのサブクラスを実装することはお勧めしません。まず、overlayView
のサブクラスの1つのインスタンスをGoogleが提供する5つのペインに追加する必要があります。おそらく、このインスタンスをペインoverlayMouseTarget
に追加する必要があります。 しかし、このインスタンスは他のdomによって「シャドウ」されています。したがって、mouseover
、mouseout
などの通常の元のブラウザイベントはこのインスタンスに到達できません。
Google Maps APIメソッドを使用する必要があります:addDomListener
それを処理する( なぜ? )。さまざまなイベントハンドラーを実装するために多くのJavaScriptコードが必要であり、視覚効果を実現するためだけに多くのcssクラスの追加と削除を行います。これは、CSSコードの数行を使用して実行できますifこのインスタンスはマップコンテナの外にあります。
したがって、実際にGoogleマップコンテナの外部にある1つの外部DOMを1つのコンテキストメニューに変換することには、ブラウザから元のDOMイベントを受信できるというメリットがあります。また、外部ライブラリを使用すると、ターゲットの動作を改善できます。コンテキストメニューとして、元のイベントだけでなく、マップからのイベントも処理できる必要があります。
-----------以下の実装を参照してください------------------------
マップ部分のHTMLでは、次のコードが使用されます。
<div id="mapcover">
<div id="mapcover-map"></div> <!-- this is map container-->
<div id="demoControlPanel" class="mc-static2mapcontainer panel">I am map UI control button's container, I think one can use jQuery UI to make me look better<br><br>
<div id="zoom-in-control" class="text-center">zoomIn</div>
<div id="zoom-out-control" class="text-center">zoomOut</div>
</div>
<div id="demoContextPanel" class="mc-ascontextmenu panel">
I am map context menu container, you can sytle me and add logic to me, just as normal DOM nodes.
since I am not in Map Container at all!
<div class="text-center">
<div role="group" aria-label="..." class="btn-group">
<button id="place-marker1" type="button" class="btn btn-default">Marker1</button>
<button id="place-marker2" type="button" class="btn btn-default">Marker2</button>
</div>
</div>
<div class="form-group">
<label for="content-marker1">Content of next Marker1</label>
<input id="content-marker1" type="text" placeholder="New of Marker1!" class="form-control">
</div>
</div>
</div>
これは、1人の開発者が1つのcssクラス「.mc-ascontextmenu」を追加するだけで、1つの外部DOM(id = demoContextPanel)を1つのマップコンテキストメニューに変換する方法を示しています。そのページはmapcover.jsを使用します。これは、開発者がマップコントロールUI、コンテキストメニュー、カスタマイズされたマーカーなど、マップのいくつかの主要コンポーネントを管理するのに役立ちます。そうすれば、開発者はマップUIのスタイルを自由に設定できます。
さらに必要な場合は、Githubにアクセスしてreadme.mdを参照してください: https://github.com/bovetliu/mapcover
次の手順に従って、Googleマップにコンテキストメニューを追加できます。
以下は作業スニペットです(Googleの請求エラーを回避するために独自のキーを使用してください):
var map;
var karachi = {
lat: 24.8567575,
lng: 66.9701725
};
$(document).ready(function() {
initMap();
});
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 13.5,
center: karachi
});
let contextMenu = document.getElementById('contextMenu');
map.controls[google.maps.ControlPosition.TOP_CENTER].Push(contextMenu);
hideContextMenu();
google.maps.event.addListener(map, "rightclick", function(event) {
showContextMenu(event);
});
google.maps.event.addListener(map, "click", function(event) {
hideContextMenu();
});
}
function showContextMenu(event) {
$('#contextMenu').css("display", "block");
$('#contextMenu').css({
left: event.pixel.x,
top: event.pixel.y
})
}
function hideContextMenu() {
$('#contextMenu').css("display", "none");
}
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
.contextMenu {
background-color: rgb(255, 255, 255);
border: 2px solid rgb(255, 255, 255);
border-radius: 3px;
box-shadow: rgba(0, 0, 0, 0.3) 0px 2px 6px;
cursor: pointer;
font-size: 1rem;
text-align: center;
color: #0d1f49;
width: 20vw;
margin: 1px;/*Please note that this margin is necessary otherwise browser will open its own context menu*/
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAGlM3LLIL2j4Wm-WQ9qUz7I7ZpBsUx1X8">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="map"></div>
<div id="contextMenu" class="contextMenu">
<div onclick="alert('On click of item 1 is called')">
Item 1
</div>
</div>