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

Fix behavior in which releasing the CTRL-key before mouse button causes map to continue rotating #1888

Closed
averas opened this issue Jan 5, 2016 · 13 comments · Fixed by #4389

Comments

@averas
Copy link
Contributor

averas commented Jan 5, 2016

If you rotate a map with the CTRL-key and let go of the CTRL-key before you release the left mouse button the map will keep rotating even after releasing the left mouse button. Clicking on the map will not stop the rotation. The only way to stop the rotation is "grabbing" the map again with the CTRL-key.

This behaviour is quite unintuitive.

@planemad
Copy link

planemad commented Jan 5, 2016

Works fine for me on Chrome and Safari. @averas browser details?

@averas
Copy link
Contributor Author

averas commented Jan 5, 2016

@planemad Are you on PC/Windows or PC/Linux? I realised this might be related to Mac/OSX touchpad behaviour where CTRL-touchpad click is the same as right click. Would be great if someone else with a Mac could confirm my finding.

I see this behaviour in Chrome and Safari. In Firefox CTRL-click doesn't actually allow rotation as all.

@planemad
Copy link

planemad commented Jan 5, 2016

@averas i'm on OSX, using the touchpad

@averas
Copy link
Contributor Author

averas commented Jan 5, 2016

Now that's really odd.. Anyone else on Mac (El Capitan) with touchpad?

To add a little more detail:

  1. Go to https://www.mapbox.com/mapbox-gl-js/examples/
  2. Hold CTRL and click with touchpad on map
  3. Release the CTRL button while still holding the touchpad down
  4. Release the touchpad

At this point my map continues to rotate and the only way to get it to stop is do grab it again with CTRL-click as described above.

Btw. @planemad is rotation working at all for you in Firefox?

@planemad
Copy link

planemad commented Jan 5, 2016

@averas yes, I'm having the issue on https://www.mapbox.com/mapbox-gl-js/examples/ and other examples.

When tested on my own map this problem is not there.

@averas
Copy link
Contributor Author

averas commented Jan 5, 2016

👍 Same for me!

@jfirebaugh
Copy link
Contributor

Thanks, that's good intel. My hunch would be that this is only triggered if the map is in an iframe.

@averas
Copy link
Contributor Author

averas commented Jan 5, 2016

@jfirebaugh Good thinking. My maps that I initially discovered this behaviour on are not in iframes, however.

@lucaswoj lucaswoj changed the title Releasing the CTRL-key before mouse button causes map to keep rotate Fix behavior in which releasing the CTRL-key before mouse button causes map to continue rotating Jul 29, 2016
@stevage
Copy link
Contributor

stevage commented Jan 4, 2017

Related to #3389?

@rgtaylor1989
Copy link

