-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Motivation
We have a number of issues in our issue queue that are regarding customizing various things regarding interactivity.
- Add
dragInertia
options for custom drag panning #8260 - contextmenu event should dissociate right click event from rotate/tilt event #8824
- [WIP] fixes #6884 Option to only enable zooming by scrolling while holding ctrl #6886
- add mobile gesture handling for pitch #3405
- Support multitouch two-finger panning #2618
- Draw box zoom in map perspective #1345
The idea with this proposal is to make this easier to do for developers by allowing them to bind their own event handlers declaratively at map init time, moving what we do in bind_handlers.js
up and out so developers can integrate their own implementations and not necessarily have to rely on passing options
and or activating/deactivating handlers that we have.
We can take this one step further, and extract our handlers and controls into separate npm packages ( similar to what babel and turf do ) so users not using our implementations don't have to pay the cost of the increased bundle size.
Design Alternative
The current status quo of adding additional options to Map
, and or exposing configuration though map.{handlerName}
.
This has the potential of adding a lot of cruft and complexity over-time as we try to accomodate additional requests.
Design
- A newly constructed
Map
isinteractive:false
by default, and this option gets removed from theMap
constructor. - Add a
map.bindInteractionHandlers(handlers: EventHandlers)
method, this is how you would add interactivity to the map.
type EventHandlers = {
mousemove: function() {..},
mousedown: function() {..},
mouseup: function() {..},
....,
}
- Separate out our interaction handlers to a separate sub-module, in order to enable the current state of
interactive: true
would look something like this.
import mapboxgl-interaction-handlers from '@mapbox/mapbox-gl-event handlers';
import mapboxgl from 'mapbox-gl-js';
// create an non-interactive map
const map = new Map(..);
// Add interactivity after the fact
map.bindInteractionHandlers(mapboxgl-interaction-handlers);
Pros:
- Lower bundle size
- Allows develops to fork our just interaction handlers and use them without having to fork entirety of gl-js if they need a different interaction paradigm.
- Developers already using existing gesture processing libraries like
hammer.js
can have better integration with the rest of their app.
Cons:
- API Breaking change :(
- Requires some refactoring within gl-js, we currently query the interaction state globally on
map
for things likezooming
hackily throughout the codebase. - Additional overhead on our side for maintaining an additional module and publishing and releasing it.