fljot / Gestouch

Gestouch: multitouch gesture recognition library for Flash (ActionScript) development.
MIT License
356 stars 84 forks source link

Swipe Offsets #27

Closed sidesixmedia closed 11 years ago

sidesixmedia commented 12 years ago

Using both ORTHOGONAL and NO_DIRECTION for a SwipeGesture, we're seeing a lot of results where the magnitude of the X and Y offsets are the same (2 and -2, for example). This creates a 50/50 chance that the gesture is interpreted in the wrong direction than the user intended. We're being intentionally sloppy with our touches to see how well the framework can stand up to a fast paced grid game like Bejeweled.

Is there any way for us to tweak the Swipe instance to help avoid these scenarios? Can the offsets be decimal, for example? We tried playing with the slop parameter (pixels, I assume?), but that didn't appear to have any affect on our touch tests.

Thanks, fljot!

fljot commented 12 years ago

Well this is embarassing.. I'm telling this 3rd time, and 3rd time I swear I'll merge that hotfix into master and release it... But I don't do any flash development recently, so it always gets lost.

Try this https://github.com/fljot/Gestouch/tree/hotfixes/swipe-slop, I hope that works just as you expected. And briefly look through https://github.com/fljot/Gestouch/issues/18 and https://github.com/fljot/Gestouch/issues/23. Long story short — in the middle of fine tuning gestures I somehow removed correct slop evaluation from swipe. I think this one should be correct.

And now I swear I merge and release. You are the 3rd and it seems like you know what you want from these gestures=) Please confirm the hotfix.

sidesixmedia commented 12 years ago

Don't be embarassed...good things take time =). We'll pull the slop hotfix and review, but do you think that will actually help with the X/Y magnitudes being the same? I'm curious if those are actually tracked as decimals since their type is NUMBER or if they are only treated internally as integers? If the X/Y magnitudes were tracked with a bit more precision, even two decimal places, I'd imagine we wouldn't see these directional issues again.

Thanks for the update.

fljot commented 12 years ago

Normally all coordinates are integers, but just in case — who knows how the library could be used (some custom input adapters). So let it stay Numbers.

fljot commented 12 years ago

@sidesixmedia any luck?

sidesixmedia commented 12 years ago

Hi fljot. Sorry...project got pushed back for a couple of days. We pulled the slop branch and that definitely helped. We haven't had time to tweak the settings much yet, but will being doing so this weekend.

Related question: Is there a way to detect a swipe after the user has released their touch rather than as they move across the screen? So the swipe would require a touch, motion, and release?

fljot commented 12 years ago

What you describe is a different thing than common (well-designed) Swipe gesture. And you can't configure SwipeGesture to do that in this fashion since it's internal algorithm is aimed to make decision as soon as possible based on direction, distance & velocity. But it shouldn't be difficult to write your own.

joemontana commented 11 years ago

hey fljot i understand where you're coming from, but i think a swipe is made of touch begin, touch move and touch out (try on your iphone home screen, for instance). if you begin touching, move across the screen and dont touch out, the iphone home screen does not interpret it as a swipe, but just a pan (or if you touch, move fast and then move slowly, it isnt a swipe neither). i noticed the adobe's standard gesture also works in the way you mentioned, so i might code one doing 'touch in, move, touch out' that myself :) well, just my 2 cents. cheers

fljot commented 11 years ago

@joemontana sorry I didn't get your arguments =) could you repeat again? Unfortunately I don't have any iDevices, but I'm pretty sure there are really few usages of swipe gestures. One is swipe to the left in various UITableViews (in Mail for example) to remove items, another one is a global gesture with 4 fingers (swipe up) to show the list of recent/active apps. And Apple's UISwipeGestureRecognizer behaves exactly the same in this sense of recognizing before touch ends.

ghost commented 11 years ago

Hey joemontana, did you implement it? Because its sound very very sweet just reading about your eye for gesture-details :+1:

joemontana commented 11 years ago

