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

Recognize two gestures simultaneously via Hammer's recognizeWith method? #123

Closed
danDanV1 opened this issue Jan 23, 2019 · 9 comments
Closed

Comments

@danDanV1
Copy link

With the following config, only the swipe event is fired.

export default Component.extend(RecognizerMixin, {
  recognizers: "swipe pan",
  pan(e) {
    // do something with the event
    console.log("panning");
  },
  swipe(e) {
    console.log("swipe");
  },

If you swap the recognizer's order recognizers: "pan swipe" then only the pan event fires.

Hammer has a recognize-with method to recognize two gestures simultaneously, eg. pinch and rotate, or pan and swipe, etc.
http://hammerjs.github.io/recognize-with/

I couldn't find documentation or past issue covering. Is recognizing two gestures currently supported? If so, how to define the custom recognizer?

@danDanV1
Copy link
Author

danDanV1 commented Jan 23, 2019

I think I may have it now. Noting for documentation sake.

export default Component.extend(RecognizerMixin, {
  recognizers: "pan swipe",

with a custom pan.js recognizer:

export default {
  include: ["swipe"], //an array of recognizers to recognize with.
  exclude: [], //an array of recognizers that must first fail
  options: {},
  recognizer: "pan" // `tap|press|pan|swipe|rotate|pinch` the base Hammer recognizer to use
};

is that the recommended implementation?

@danDanV1
Copy link
Author

If this is the correct implementation, would help to have in the docs.

Should solve #86 (comment)

@danDanV1 danDanV1 reopened this Jan 23, 2019
@eriktrom
Copy link
Member

eriktrom commented Jan 24, 2019

@edeis53 - TBH - i don't recall, at least not in a way that i can verbalize. it's been a long time since i used hammer.js or this addon (i usually custom code such things in a rAF loop these days)

so i guess to answer ur q: does it do what you want? If so, why?

There are a few open issues with similar questions hanging around missing api docs and the "what is the api to use" in general, so while my answer is in the form of a question, if you can provide a rational explanation that i can pass on when this is asked again, would super love to hear it. Someone (u or i or another) could then also make docs w/o digging, since u just came back from digging...

If not no worries. thanks!

@danDanV1
Copy link
Author

@eriktrom yes, it does what I want it to do: recognize two gestures simulatenously.

eg. the equivalent of (Hammer.js docs)

var pinch = new Hammer.Pinch();
var rotate = new Hammer.Rotate();
pinch.recognizeWith(rotate);

is accomplished by my previous post with the custom pan recognizer. I compared my above implementation to a native hammer manager implementation, and the result matches.

Let me know if you have any questions. I've only been integrating this for a day or so thus far...

@eriktrom
Copy link
Member

eriktrom commented Jan 24, 2019

https://codepen.io/mortkire/pen/ZwGmbg

does the pan event never fire in ur opening comment or is it just hard to trigger that intermediate state?

cause it does, briefly in that codepen... which means... u found a 3+ year old bug, its been there since this addon was initially made..

here is a flow chart for how hammer works (embedded in the source code, useful). Possible state happens b/c we recognized pan. swipe is pan with acceleration detection.. a potential next possible state, one that must first recognize pan... specifically

If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
POSSIBLE to give it another change on the next cycle.

/**
 * Recognizer flow explained; *
 * All recognizers have the initial state of POSSIBLE when a input session starts.
 * The definition of a input session is from the first input until the last input, with all it's movement in it. *
 * Example session for mouse-input: mousedown -> mousemove -> mouseup
 *
 * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed
 * which determines with state it should be.
 *
 * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to
 * POSSIBLE to give it another change on the next cycle.
 *
 *               Possible
 *                  |
 *            +-----+---------------+
 *            |                     |
 *      +-----+-----+               |
 *      |           |               |
 *   Failed      Cancelled          |
 *                          +-------+------+
 *                          |              |
 *                      Recognized       Began
 *                                         |
 *                                      Changed
 *                                         |
 *                                  Ended/Recognized
 */

(found by trying to write some docs, hit wall when things didn't add up right according to ur issues in addon only...)

tbc - or ❤️ if u fix the addon logic :)

@eriktrom
Copy link
Member

eriktrom commented Jan 24, 2019

maybe instead of bug, better put is

the api could just be recognizers: "pan swipe", b/c that's all the information needed to say swipe depends on recognizing pan, in the simple cases.

and

mc.get('quadrupletap').recognizeWith('tap'); means 'quadrupletap depends on 4 taps'

the quadruple tap in their examples (https://codepen.io/jtangelder/pen/qeCAs) is more complicated, but order of 'pan swipe' vs 'swipe pan' OR 'tap quadrupletap' vs 'quadrupletap tap' should follow state chart regardless, which is an api inconsistency, at least from my point of view.

maybe this is just a braindump, as backwards compat could be issue, but open to thoughts (and prs cause im not using ember much right now so could be a while or never if left to me alone, tbh)

either way, thanks @edeis53 for the thorough explanation. now i know why so many people have asked this similar type of q

@eriktrom
Copy link
Member

for complicated use cases api could be:

recognizers: {
  include: ["swipe"], //an array of recognizers to recognize with.
  exclude: [], //an array of recognizers that must first fail
  options: {},
  recognizer: "pan" // `tap|press|pan|swipe|rotate|pinch` the base Hammer recognizer to use
};

and for re-use:

// pan.js although could name file what u want to reflect 2 simultaneous gestures happen, e.g., pan-swipe.js 
export default {
  include: ["swipe"], //an array of recognizers to recognize with.
  exclude: [], //an array of recognizers that must first fail
  options: {},
  recognizer: "pan" // `tap|press|pan|swipe|rotate|pinch` the base Hammer recognizer to use
};

// ur component

import { default as recognizers } from '../recognizers/pan'

export default Component.extend({
   recognizers,
});

food for thought - could this be non breaking change? anyone want to try?

@danDanV1
Copy link
Author

danDanV1 commented Jan 25, 2019

@eriktrom in my original comment the second recognizer is never fired.

recognizers: "swipe pan", pan never fires
recognizers: "pan swipe", swipe never fires.

I don't think we need to commit any changes to this addon. Works as designed with Hammer simultaneous gesture support. As you dug out, Hammer will only recognize Swipe or Pan as the detection is related, unless you declare the recognizeWith option.

Just a note in documentation should suffice, as end user could define infinite combinations of gestures, eg. pinch and rotate, etc.

I originally made a pan-swipe recognizer, but wasn't keen on panSwipeActionName events. It was confusing, because I wanted to detect panStart and swipeLeft events, etc. cause what's a panSwipeStart event? so I just declared my own pan recognizer.

@eriktrom
Copy link
Member

Thanks again for your response.

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

No branches or pull requests

2 participants