Подтвердить что ты не робот

Контекстное меню Google Map V3

Я ищу библиотеку контекстного меню Google Map V3. Я нашел здесь несколько примеров кода.

Вопрос Google maps v3 - Доступное контекстное меню? в апреле также просто придумало приведенные выше примеры. Так что Gmap3 добавляет простое контекстное меню.

Но, возможно, кто-то инкапсулировал примеры в библиотеку многократного использования или что-то нашел. Очевидно, что что-то для V2.

- Обновлено 2012-05-31 -

Я нашел еще один http://googlemapsmania.blogspot.de/2012/04/create-google-maps-context-menu.html, но еще не успел его протестировать.

4b9b3361

Ответ 1

Я не думаю, что для этого вам нужна библиотека. Я бы начал с попытки:

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 - это смещение, в котором срабатывает событие клика - подсчитывается из верхнего левого угла холста, удерживающего объект карты.

Ответ 2

Я создал рабочий скрипт JS для отображения контекстного меню, а также возможность иметь интерактивные элементы в этом контекстном меню.

Он показывает контекстное меню с кликом, когда маркер щелкнул правой кнопкой мыши на карте Google. В основном это использует OverlayView на карте. Кстати, это просто демо.

var loc, map, marker, contextMenu;

ContextMenu.prototype = new google.maps.OverlayView();

/**
  * onAdd is called when the map 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 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);

Ссылка на скрипт:

http://jsfiddle.net/jEhJ3/3409/

Ответ 4

Перейдите на этот демонстрационный веб-сайт: http://easysublease.org/mapcoverjs/

В контекстном меню я не предлагаю реализовать один подкласс класса overlayView, предоставляемый API Карт Google. Во-первых, один экземпляр подкласса overlayView должен быть добавлен к пяти панелям, предоставленным Google. Возможно, нужно добавить этот экземпляр в панель overlayMouseTarget. Но, этот экземпляр "затенен" другим dom над ним. Таким образом, обычное исходное событие браузера, такое как mouseover, mouseout, не может достигнуть этого экземпляра.

Необходимо использовать метод API Карт Google: addDomListener для его обработки (почему?). Это требует большого количества кода JavaScript для реализации различных обработчиков событий, много добавления и удаления класса CSS, чтобы реализовать некоторые визуальные эффекты, которые могут быть выполнены с использованием нескольких строк кода CSS , если этот экземпляр находится за пределами контейнер карты.

Таким образом, фактически преобразование одного внешнего dom вне контейнера карты google в одно контекстное меню имеет преимущество, что оно может получать исходные события 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 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>

Он показывает, как один разработчик может преобразовать один внешний DOM (id = demoContextPanel) в одно контекстное меню карты, просто добавив один класс css ".mc-ascontextmenu"! На этих страницах используется mapcover.js, который помогает разработчику управлять некоторыми ключевыми компонентами Карты, такими как интерфейсы управления картой, контекстное меню и настраиваемые маркеры. Затем разработчики имеют полную свободу в стиле своих интерфейсов карты.

Если вам нужно больше, вы можете пойти в его Github посмотреть readme.md: https://github.com/bovetliu/mapcover