koca / vue-use-gesture

👇 Bread n butter utility for component-tied mouse/touch gestures in Vue
https://vue-use-gesture.netlify.app
MIT License
152 stars 9 forks source link

An example of use-gesture would be very nice. #3

Open bluelemonade opened 3 years ago

bluelemonade commented 3 years ago

An example of use gesture would be very nice. currently there are only examples in example-vue-2 for the other gestures, I am interasted in a drag & rotate gesture

thanks for the amazing work, I actually struggle with interactjs...

actually I try to make a draggable component, in the end with scopes to put different content in it. I used the use-drag file, but got some errors. here's my base app

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/> 
     <dragcard/>
     <dragcard/>  
     <dragcard/>  
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
import dragcard from './components/use-drag.vue'

export default {
  name: 'App',
  components: {
    HelloWorld,
    dragcard
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

in your file I made the root div more generic to get a container to fill with other stuff. It works but it throws an error.

vueusegesture.esm.js?b67e:1312 Deprecation notice: When the domTarget option is specified, you don't need to write useEffect(bind, [bind]) anymore: event binding is now made handled internally to this lib. Next version won't return anything when domTarget is provided, therefore your code will break if you try to call useEffect.

I saw in the pinch demo that you use v-on="bind()" and not the domTarget in the gesture method. Ok, when I change this, comment out the { domTarget: refEl } and use the bind, Now error, but now interaction.

Would be nice to get a little help,

in the next step I will take over the drag into the gesture and integrate the pinch. but first i have to bring my knowledge of composition api up to date.

<template>
    <div id="drag-card" ref="refEl" :style="transformStyle">
    <!-- <div id="drag-card" ref="refEl" :style="transformStyle" v-on="bind()"> -->
        <div class="area w-20 h-20 bg-blue-300 rounded-2xl"> </div>
    </div>
</template>

<script>
import { useDrag, useSpring } from 'vue-use-gesture'
import { defineComponent, computed, ref } from '@vue/composition-api'

export default defineComponent({
  setup() {
    const refEl = ref()
    const transform = useSpring({ x: 0, y: 0 })

    // bind doesn't work for vue 2 bec of event names we can change listener names using vue-demi
    const bind = useDrag(
      ({ down, movement: [mx, my] }) => {
        transform.x = down ? mx : 0
        transform.y = down ? my : 0
      }  ,
       { domTarget: refEl }
    )
    console.log(bind())

    const transformStyle = computed(() => {
      const style = { transform: `translate3d(${transform.x}px,${transform.y}px,0)` }
      return style
    })

    return {
      refEl,
      bind,
      transformStyle,
    }
  },
})
</script>

<style>
.area {
  touch-action: none;
  cursor: -webkit-grab;
  cursor: grab;
}
</style>
bluelemonade commented 3 years ago

I put the pinch and the drag into one component,

but there's a problem: when using the v-on="bind()" on the div I can pinch when I deactivate the domtarget. When I use the domTarget option a, delete the v-bind I can drag the rects around, but I can't pinch!

strange, Would be nice to get an advice. thank you.

and I saw the https://codesandbox.io/s/rkgzi?file=/src/index.js react demo, would be nice to move and pinch at the same time, acutally that is not possible.

regards

<template>
    <!-- <div id="drag-card" ref="refEl" :style="transformStyle" class="scale-element" > -->
    <div id="drag-card" ref="refEl" :style="transformStyle" class="scale-element" v-on="bind()">
      <div class="area bg-blue-300 rounded-2xl"> </div>
    </div>
</template>

<script>
import { useSpring, useGesture } from 'vue-use-gesture'
import { defineComponent, computed, ref } from '@vue/composition-api'

export default defineComponent({
  props: {
    startX: Number,
    startY: Number,
  },
  setup(props) {
    console.log(props.startX, props.startY);
    const refEl = ref()

    const transformer = useSpring({ x: props.startX, y: props.startY, scale: 1, rotate: 0 })
    const startColor = ref('#ff0000');

    const bind = useGesture(
      { 
        onDragStart: () => { 
         console.log("onDragStart");
        },
        onDrag: ({ offset: [dx, dy] }) => { 
          transformer.x = props.startX + dx;
          transformer.y = props.startY + dy;
        },
        onPinchStart: () => { 
         console.log("onPinchStart");
        },
        onPinch: ({ offset: [d, a] }) => { 
          console.log("onPinch");
          transformer.scale = 1 + d / 200;
          transformer.rotate = a;
        },
      },
      //  { domTarget: refEl } 
    )

    const transformStyle = computed(() => (
        { 
         transform: `translate3d(${transformer.x}px,${transformer.y}px,0) rotate(${transformer.rotate}deg) scale(${transformer.scale})`,
         backgroundColor: startColor.value,
        }
        )
    )

    return { bind, transformStyle, refEl }

  },
})
</script>

<style>
.area {
  touch-action: none;
  cursor: -webkit-grab;
  cursor: grab;
  width: 200px;
  height: 200px;
}

.scale-element {
  position: absolute;
  border-radius: 0px;
  /* display: block; */
  /* width: 800px;
  height: 800px; */
  margin: auto;
  touch-action: none;
  /* background-color: red; */
}

/* .drag {
  position: relative;
  width: 200px;
  height: 200px;
  background: grey;
  border-radius: 5px;
  box-shadow: 0px 10px 30px -5px rgba(0, 0, 0, 0.3);
  transition: box-shadow 0.5s, opacity 0.5s;
  will-change: transform;
  border: 10px solid white;
  cursor: grab;
  overflow: hidden;
  touch-action: none;
} */
</style>
koca commented 3 years ago

Hey @bluelemonade ^^ I'll get back to you tomorrow. Sorry about the late response im kinda busy this week 🙏

bluelemonade commented 3 years ago

thanks for your response. that's what I tried to do: https://codesandbox.io/s/rkgzi?file=/src/index.js:1644-1649 I got the drag OR the pinch to work, the pinch did stay also in place, no movement...

edited, in the meantime i have been working with the drag gesture, works great, the spring integration is great too. unfortunately the pinch doesn't work yet.

I have a card with content, sometimes text to scroll, sometimes an svg with drag & drop games, this content is added via slots. everything works wonderfully.

I gave stop propagation to the pointer events, start move and up to the inside area into which I load the components, as well as the background of the svgs, unfortunately the gsap drags no longer work, and sometimes the drags also arrive on the card. any ideas, how can I stop the pointerevents to reach the card.