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

OpenLayers 3: событие "movestart" на карте

API OpenLayers3 имеет map.on( "moveend" ), однако я не могу найти movestart. Кто-нибудь знает, как я могу это достичь? Есть ли эквивалентное событие?

OpenLayers 2 имел событие movestart на карте. Я смотрю точную параллель в OpenLayers3

Вот базовый jsFiddle. Если кто-то хочет поиграть. Я добавил событие movestart, чтобы показать, что хочу, но на самом деле он не существует.

Используйте случай! можно спросить: у меня есть остановки на картах с почти полноэкранными инфо-окнами. Пользователи могут переключиться на следующий маркер из infowindow. Я делаю окна полупрозрачными, чтобы показывать панорамирование карты внизу, поэтому пользователи получают контекст, где находится следующее местоположение. Это отлично работает в OpenLayers2 с событиями movestart и moveend. Но в новой версии карты OL3 я не могу получить событие movestart.

Обновление: я ответил на вопрос сам, но я все еще предлагаю награду, если кто-то хочет предложить лучшее решение.

4b9b3361

Ответ 1

UPDATE v4.2.0 теперь поддерживает собственные события movestart и moveend

map.on('movestart', function(event) {

    //To Remove after first use: ol.Observable.unByKey(event);
});

map.on('moveend', function(event) {

    //To Remove after first use:  ol.Observable.unByKey(event);
});

Для версий OpenLayers 3 до версии v4.2.0

Хорошо, так что в среднем, без события movestart, а при moveend только срабатывании, если есть фактическое движение на карте, вот как я смог достичь поведения movestart и moveend.

jsFiddle:

var pan = ol.animation.pan({
    duration: 700,
    source: this.map.getView().getCenter()
});
map.beforeRender(function(map, frameState) {
    var stillPanning = pan(map, frameState); // returns false panning is done
    if (stillPanning) {
        // do movestart stuff here
        if (!everDone) {
            doSomething();
            everDone = true;
        }
    } else {
        // do move end stuff here
        undoSomething();
        everDone = false;
    }
    return stillPanning;
});
map.getView().setCenter(geom);

Так почему это работает?

  • ol.animation.pan возвращает a ol.PreRenderFunction, который возвращает false, если анимация не завершена

  • Написание пользовательской функции и ее предоставление map.renderBefore теперь можно использовать для записи обертки вокруг анимации панорамирования, как показано выше.

  • Весь бизнес с everDone заключается в том, что раздел stillPanning будет вызываться несколько раз. Это нормально, если то, что вы хотите сделать, может принимать повторяющиеся вызовы, но если вы хотите что-то переключить, вы хотите сделать это только один раз.

поведение "moveend" moveend Обратный вызов запускается только в том случае, если карта действительно перемещается. Это прекрасно, но это мешает нам выполнять пред-анимационные действия, просто делая их до анимации. Если у вас был сценарий, в котором карта фактически не перемещается, то что бы вы делали до анимации никогда не будет undo, потому что это поведение находится в moveend, который никогда не вызывается!

Надеюсь, это поможет кому-то. Мне пришлось потратить два хороших часа, чтобы заставить меня работать для меня, потому что отсутствует обратный вызов movestart: (

ОБНОВЛЕНИЕ

При дальнейшем обсуждении этой потока существует другое решение, предложенное @ahocevar. То есть использовать событие propertychange на представлении так:

function onpropertychange() {
  map.dispatchEvent('movestart');
  var view = map.getView();
  view.un('propertychange', onpropertychange);
  map.on('moveend', function() {
    view.on('propertychange', onpropertychange);
  });
};
map.getView().on('propertychange', onpropertychange);

Вот рабочий пример этого подхода: jsFiddle