Jump to content
Search Community

iOS10 Draggable pinch zoom UX Headache

Silverback IS test
Moderator Tag

Go to solution Solved by GreenSock,

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

I don't have a CodePen url as I don't think it's necessary to explain the issue but you'll be able to see what I mean on our website www.britishwebsites.co.uk

 

With a large draggable area, now that ios10 does not allow a developer to easily override the ability to pinch and zoom, it becomes necessary that the pinch-zoom functionality on a draggable area works. If you zoom into a large draggable area (our big map/island) you can not then zoom out again. You would have to zoom in on another part of the website then scroll into the map view, but it is possible to get completely stuck.

 

Are there any plans to make it so the draggable plugin can allow multiple touches to perform the default behaviour (i.e. zooming)?

 

I know I can disable pinch zooming through javascript still, but I suppose it is a good thing to allow users to zoom in on websites which is why Apple have decided to ignore user-scalable=no now.

Link to comment
Share on other sites

We'll have to look into this further and consider what's feasible but in its current state Draggable doesn't automatically enable native multi-touch gestures when multiple touches are on the same element. Again, not entirely sure that's even feasible at this point. I'll need some time to research/experiment.

Link to comment
Share on other sites

Jonathan: The behaviour is easily replicated on any draggable element in all existing demos. The difference is that the draggable element in our site is a large area. But essentially what I need to work out if I can do is perform native zooming with the touches starting on the draggable element. You can't zoom in or out when touching the draggable element, but if I zoom in on the page then scroll into a large area where the draggable element fills the screen, a user wouldn't then be able to zoom out or scroll away.

 

Jack: Thank you very much - I imagine it'd be a task and perhaps not possible, but thought it was worth asking the question. Thank you for your response. My other option is to disable pinch zooming using javascript which I think will be OK if there isn't another workaround.

 

Thanks both! Sorry for my delayed reply.

Link to comment
Share on other sites

I was thinking about this and I can't figure out a way around a central problem: when a touchstart occurs on an item, we must preventDefault() the event, otherwise the browser will do what it normally would on drag, like scroll the window or highlight text. But if we prevent that default behavior, then I'd imagine when the 2nd touch happens (for pinch-zoom), it can't really do its native behavior because the first event's default was cancelled. 

 

It's not hard to sense the 2nd touch and then allow the default behavior (don't call preventDefault()) but I suspect that's not really enough because half of the events that trigger the pinch-zoom were ignored (well, not ignored but the default behavior was prevented). 

 

Just kinda thinking out loud here; I'm not sure this dilemma has a solution. If anyone has ideas, I'm all ears. 

Link to comment
Share on other sites

Hello Jack, just throwing an idea?

 

What about using event.touches to detect multi touch? .. which returns an Array

 

https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches

 

To get a TouchList

 

https://developer.mozilla.org/en-US/docs/Web/API/TouchList

 

They have an example on that event.touches page that through a loop first checks the length of each touches touchstart event to find out how many touches were used by the user.

 

What makes it even more crazy is having to deal with each way the various browser support multi-touch. Especially since the other methods in the touch object are not widely supported yet in all browsers like radiusX, radiusY, or rotationAngle. As well as all modern browsers not supporting touchenter, touchleave, or touchcancel which would help do multi-touch in the browser without a polyfill like MagicTouch.js.

 

Just throwing out ideas for touch, which seems to be a huge beast for cross browser compatibility.

Link to comment
Share on other sites

Thanks Jonathan. The problem isn't sensing when there's a multi-touch, though. That's pretty trivial. It's more about the fact that on the FIRST touch, we preventDefault() on the event which kinda tells the browser "don't do what you'd normally do with this touch, like drag-scrolling, pinch-zooming, etc.". So it's more of an issue with properly handling preventDefault(), but you can't go back in time and say "oh, I know I told you to preventDefault() on that last touch, but I was just kidding - can you now ignore that request because there's another touch that happened?"

 

Tricky, I know. Not sure there's a solution. 

  • Like 1
Link to comment
Share on other sites

It's almost as if Apple have done something silly by not allowing developers to easily prevent zooming on mobile layouts :o

 

It does seem like it may not be possible if the first touch has to have default behaviours prevented. The only thing I could think is allowing a user to only zoom if both touches are simultaneous.

 

Also perhaps delaying the preventDefault() function by 200-300ms to see if there's a second touch but I'm not sure if that'd work either.

Link to comment
Share on other sites

Or alternatively...you could have a setting so that when you reach the boundary the touch move behaviour could scroll another element (by default the body perhaps). Kind of like how iOS scrollable elements work. You can scroll to the end, you get a bounce, but when the bouncing stops, if you then try and scroll down, the next parent element which is scrollable will start scrolling. That way at least you could get out of the area where you cannot pinch-zoom. (Wouldn't work for Google Maps, but I don't know if anyone is using draggable for an infinite sized canvas)

  • Like 1
Link to comment
Share on other sites

I wish there was a way to just delay the preventDefault() call by 200-300ms but that's just impossible because the browser needs an answer IMMEDIATELY about what it's supposed to do. In other words, if we don't give that answer right away, it'll impose the default behavior which is NOT what you want when dragging. 

 

I'll try to poke around and see if I can find any other viable solutions, but it's not looking great at the moment. 

Link to comment
Share on other sites

  • Solution

Yeah, I just did more testing and confirmed that in order to disable the native touch-scrolling (which is necessary, otherwise the entire page will move when you try touch-dragging the Draggable), preventDefault() must be called on the touchstart event, but doing so ALSO prevents native pinch-zooming. So the way touch events are implemented in the browser, it's forcing us to choose one or the other. Can't do both. Pretty frustrating, I know. 

 

If anyone knows of a workaround, please let us know. For now, it looks like it's simply impossible. 

  • Like 1
Link to comment
Share on other sites

What about the idea of scrolling the next scrollable parent (perhaps defined by the user) instead of bouncing if already at the container boundary? If enabled it could default to scrolling the body if enabled? Similar to a scrollable div in iOS with -webkit-overflow-scrolling:touch applied

Link to comment
Share on other sites

I'm a little confused - I thought we were talking about pinch-zooming and multi-touch. Your last comment seems to be talking about scrolling. Did I miss something? And by the way, the behavior you described is exactly what the autoScroll feature does already in Draggable :) (if I understood you correctly)

Link to comment
Share on other sites

  • 2 weeks later...

I'm a little confused - I thought we were talking about pinch-zooming and multi-touch. Your last comment seems to be talking about scrolling. Did I miss something? And by the way, the behavior you described is exactly what the autoScroll feature does already in Draggable :) (if I understood you correctly)

Sorry, you are correct, I didn't mean to confuse the situation! It is another potential solution to the main problem that a user can get completely stuck, and would provide a way they could scroll out of the draggable area to pinch and zoom.

 

Easiest to demonstrate on CodePen:

See the Pen VKNZZN by silverbackis (@silverbackis) on CodePen

 

So with the draggable area larger than the container, it'd be great if AutoScroll could be set to scroll the body when it reaches the edge of the container. I hope this helps to clarify, but I'm happy to start a new topic if this is not the best place to suggest this as an alternative way of preventing a user getting stuck.

 

Sorry for my delayed reply as well!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...