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

Drag scroll only in one direction #92

Open
mariusGundersen opened this issue Jan 12, 2025 · 8 comments · May be fixed by #93
Open

Drag scroll only in one direction #92

mariusGundersen opened this issue Jan 12, 2025 · 8 comments · May be fixed by #93

Comments

@mariusGundersen
Copy link

It would be nice if it was possible to only scroll the page either vertically or horizontally. The code should look at the client width/height and the scroll width/height to determine which orientation is scrollable. It could also look at the current scroll offset to determine that it shouldn't scroll anymore once it has reached the edges.

With this in place I think a further improvement would be for it to look for scrollable parents, so that it is also possible to scroll overflowing elements, not just the body.

@Pomax
Copy link
Member

Pomax commented Jan 12, 2025

Can you describe the use-case where this would come into play?

@mariusGundersen
Copy link
Author

I want to put a delete area at the bottom of the screen, so I can drag an element from a horizontal sortable list and drop it in the delete area to remove it. But it's a bit strange that the screen scrolls downwards when I drag something there, especially as there isn't any more content to scroll into view.

@Pomax
Copy link
Member

Pomax commented Jan 12, 2025

just so I understand you mean that even though the regular page can't scroll further down, using the drag polyfill causes the page to scroll anyway? Do you have a small (or reduced) test case that we can use to do some testing and dev work against?

@mariusGundersen
Copy link
Author

Here is a simple recreation: https://codepen.io/mariusgundersen/pen/JoPLzwd

@bitifet
Copy link

bitifet commented Jan 12, 2025

Having @mariusGundersen started the discussion, I'd provide a different (and maybe more generic) approach I conceived while thinking in similar problems.

It may be harder to implement (not sure up to which point) and I'm busy enough with may own side projects so I didn't say anything. So take it as what it is: Just a different point of view.

Getting to the point, the idea is to recognise some minimal gesture (like a "mostly" horizontal sweep followed by a "mostly" vertical sweep or vice-versa) as a sign that the user effectively wants to drag something.

Otherwise (if the initial movement is "mostly" horizontal or "mostly" vertical), the user is just trying to scroll (either horizontally or vertically).

The problem here is that just enabling the scroll when we "detect" that the user really want to scroll will produce a kind of "delay" effect that should be mitigated by, at least, producing the equivalent scroll in that direction to make it appear like just a simple delay (the delay taken by the system to identify if this is a scrolling or a dragging action).

This is similar that what happens with "click" and "double-click" events that, to detect a "double-click" we need to delay the "simple" click event to avoid the "click" event being triggered if the user is performing a "double-click" instead.

@mariusGundersen
Copy link
Author

I gave it a try to fix it and discovered that it's fairly easy to solve, much simple than I thought. This is it:

  _moveImage(e) {
    requestAnimationFrame(() => {
      if (this._img) {
-        let pt = pointFrom(e, true), s = this._img.style;
+        let pt = pointFrom(e, false), s = this._img.style;
-        s.position = `absolute`;
+        s.position = `fixed`;
        s.pointerEvents = `none`;
        s.zIndex = `999999`;
        s.left = `${round(pt.x - this._imgOffset.x)}px`;
        s.top = `${round(pt.y - this._imgOffset.y)}px`;
      }
    });
  }

This prevents the scrollable area from growing when dragging the clone

mariusGundersen added a commit to mariusGundersen/dragdroptouch that referenced this issue Jan 13, 2025
@Pomax
Copy link
Member

Pomax commented Jan 13, 2025

@bitifet that's more something for a gesture library, this polyfill is mostly to make sure that touch is supported at all rather than "interpreting what that touch means", so if it turns out this can be done in page code, by hooking into the touchstart/touchend events (with only as much code changes to allow for that of course), that may also end up being the solution.

@bitifet
Copy link

bitifet commented Jan 13, 2025

@Pomax as I said, my only intention was to provide a different point of view just in case it could be useful.

That being said, I'm not sure if I understood you well (or if I did not explain myself well).

If this is a «Polyfill that enables HTML5 drag drop support on mobile (touch) device» I understand it tries to enable it, at least preferably, without disabling other features like scrolling capabilities. And in desktop environment scrolling and dragging are handled by very different gestures (click + drag vs dragging scrollbars or using mouse wheel for instance) while in touch devices we use to scroll in both directions just by "dragging the whole document" so it is hard to differentiate when the user is trying to drag an element or if he's just trying to scroll the whole page.

I suggested a gesture to prevent scrolling when dragging is intended instead because also long tab has its own special use (usually double click).

I don't know this can (or should) be handled externally.

I just feel like it could bring touch devices capabilities closer to those of desktop computers and thought this idea could contribute to the debate.

I apologize if it did'nt go that way...

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

Successfully merging a pull request may close this issue.

3 participants