I did some digging into the code on this issue (moved from #4187 to an open bug for discussion)

Mapbox GL Code

The issue is when the user lets go of ctrl and then lets go of the left mouse click, this._ignoreEvent(e) on line 128 returns "true" (https://github.com/mapbox/mapbox-gl-js/blob/master/js/ui/handler/drag_rotate.js#L128). This causes the rest of the _onUp(e) function not to run ... which causes the drag_rotate handler to be stuck on _onMove(e).

The problem is with _ignoreEvent(e) it seems? (https://github.com/mapbox/mapbox-gl-js/blob/master/js/ui/handler/drag_rotate.js#L193).

Is there any reason to have line 128? If removed it fixes this problem. I dont know if it will break anything else though by removing this line.

Different Approach (Maybe?!?!?!?!)

Wouldnt it be better to have a function that can change between the Rotation_Pan and Pan seamlessly? See my logic below and an example code. I am certain the code will not work because I am not that familiar with Mapbox GL ... so perhaps someone who knows more could make it work (if it is even possible).

Rotate Pan Handler
onmousedown --> was ctrl held || e.which == 3 //right click --> If true then run rotate_pan_handler
onmousemove ---> still holding ctrl || e.which == 3 --> if "true" then change the bearing, etc
onmousemove ---> still holding ctrl || e.which == 3 --> if "false" then grab information you need to start changing the bearing from that point and run the function to change the bearing, etc
onmouseup ---> stop changing the map and take off eventlisteners.

Panmap
onmousedown --> was ctrl held || e.which == 3 //right click --> If false then run pan_handler
onmousemove ---> did the user hit ctrl --> if true then grab information you need to start changing the bearing from that point and run the function to change the bearing, etc
onmousemove ---> did the user hit ctrl --> if false then pan the map
onmouseup ---> stop changing the map and take off eventlisteners.

this._el.addEventListener('mousedown', this._onDown);

_onDown(e){

  if(e.ctrlKey || e.which == 3){
      window.document.addEventListener('mousemove', this._onMove_RatPan);
      window.document.addEventListener('mouseup', this._onUp_RatPan);
  } else {
      window.document.addEventListener('mousemove', this._onMove_Pan);
      window.document.addEventListener('mouseup', this._onUp_Pan);
  }


}

_onMove_RatPan(e){

  //Are they still holding the control key or right click
  if(e.ctrlKey || e.which == 3){

      //***Change the map bearing and pitch here***

  //if they let go of the of control
  }else{

      //grab any information you need for the pan here? 

      //remove the event listeners for rotation.
      window.document.removeEventListener('mousemove', this._onMove_RatPan);
      window.document.removeEventListener('mouseup', this._onUp_RatPan);

      //switch to the pan functions
      window.document.addEventListener('mousemove', this._onMove_Pan);
      window.document.addEventListener('mouseup', this._onUp_Pan);
  }

}

_onUp_RatPan(e){
    // finish the rotate
}

_onMove_Pan(){

  //Did the user hit the control key
  if(e.ctrlKey){

      //grab any information you need for the pan rotate here? 

      //remove the event listeners for pan.
      window.document.removeEventListener('mousemove', this._onMove_Pan);
      window.document.removeEventListener('mouseup', this._onUp_Pan);

      //switch to the rotate pan functions
      window.document.addEventListener('mousemove', this._onMove_RatPan);
      window.document.addEventListener('mouseup', this._onUp_RatPan);
      
  }else{

      //***Change the map bearing and pitch here***
    
  }
}

_onUp_Pan(e){
    // finish the pan
}

@jaapster
Copy link

jaapster commented Mar 3, 2017

I have the same issue in Chrome and Firefox on MasOS. Both in the mapbox examples and in my own app (where the map control is not in an iframe)

@dannybloe
Copy link

Yeah, please please fix this bugger. I drives me crazy. We have to release our app next month and I'm considering to disable this feature (with pain in my heart) because I'm sure our customers will be very unhappy due to this.

@joshmaisey
Copy link

We also have the same issue on Chrome/Firefox/Safari on Mac OS X El Capitan. Also reproducing the issue on a Windows10 WM.

andrewharvey added a commit to andrewharvey/mapbox-gl-js that referenced this issue Mar 9, 2017
already released. Fixes mapbox#1888

The DragRotateHandler._keyUp method fires on a mouseup event so it can stop the
rotation/active state when you release the mouse button. However this
method also fires due to other interactions with the map such as
DragPan. So the _ignoreEvent method determines if the event mouseup or
other is to be ignored because it doesn't affect the DragRotateHandler.

This commit ensures that when the mouseup event happens on the left
mouse button without the Ctrl key pressed and DragRotate is still active
that the event is not ignored so that DragRotate can be deactivated.
lucaswoj pushed a commit that referenced this issue Mar 10, 2017
)

already released. Fixes #1888

The DragRotateHandler._keyUp method fires on a mouseup event so it can stop the
rotation/active state when you release the mouse button. However this
method also fires due to other interactions with the map such as
DragPan. So the _ignoreEvent method determines if the event mouseup or
other is to be ignored because it doesn't affect the DragRotateHandler.

This commit ensures that when the mouseup event happens on the left
mouse button without the Ctrl key pressed and DragRotate is still active
that the event is not ignored so that DragRotate can be deactivated.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
10 participants