Reputation: 21
I add some marker to a mapbox map and let the fitBounds() method from geojson-extent.js adjust the map position and zoom.
map.fitBounds( geojsonExtent(geojson), {
padding: {top: 200, bottom:30, left: 30, right: 30}
});
The animation duration is set by default to five seconds. When the user do a mouse wheel interaction in this time over the map, the animation stops. No problem: The zoom stops the animation. But how can I prevent this?
I tried a lot of solutions:
1. disable the zoom
map['scrollZoom'].disable();
User can't scroll the map by mouse wheel, but animation still stops.
2. catch the wheel event
map.on('wheel', function(e) {
e.preventDefault();
});
User can't scroll the map by mouse wheel, but animation still stops.
3. disable user interaction completely
var map = new mapboxgl.Map({
interactive: false
});
Cool, animation is not being interrupted any more, but now the user can't pan the map. I found no solution to reset this property on run time or add navigation elements for panning.
4. set animation to important
map.fitBounds( geojsonExtent(geojson), {
essential: true,
padding: {top: 200, bottom:30, left: 30, right: 30}
});
No effect.
5. disable animation
map.fitBounds( geojsonExtent(geojson), {
animate: false,
padding: {top: 200, bottom:30, left: 30, right: 30}
});
This works, but it's a kind of workaround. I like to keep the animation.
6. add an overlay to block the user interaction
map.on('movestart', function(e){
$("#map-box").append('<div class="block-interactions"></div>');
});
map.on('moveend', function(e){
$("#map-box .block-interactions").remove();
});
.block-interactions {
position: absolute;
width: 100%;
height: 535px; /* map height */
}
This is my current solution and it works, but feels like a bad hack and is still a workaround.
So, do you have an other idea to prevent the animation being interrupted? At best with mapbox methods.
Thank you, for your help!
Upvotes: 2
Views: 2160
Reputation: 4710
You can disable interaction before calling fitBounds
and then re-enable it in response to moveend
and zoomend
events.
// define map here...
function disableInteraction() {
map.scrollZoom.disable()
}
function enableInteraction() {
map.scrollZoom.enable()
}
map.on('moveend', function() {
enableInteraction()
})
map.on('zoomend', function() {
enableInteraction()
})
// The next two lines should go wherever you want to invoke `fitBounds`
disableInteraction()
map.fitBounds(/* ... */)
You can modify disableInteraction
and enableInteraction
if you want to disable other forms of interaction besides scroll zoom. For example, to disable everything:
function disableInteraction() {
map.scrollZoom.disable()
map.boxZoom.enable()
map.dragRotate.enable()
map.dragPan.enable()
map.keyboard.enable()
map.doubleClickZoom.enable()
map.touchZoomRotate.enable()
}
Upvotes: 1