mapbox-gl-js
mapbox-gl-js copied to clipboard
Easier way to disable all rotation and pitch
Sadly, most of the maps that I work on have no need for any 3D features or orientations other than north-up. But by default all these navigation features are enabled, which means eventually some poor user accidentally holds down control and gets very confused. Then I fumble through finding how to disable them all:
var map = new mapboxgl.Map({
...
pitchWithRotate: false,
dragRotate: false,
touchZoomRotate: false
).addControl(new mapboxgl.NavigationControl({ showCompass: false }), 'top-left');
Just a suggestion to consider making this easier, like maybe an option such as "fixedViewport: true" that would imply the others. Or just a note in the documentation explaining the above.
Want to submit a PR with an example containing the above code?
Interesting. There is this example "Disable map rotation" which purports to just disable rotation, but actually also disables pitch, which I wouldn't have expected.
Although, in that light, now that I read If false , the map's pitch (tilt) control with "drag to rotate" interaction will be disabled."
that makes sense - it just wasn't obvious to me at first.
The Disable map rotation example also fails to disable Shift+Left/Right Arrow rotations.
Anyone know how I can disable also the SHIFT + arrow keys?
@danichim my solution is fork the keyboardhandler, and change the keyboard handle, remove code to change rotation and pitch https://github.com/mapbox/mapbox-gl-js/blob/master/src/ui/handler/keyboard.js
then
m.keyboard.disable();
m.keyboard = new KeyboardWithoutPitchAndRotateHandler(m);
m.keyboard.enable();
import { Map } from "mapbox-gl";
const panStep = 100,
bearingStep = 15,
pitchStep = 10;
export class KeyboardWithoutPitchAndRotateHandler {
_map: Map;
_el: HTMLElement;
_enabled: boolean = false;
constructor(map: Map) {
this._map = map;
this._el = map.getCanvasContainer();
}
isEnabled() {
return !!this._enabled;
}
enable() {
if (this.isEnabled()) return;
this._el.addEventListener("keydown", this._onKeyDown, false);
this._enabled = true;
}
disable() {
if (!this.isEnabled()) return;
this._el.removeEventListener("keydown", this._onKeyDown);
this._enabled = false;
}
_onKeyDown = (e: KeyboardEvent) => {
if (e.altKey || e.ctrlKey || e.metaKey) return;
let zoomDir = 0;
let bearingDir = 0;
let pitchDir = 0;
let xDir = 0;
let yDir = 0;
switch (e.keyCode) {
case 61:
case 107:
case 171:
case 187:
zoomDir = 1;
break;
case 189:
case 109:
case 173:
zoomDir = -1;
break;
case 37:
if (e.shiftKey) {
// bearingDir = -1;
} else {
e.preventDefault();
xDir = -1;
}
break;
case 39:
if (e.shiftKey) {
// bearingDir = 1;
} else {
e.preventDefault();
xDir = 1;
}
break;
case 38:
if (e.shiftKey) {
// pitchDir = 1;
} else {
e.preventDefault();
yDir = -1;
}
break;
case 40:
if (e.shiftKey) {
// pitchDir = -1;
} else {
yDir = 1;
e.preventDefault();
}
break;
default:
return;
}
const map = this._map;
const zoom = map.getZoom();
map.easeTo(
{
duration: 300,
delayEndEvents: 500,
easing: easeOut,
zoom: zoomDir
? Math.round(zoom) + zoomDir * (e.shiftKey ? 2 : 1)
: zoom,
bearing: map.getBearing() + bearingDir * bearingStep,
pitch: map.getPitch() + pitchDir * pitchStep,
offset: [-xDir * panStep, -yDir * panStep],
center: map.getCenter(),
},
{ originalEvent: e },
);
};
}
function easeOut(t: number) {
return t * (2 - t);
}
There are easy ways to disable tilt for Android and iOS. Is there an equivalent for web?
+1 Pitch can be disabled easily using setMaxPitch or whatever, but to properly disable rotation you have to dig through the code and do all kinds of hacks. The "disable rotation" example doesn't actually disable rotation, just part of the interaction handlers. The keyboard and the navigationbutton (if you add it) can still rotate..
I believe the keyboard rotation/pitch is solved by map.keyboard.disableRotation()
. I have suggested this as an addition to this page.