vueuse / gesture

🕹 Vue Composables making your app interactive
https://gesture.vueuse.org
MIT License
353 stars 18 forks source link

Dragging problem / Minimal drag example #16

Open rafaellehmkuhl opened 2 years ago

rafaellehmkuhl commented 2 years ago

I'm trying to reproduce a minimal drag example, where the user can drag a component somewhere, and it stays there. Problem is: the first time the user drags the component, it stays there, but as soon as he tries to re-drag the component, it goes back to the (0,0) position and begins the next drag from there.

gifgesture

My code is the following:

<template>
  <div ref="widgetRef" class="widget">
    <span>Widget</span>
  </div>
</template>

<script setup lang="ts">
import { useGesture } from '@vueuse/gesture'
import { type PermissiveMotionProperties, useMotionProperties, useSpring } from '@vueuse/motion'
import { ref } from 'vue'

const widgetRef = ref()

const { motionProperties } = useMotionProperties(widgetRef, {
  cursor: 'grab',
})
const { set } = useSpring(motionProperties as Partial<PermissiveMotionProperties>)

useGesture(
  {
    onDrag: ({ movement: [x, y] }) => set({ x, y, scale: 2 }),
    onDragEnd: () => set({ scale: 1 }),
  },
  {
    domTarget: widgetRef,
  }
)
</script>

<style scoped>
.widget {
  padding: 10px;
  margin: 5px;
  background-color: antiquewhite;
}
</style>
lotestudio commented 2 years ago

It's not so clear for me too... Dragging use translate3D to style position on the element while dragging. But every time when start dragging again the values reset to 0,0,0... I've tried with other options from state and set (like values), but no success... :(

thalida commented 1 year ago

Ran into this issue and was able to solve it with a hackity-hack™️ (as of ^2.0.0-beta.1).

This issue is fairly stale (is this package still supported?) Either way, commenting my "solution" for next person who finds this issue. If there's a proper/better way to do this please share!

gestureModule.config.drag.initial = [x, y];

Example Usage:

const gestureModule = useGesture(
  {
    onDrag: handleSurfaceDrag,
    onPinch: handleSurfacePinch,
    onHover: handleSurfaceHover,
    onWheel: handleSurfaceScroll,
  },
  {
    domTarget: surfaceEl,
    eventOptions: { passive: false },
  }
);

function handleSurfaceDrag({
  movement: [x, y],
  dragging,
}: {
  movement: [number, number];
  dragging: boolean;
}) {
  if (!dragging) {
    return;
  }

  doSomething({x, y});

  // update initial point for next drag
  gestureModule.config.drag.initial = [x, y];
}

I also ran into this issue with onWheel, but I needed to update the state instead:

gestureModule.state.wheel.values = [x, y]
viniciusdeliz commented 5 months ago

@rafaellehmkuhl have you got around this issue? were you able to use @vueuse/gesture in production or have you opted to use another solution?

rafaellehmkuhl commented 5 months ago

I gave up on this one and I'm now using vue-draggable-plus. It's pretty good, and maintaned by one of vue-use contributors.