Ответ 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
.
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
возвращает aol.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