Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support dragPan.disable() mid-drag #2419

Closed
kristfal opened this issue Apr 11, 2016 · 13 comments · Fixed by #6232
Closed

Support dragPan.disable() mid-drag #2419

kristfal opened this issue Apr 11, 2016 · 13 comments · Fixed by #6232
Labels

Comments

@kristfal
Copy link

mapbox-gl-js version: Master branch

Steps to Trigger Behavior

  1. Start dragging the map (mouse or touch input)
  2. Set map.dragPan.disable() during the drag event

Expected Behavior

Dragging should no longer move the map.

Actual Behavior

Map will continue being draggable until mouseup or touchend

Afaik, the root issue is that event listeners can't be removed until the ongoing mousedown / touchstart event is finished.

Workaround:

Update the following drag_pan.js handlers:

_onDown: function (e) {
        if (this._ignoreEvent(e)) return;
        if (this.isActive()) return;
        if (!this._enabled) { // Added check for _enabled
            this._inertia = [];
            return;
        };

        if (e.touches) {
            document.addEventListener('touchmove', this._onMove);
            document.addEventListener('touchend', this._onTouchEnd);
        } else {
            document.addEventListener('mousemove', this._onMove);
            document.addEventListener('mouseup', this._onMouseUp);
        }

        this._active = false;
        this._startPos = this._pos = DOM.mousePos(this._el, e);
        this._inertia = [[Date.now(), this._pos]];
    },

    _onMove: function (e) {
        if (this._ignoreEvent(e)) return;
         if (!this._enabled) { // Added check for _enabled
            this._inertia = [];
            return;
        };

        if (!this.isActive()) {
            this._active = true;
            this._fireEvent('dragstart', e);
            this._fireEvent('movestart', e);
        }

        var pos = DOM.mousePos(this._el, e),
            map = this._map;

        map.stop();
        this._drainInertiaBuffer();
        this._inertia.push([Date.now(), pos]);

        map.transform.setLocationAtPoint(map.transform.pointLocation(this._pos), pos);

        this._fireEvent('drag', e);
        this._fireEvent('move', e);

        this._pos = pos;

        e.preventDefault();
    },
@lucaswoj
Copy link
Contributor

What are your thoughts, @bhousel?

@kristfal
Copy link
Author

The reason for wanting/needing to use dragPan.disable() mid-drag is that it is currently not possible to replicate the draggable marker functionality on touch devices.

On desktop, you can dragPan.disable() on mousemove (as per example) and lock the map prior to the drag event. On touch-devices, this is not possible, so the dragPan.disable() has to be called during the actual drag-event.

@averas
Copy link
Contributor

averas commented Apr 13, 2016

I identified more limitations (#2237) in the current interactions implementation a while back that probably, along with this, should be adressed in a broader re-design of how interactions are enabled/disabled and how interactions that depend on the state of others get such information...

@bhousel
Copy link
Contributor

bhousel commented Apr 13, 2016

should be adressed in a broader re-design of how interactions are enabled/disabled and how interactions that depend on the state of others get such information...

^ yes, this

@mcwhittemore
Copy link
Contributor

Being able to disable interactions better would be nice. We are stepping around this in a few places with Draw currently. Mostly with zoom on double click.

@lucaswoj
Copy link
Contributor

@bhousel I'd love to see a clean-slate reimagining of our interaction handlers, when you have some spare cycles 😄

@rajputneeru
Copy link

I got this error when app is in background and i am trying to open the app again ,i search a lot and get solution to disable map ,i tried this mapView.setEnabled(false); but unfortunately that's not working Anyone can help me to resolve this issue:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.orbis, PID: 15833
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.mapbox.mapboxsdk.maps.NativeMapView.createSurface(android.view.Surface)' on a null object reference
at com.mapbox.mapboxsdk.maps.MapView$SurfaceCallback.surfaceCreated(MapView.java:426)
at android.view.SurfaceView.updateWindow(SurfaceView.java:656)
at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:266)
at android.view.View.dispatchWindowVisibilityChanged(View.java:11139)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1290)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1855)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1550)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7190)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:959)
at android.view.Choreographer.doCallbacks(Choreographer.java:734)
at android.view.Choreographer.doFrame(Choreographer.java:670)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:945)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)

@krabbypattified
Copy link

+1 I'm running into the same exact issue as @kristfal (disabling dragPan mid-drag for mobile/touch devices). It is a crucial functionality for my app.
Is there any progress on this?

krabbypattified pushed a commit to krabbypattified/mapbox-gl-js that referenced this issue Oct 19, 2017
Allows draggable markers to work on mobile (touch) devices.
krabbypattified pushed a commit to krabbypattified/mapbox-gl-js that referenced this issue Oct 19, 2017
Allows the user to call map.dragPan.disable() mid-drag.
This enables draggable markers on mobile devices.
@krabbypattified
Copy link

I've created a pull request that fixes this issue.

krabbypattified pushed a commit to krabbypattified/mapbox-gl-js that referenced this issue Oct 27, 2017
@clemishow
Copy link

clemishow commented Jan 24, 2018

Really need this feature ! #5486

@krabbypattified
Copy link

@clemishow Agreed, this PR has been dead for a while! Can we get an owner to look at it again and help us get it accepted?

@clemishow
Copy link

@krabbypattified Yeah, and in addition it works perfectly

@sameerabit
Copy link

sameerabit commented Jan 21, 2020

This solved my problem.

map.on("mousemove", e => {
        var features = map.queryRenderedFeatures(e.point);
        if (features.length > 0) {
            if (hoveredStateId) {
                map.dragPan.disable();
                map.setFeatureState(
                    { source: 'states', id: hoveredStateId },
                    { hover: false }
                );
            }
                hoveredStateId = e.features[0].id;
                map.setFeatureState(
                { source: 'states', id: hoveredStateId },
                { hover: true }
            );
        }
    });
map.on("mouseleave", e => {
     var features = map.queryRenderedFeatures(e.point);
     if (features.length > 0) {
         map.dragPan.enable();
     }
 });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants