Можем ли мы сделать ol.Overlay перетаскиваемым на OpenLayers 3?

Я пытаюсь сделать так, чтобы ol.overlay был перетаскиваемым, но я не в состоянии это сделать. Я нашел этот пример ( http://openlayers.org/en/v3.2.1/examples/drag-features.html?q=drag), но он сделан с использованием ol.Features, и мне нужно наложение, так как Я могу использовать собственный -html div- для показа того, что мне нужно. Я также нашел очень интересный пример, который может делать то, что я хочу, но это делается с помощью Google Maps v3, и мне это нужно для ol3.
Заранее спасибо.

3 ответа

Решение

ОБНОВИТЬ:

Там нет необходимости в этом ol.Map.prototype.forEachOverlayAtPixel метод (см. https://github.com/openlayers/ol3/issues/5760).

Просто зарегистрируйтесь mousedown Прислушайтесь к элементу наложения DOM, и все готово. Скрипка обновлена.


ol.Overlay это плохой тип в OL3, но с некоторой работой, да, вы можете достичь этого. ol.Feature является всемогущим, и если вам действительно нужно ol.Overlay Я придумал эту демо-скрипку.

Идея заключается в следующем:

  • Слушай pointerdown событие карты и проверьте, есть ли наложение на пикселе, по которому щелкнули;

    • ol.Map.prototype.forEachOverlayAtPixel - только что создан для вопроса
  • дезактивировать ol.interaction.DragPan - панорамирование карты;

  • Слушай pointermove и установите положение наложения;

  • Слушай pointerup и восстановить ol.interaction.DragPan;

Вы можете просто зарегистрировать прослушиватель событий mousedown на div оверлея. Внутри этого слушателя зарегистрируйте события mousemove и mouseup в окне. Чтобы обновить позицию на 'mousemove', используйте ol.Map#getEventPixel() метод, который принимает событие mousemove в качестве аргумента. При 'mouseup' вы просто отменяете регистрацию оконных слушателей.

marker_el.addEventListener('mousedown', function(evt) {
  function move(evt) {
    marker.setPosition(map.getEventCoordinate(evt));
  }
  function end(evt) {
    window.removeEventListener('mousemove', move);
    window.removeEventListener('mouseup', end);
  }
  window.addEventListener('mousemove', move);
  window.addEventListener('mouseup', end);
});

См. http://jsfiddle.net/rnzgfg89/6/ для рабочего примера.

Решил немного добавить к обсуждению. Мне понравилось решение Джонатаса, но если наложение не крошечное, оно немного прыгает, если вы не щелкнете точно в центре наложения, поэтому я несколько улучшил его решение, найдя расстояние между щелчком и текущим положением элемент наложения. Затем при установке положения используются эти расстояния, чтобы положение мыши на наложении не менялось при перетаскивании наложения.

      let deltaX, deltaY

const getAdjustedCoords = coordinate => {
  const resultCoord = [coordinate[0] - deltaX, coordinate[1] - deltaY] 
  return resultCoord
}

marker_el.addEventListener('mousedown', function(evt) {
  dragPan.setActive(false);
  let markerpos = marker.getPosition();
  let clickPixel = [evt.x, evt.y]
  let clickCoords = map.getCoordinateFromPixel(clickPixel)
  
  deltaX = clickCoords[0] - markerpos[0]
  deltaY = clickCoords[1] - markerpos[1]
  marker.set('dragging', true);
  console.info('start dragging');
});

map.on('pointermove', function(evt) {
  if (marker.get('dragging') === true) {
    marker.setPosition(getAdjustedCoords(evt.coordinate));
  }
});

map.on('pointerup', function(evt) {
  if (marker.get('dragging') === true) {
    console.info('stop dragging');
    dragPan.setActive(true);
    marker.set('dragging', false);
  }
});

Вот моя скрипка: https://jsfiddle.net/sxc24re8/

Ваше здоровье!

Другие вопросы по тегам