vueuse / gesture

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

does not rebind when domTarget changes #17

Open Sovai opened 2 years ago

Sovai commented 2 years ago

I use if/else on the domTarget and when it toggled, the gesture event stopped working. Is there a way to make it reactive? I try to call useGesture() again in watcher but it still does not solve my issue

lnvglr commented 1 year ago

I have the same problem, is there any progress on this?

slavarazum commented 1 year ago

An error occurs when a component is mounted after the component initialization:

Error: domTarget must be defined

Using with onMounted() hook doesn't help.

onMounted(() => {
    useDrag(dragHandler, {
      domTarget: dragEl,
    });
});
chenweifang4 commented 1 year ago

You may need to rebind when the component is visible, the following code works fine on my side.

const { motionProperties } = useMotionProperties(container, {
  scale: 1,
  rotateX: 0,
  rotateY: 0,
  rotateZ: 0,
  x: 0,
  y: 0,
});

const { set, stop } = useSpring(motionProperties as Partial<PermissiveMotionProperties>);

const dragHandler = (options: CommonGestureState) => {
  const [x, y] = options.offset;
  if (x === 0 && y === 0) {
    return;
  }
  set({
    x,
    y,
  });
};

watch(
  () => is_visible,
  () => {
    nextTick(() => {
      const { bind, clean } = useDrag(dragHandler, {
        domTarget: container,
      });
      if (is_visible.value) {
        bind();
      } else {
        clean();
        stop();
      }
    });
  },
  {
    deep: true,
  }
);
mcmimik commented 6 months ago

This issue seems to be quite prevalent and, unfortunately, it significantly blocks using the library in real life.

For those considering contributing with a PR, the problematic area can be found here: Controller.ts.

As a point of reference, Floating UI addresses a similar challenge gracefully using watchers. You can see their approach here: Floating UI :: useFloating, where they utilize:

watch([referenceElement, floatingElement], attach, {flush: 'sync'});

Hope, this might offer some inspiration for a solution.