Currently the scrollZoom option turns off onWheel handler. This prohibits not only zooming by scrolling but zooming by pinching on a touchpad, and also zooming by scrolling while pressing CTRL key.
We would need an option to override scroll zooming while CTRL key is pressed, in which case it would be fully backward compatible.
The option to achieve the behaviour that disables zooming while scrolling but enables zooming with scrolling while holding the CTRL key (or pinching on touchpad). So the example below would turn scrolling off, but would allow ctrl + scroll.
const mapOptions = {
scrollZoom: {
ctrl: true
}
};
This change might also need some kind of UI change, like GoogleMaps does on a touch device. But it's not necessary IMO.
This all should be changed on the client side, by extending the ScrollZoomHandler class. It bares the _enabled property currently, but would need a _ctrlEnabled property too. The name could be changed tho.
In which case the onWheel handler would need an extra condition, something like this:
// scroll_zoom.js
onWheel(e: WheelEvent) {
if (!this.isEnabled() && !(this.isCtrlEnabled() && e.ctrlKey)) return;
// ...
}
On how to handle this property I'm not quite sure, please advise.
Accidental closure, just wanted to cancel my reply, sorry.
We implemented something like this using some JS event handler, but found that on some browsers (Chrome on Linux and probably Windows too) holding Ctrl while scrolling zooms the page.
I've seen the meta/command key used more frequently for zooming the map, so that might be why.
We also tried Shift, but Mapbox seems to slow down the zoom when you hold shift. Although, we did also discover you can draw a zoom area while holding shift.
@nigelsim I can confirm that CTRL+Scrollwheel is mapped to the web browser page zoom controls on both Chrome and Firefox for Linux, but it seems be possible to avoid this behaviour.
Please have a look at https://developers.google.com/maps/documentation/javascript/interaction CTRL+Scrollwheel doesn't trigger the browser page zoom, they may be using something like event.preventDefault() / event.stopPropagation();
Can you share your JS event handler code?
Here's what we came up with
map.on("wheel", event => {
if (event.originalEvent.ctrlKey) {
return;
}
if (event.originalEvent.metaKey) {
return;
}
if (event.originalEvent.altKey) {
return;
}
event.preventDefault();
});
Thanks @epeli, you are spot on. Where I hit issues was that we show a div over the map with a message if CTRL isn't held down, but if you then started CTRL+Scrollwheel before that message had disappeared then the event caused the zoom action. Since we've sorted out all of the correct event listeners on each of the elements things have worked well.
I'm using MapBox via an AngularJS component, so most of the code isn't of a lot of use, but if you are still interested I'll unpick it from the rest of our component for you to have a look at.
Basically, we put an wheel event listener on the map. If it triggers without CTRL we set a class on it's parent which shows the overlay div. On a timeout that div is hidden again. There is also a scroll handler on the overlay div that will hide immediately if CTRL+scroll occurs as a way of dismissing that message.
We're just about to reimplement in Angular 7, so this feature will hopefully end up in whatever upstream component we use, and code won't require any unpicking.
Hello,
Based on @esamattis comment, I've managed to create a function to lock the default chrome/firefox "CTRL+Scroll" zoom behavior and allow zooming in mapbox instead.
By default, I'm disabling the mapbox scrollZoom, to allow normal scrolling on the page, but I reactivate it if CTRL key is pressed. I've also tweaked the wheel zoom rate using .setWheelZoomRate() :
map.scrollZoom.disable();
map.scrollZoom.setWheelZoomRate(0.02); // Default 1/450
map.on("wheel", event => {
if (event.originalEvent.ctrlKey) { // Check if CTRL key is pressed
event.originalEvent.preventDefault(); // Prevent chrome/firefox default behavior
if (!map.scrollZoom._enabled) map.scrollZoom.enable(); // Enable zoom only if it's disabled
} else {
if (map.scrollZoom._enabled) map.scrollZoom.disable(); // Disable zoom only if it's enabled
}
});
Most helpful comment
Here's what we came up with