mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.11k stars 2.21k forks source link

Support two-finger panning with laptop touchpad #12932

Open olinoles opened 11 months ago

olinoles commented 11 months ago

Motivation

In certain contexts, map panning feels more intuitive for users on touch-pad enabled laptops when achieved through a two-finger gesture. This behaviour mirrors what is seen in other canvas-centric web applications like Figma, Canva, and Apple Maps for OSX. While these apps may not all be map-focused, the two-finger pan gesture has become a widely recognised mechanism for canvas panning.

From my observations, users who predominantly operate on laptops stand to benefit from having this gesture-based panning option. A related issue, #2618, was brought up by @JarnoLeConte back in 2016. It was only partially addressed with the introduction of the gestureHandling property. The attention it got, reflected by 50 thumbs-up reactions, suggests that there's at least some demand for such a feature.

Proposed Implementation

I was drawn to this feature for another project and successfully implemented this behaviour using a function that leverages the map.panBy method. This function, consisting of only 11 lines of code, also incorporates a helper function to identify touchpad scrolling.

Codepen example Try panning with a touchpad, and notice pinch-to-zoom and double-click behaviour is preserved.

function panHandler(e) {
  const trackPadSensitivity = 0.6;
  const mouseSensitivity = 0.1;
  if (!e.ctrlKey) {
    e.preventDefault();
    e.stopPropagation();
    const sensitivity = isTouchpad(e) ? trackPadSensitivity : mouseSensitivity;
    map.panBy([e.deltaX * sensitivity, e.deltaY * sensitivity], {
      duration: 0
    });
  }
}

I'd really appreciate any feedback and thoughts on this addition, particularly around the technical implementation. I'd be happy to put together a PR (my first contribution) if there is support for this feature.

Jdyn commented 3 months ago

Recently needed to implement this feature and your solution is working perfectly so far from a Macbook trackpad. Hopefully this can get added officially. Thanks for sharing.

edit: The only problem I have noticed is that since we are using panTo to make these micro movements and mimic real map movement, we get a large amount of movestart and movend events that don't actually indicate the start or end.

For now I added some custom event data to panTo and some debouncing and it works well since I did need to do some work after the panning ends.