@fljot i'll try to record and post on youtube so you can have a look at what i mean -- it's probably better than trying to describe it in words.

@Indyaner i did implement it on fljot's code, although i just ran a quick test and never actually used it. i suspect it works fine, but needs a checking when touching out (maybe the user took too long to get the finger out after it was recorded as a valid gesture?). i basically just added a flag 'shouldSwipe' where it was originally triggering. have a look at it here http://cl.ly/code/352v0a1C0b47

fljot commented 11 years ago

@joemontana from what I see in your example the sequence like "quick directional touch move + looooooooong pause (no movements) and then release -> recognized".. what kind of "gesture" is that?

joemontana commented 11 years ago

@fljot well, it's just the wrong behaviour -- your swipe is recognized at the time you move rather than "move + release". as i said, i didnt really test it, i just quickly hacked it to trigger when released. but i've done this http://www.youtube.com/watch?v=D4vXdfI69EE, i hope it helps to show what i meant with the swipe being recognized on the release only. of course, this is just a little suggestion ;)

fljot commented 11 years ago

@joemontana kudos for detailed video! But it's a common (as far as I notice myself) mistake for "swipe gesture" and "swipe the/on screen to ..." where first one is a technical thing and second one is a sort of casual word for touch scrolling paradigm.

Touch scrolling is (might be) based on Pan gesture since this is a continuous kind of interaction (and Pan gesture is continuous gesture). You move your finger — and interface continuously responds to your input e.g. moves scrollable content. When you lift your finger — throw happens (sometimes with snapping like in the case of iOS devices' home screen). To perform the throw that component must calculate your throw velocity (based on precede data we get from Pan gesture), which might be zero or just less than some threshold value, in which case we perform snapping with no "throw". In this case the snapping logic is: if we've scrolled more than half of viewport width (screen width) — switch to the next/previous page, otherwise snap to current page. You can see it all yourself. And there's simply no need in any other gesture here because all we do is panning, it's the only our interaction.

So we have one gesture that tracks touch movement. Why would we need anything else that just tracks movement? Well there are cases when we're not interested in receiving some data from the gesture all the time about where touch is, but we're rather interested in specific movement (quick directional movement). This is why Swipe gesture is kinda invented. Very important thing to note is that it's a discrete gesture (in opposite to Pan which is continuous). And why should it be recognized before touch ends (finger releases)? Because we wan't all gestures to be recognizes as soon as possible so that our UI is as much quick & responsive as possible. So as soon as we recognize desired direction and velocity — recognized. No point to wait for anything else to happen. Example of usages: swipe left to delete (show "delete" button) in Mail, Reminders apps or other UITableView based views on iOS devices, swipe left/right to change filters in some Instagram-like app (don't remember the name). There are not many actually, because Swipe is a bit of "hidden" kind of gesture since it's not recognized immediately (and therefore UI doesn't respond immediately).

joemontana commented 11 years ago

@fljot i see what you mean, so a swipe is a completely different gesture on its own. so i guess there must be a new gesture, something like "panswipe", where the pan/scrolling gets evaluated on release to see if there was a throw effort, in which case it then kicks a swipe. coolio. ;)

fljot commented 11 years ago

@joemontana well you could extend Pan and have some read-only property which you set before GestureEvent.GESTURE_ENDED like isThrow:Boolean, but this is a very specific, I would even say the only one use-case where we need such a thing. Also it's kinda of extra functionality that does not related to the touch analysis on it's own, but it's more about kind of calculations for UI behaviour in response to gesture (Pan). So for "good code" it's better not to place this analysis in the gesture itself, but rather perform in some other class like in the "touch-scroller" component itself, or as I do in independent TouchScrollModel class (that calculates everything such as panning, pulling, throw, bouncing, snapping, etc).

joemontana commented 11 years ago

@fljot i'm not extremely experienced in mobile development, but the 2 projects i worked on needed the panswipe gesture more than any other. it just gave a more humanly feel to those. i guess i would be using it more often if it was available, but surely it doesnt hurt to have that in the touch-scroller component.