UPDATE v4.2.0 now supports native movestart and moveend events
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);
});
For OpenLayers 3 versions before release of v4.2.0
Okay so in the mean while without the movestart
event, and with the moveend
only triggering if there is a actual movement in map, here's how I was able to achive movestart
and moveend
behavior.
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);
So why this works?
ol.animation.pan
returns a ol.PreRenderFunction
, which returns false if animation is not complete
Writing custom function and providing it to map.renderBefore
can be now used to write a wrapper around pan animation as shown above
The whole business with everDone
is because, stillPanning
section will get called multiple times. This is okay if what you want to do there can take repeated calls, but if you want to toggle something then you want to do it only once.
behavior of 'moveend'
moveend
callback is only triggered if map actually moves. This is fine, but it prevents us from doing pre-animation activities, by just doing them before animation done. If you had a scenario where map doesn't actually move, then what ever you did before animation will never undo
because that behavior is in moveend
which never gets called!
Hope this helps someone. I had to spend good two hours to get it to work for me, because a movestart
callback is absent :(
UPDATE
Upon more discussion on this thread there is another solution as suggested by @ahocevar. That is to use the propertychange
event on the view like so:
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);
Here's a working example of this approach: jsFiddle
precompose
event. See my jsFiddle: jsfiddle.net/j2cP4/116 – Rahprecompose
as it is not specifically targeted for move action. It will get triggered for any kind of map render, like for eg. a layer change. – Gilbertogilbertson