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

DragPan & Scroll behaviour mobile/desktop #9936

Closed
isthisstackoverflow opened this issue Sep 16, 2019 · 12 comments · Fixed by #10332
Closed

DragPan & Scroll behaviour mobile/desktop #9936

isthisstackoverflow opened this issue Sep 16, 2019 · 12 comments · Fixed by #10332

Comments

@isthisstackoverflow
Copy link

isthisstackoverflow commented Sep 16, 2019

Is your feature request related to a problem? Please describe.
I found it to be quite difficult to implement a scenario where all these requirements are fulfilled:

  • On desktop, DragPan works as it currently does ✔️
  • Mouse wheel scrolls past map ✔️ (easy with the focus condition, or just removing the interaction altogether)
  • On mobile, scroll past map with 1 finger ❌
  • On mobile, drag pan map with 2 fingers ❌

However, such a scenario is slowly becoming expected by users and customers due to Google Maps acting like that. (I personally like it better how OL does it, but oh well ...)

Describe the solution you'd like

Could the DragPan be changed to allow for the described behaviour? I think ideally a new flag would change the behaviour so that the same interaction works differently for mobile and desktop environments as described.

However, I have no idea how to distinguish between desktop and mobile environments properly, and my personal attempts of writing a new interaction as specified haven't worked.

@isthisstackoverflow
Copy link
Author

isthisstackoverflow commented Sep 16, 2019

I came up with this:

var map = new ol.Map({
  //   ...
  interactions: ol.interaction.defaults({ dragPan: false, mouseWheelZoom: false })
});

map.addInteraction(new ol.interaction.DragPan({
  condition: function(e) {
    return ol.events.condition.noModifierKeys(e) && (!/Mobi|Android/i.test(navigator.userAgent) || this.targetPointers.length === 2)
  }
}));

However, with this "solution" (jsfiddle) scrolling the page with 1 finger on the map is not possible. (Also, I should probably not use this.targetPointers?)

I am not entirely sure why, but it seems .ol-viewport having touch-action: none as element style is the problem. In #6767 (comment) it is suggested to use

.ol-viewport {
  touch-action: auto !important;
}

, which works fine in Firefox (Mobile), but does not work in Chrome (Mobile), where it ends panning/pinchzooming very quickly after starting.

I'm stuck and assume OL is currently simply not supporting what I'm trying to do?

Edit: Also updated fiddle to contain the onFocusOnly flag.
Edit2: Also tried the event propagation stop of #6767 (comment) to no avail.

@isthisstackoverflow
Copy link
Author

Inspired by #6767 (comment) I put together this codepen which behaves very googlemapsly. There's an oddity left where on reducing 2-finger-panning to 1-finger-panning by 1-finger-lifting it will both scroll and pan, but the rest seems to be fine.

It would still be great if there was official support for this, I'm just throwing some stuff around (and "my" solution's rather messy IMO).

@jahow
Copy link
Contributor

jahow commented Sep 23, 2019

Hi and thanks for taking the time to investigate this. Having the API evolve to support such a use case is definitely interesting although not very high on the (unwritten) priority list. Still, it'd be great if you could share any ideas on how to improve the API in that direction, especially since you struggled with this use case in the first place. I'll mark this issue as feature request. Thanks a lot!

@isthisstackoverflow
Copy link
Author

Thank you for labeling it right!

I'm not sure what the best approach to this would be. MouseWheel behaviour seems to be easy enough to configure, and DragPan can mostly be used the described way with a short condition. I just found OL exports ol/has.TOUCH, which can be used for that condition instead of the !/Mobi|Android/i.test(navigator.userAgent) I slapped on, too.

Leaves two problems:

DragPan will continue panning if its condition is no longer fulfilled (start two-finger dragging, can go on one-finger dragging when lifting only one finger)

This is probably about the check this.targetPointers.length === 0 in DragPan.prototype.handleUpEvent. Maybe it could be solved by adding || !this.condition_(mapBrowserEvent), as I assume the panning may both need to end when either no more pointer is left or the condition is no longer fulfilled.

However, that is a change in behaviour, and maybe somebody relies on this still working after the initial condition is no longer fulfilled?

Touch Events do not go through to elements outside map

I assume touch-action: none on .ol-viewport must stay since I found this comment in PluggableMap.js:

  // prevent page zoom on IE >= 10 browsers
  this.viewport_.style.msTouchAction = 'none';
  this.viewport_.style.touchAction = 'none';

If there was another way to fix this issue, that would be the more clean solution, I'd say. But I didn't really dig into what the issue resolved by this really is, and if there's another chance at circumventing it.

A workaround could be an interaction TouchScrollPage that adds extended code from the codepen above, and that can be configured to scroll the page on x, y, or both axes. But that's not really an interaction but rather the description of what happens on non-interaction with the map, and the code does not solve all situations yet. E.g., if the map is in a scrollable element within the page, the code would scroll the whole document instead of the scrollable sub-section. Maybe there's some other way to forward unused touch events to the next parent element despite touch-action: none?

@stale
Copy link

stale bot commented Nov 24, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Nov 24, 2019
@ahocevar
Copy link
Member

We had several improvements in the code recently that should make this easier. I‘ll put together an example that implements the desired behavior.

@dv00d00
Copy link

dv00d00 commented Feb 21, 2020

For peeps from a search engine like me:
Hosted example: https://openlayers.org/en/latest/examples/two-finger-pan-scroll.html?q=scroll
src: https://github.com/openlayers/openlayers/blob/master/examples/two-finger-pan-scroll.js

@deweydb
Copy link

deweydb commented Oct 5, 2023

For peeps from a search engine like me: Hosted example: https://openlayers.org/en/latest/examples/two-finger-pan-scroll.html?q=scroll src: https://github.com/openlayers/openlayers/blob/master/examples/two-finger-pan-scroll.js

This demo is no longer working as intended. I cannot scroll the page on mobile when my touch start is on the map.

@ahocevar
Copy link
Member

ahocevar commented Oct 5, 2023

@mike-000 Maybe your css changes from a while ago are related? #14906

@mike-000
Copy link
Contributor

mike-000 commented Oct 5, 2023

@mike-000 Maybe your css changes from a while ago are related? #14906

That did not go in until v7.5.0. v7.4.0 also does not scroll the page with a touch on the map https://openlayers.org/en/v7.4.0/examples/two-finger-pan-scroll.html and removing the css from the latest version has no effect on this issue. The issues fixed by #14906 related to pinch zoom so I suspect touch-action: pan-x pan-y; could have been used instead of touch-action: none;.

@mike-000
Copy link
Contributor

mike-000 commented Oct 5, 2023

Using touch-action: pan-x pan-y; looks promising on Android Chrome, you might want to check on other devices/browsers when the deploy preview for #15208 is available.

@deweydb
Copy link

deweydb commented Oct 5, 2023

Thank you! Looks like a good fix to me, I have tested the preview website located at:
https://deploy-preview-15208--ol-site.netlify.app/en/latest/examples/page-scroll.html
in
Safari iOS 15.4.1 iPhone 8
Opera 77.4.4095.74896 Android
Chrome 117.0.5938.61 Android

in all the above patch working as intended.

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

Successfully merging a pull request may close this issue.

6 participants