Можем ли мы сделать 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/
Ваше здоровье!