bsdfzzzy / vue2-hammer

Hammer.js wrapper for Vue 2.x to support some touching operation in the mobile.
MIT License
253 stars 48 forks source link

Use two gestures in combination? #30

Open ThomasKuhlmann opened 5 years ago

ThomasKuhlmann commented 5 years ago

Hi,

Hammerjs has an option for using two gestures in combination (e.g. swipe and pan) - http://hammerjs.github.io/recognize-with/ Is this implemented and if yes, how can it be enabled?

Right now when you use swipe and pan in conjunction, it behaves fine as long as you are using it in a simulated environment. Once you use it on an actual mobile device, the two gestures seem to conflict and give the feeling as if it's hard to move an item to the left or right.

Thanks!

bsdfzzzy commented 5 years ago

Yes it is supported now. Could you show me more detail? Your code. @ThomasKuhlmann

ThomasKuhlmann commented 5 years ago

Certainly!

background tile Changes colors depending on the delta

<v-list-tile  avatar>
  <v-list-tile-action v-if="interaction.direction==='right'">
    <v-icon :color="interaction.state==='selected'? 'white': 'red'">{{ rightSwipeIcon }}</v-icon>
  </v-list-tile-action>
  <v-list-tile-content/>
  <v-list-tile-action v-if="interaction.direction==='left'">
    <v-icon :color="interaction.state==='selected'? 'white': 'primary'">{{ leftSwipeIcon }}</v-icon>
  </v-list-tile-action>
</v-list-tile>  

Front tile moves when panned to reveal the action, resets when the pan ends and gets deleted when swiped

<v-list-tile 
  v-hammer:pan.left.right="(event)=>pan(event,index)"
  v-hammer:panend="()=>resetInteraction()"
  v-hammer:swipe.left.right="(event)=>swipe(event,item)"
  :key="index+'tile'"
  :style="moveTile(index)" 
  avatar
  @click="$emit('click', item)">
  <slot :item="item"/>
</v-list-tile>
 data() {
    return {
      interaction: {
        direction: null,
        delta: 0,
        index: null,
        state: "inactive"
      }
    };
  },
 pan(event, index) {
      this.interaction.direction = event.deltaX < 0 ? "left" : "right";
      if (
        (this.leftSwipeIcon && this.interaction.direction === "left") ||
        (this.rightSwipeIcon && this.interaction.direction === "right")
      ) {
        this.interaction.delta = event.deltaX;
        this.interaction.index = index;
        if (Math.abs(event.deltaX) > 40 && Math.abs(event.deltaX) < 80)
          this.interaction.state = "active";
        else if (Math.abs(event.deltaX) > 80)
          this.interaction.state = "selected";
        else this.interaction.state = "inactive";
      }
    },
    swipe(event, item) {
      if (this.leftSwipeIcon && event.type === "swipeleft")
        this.$emit("swipe:left", item);
      if (this.rightSwipeIcon && event.type === "swipeRight")
        this.$emit("swipe:left", item);
    },
    resetInteraction() {
      this.interaction.index = null;
      this.interaction.direction = null;
      this.interaction.delta = 0;
      this.interaction.state = "inactive";
    },

here's how it looks like on a mobile: https://files.fm/u/u7rhvut7