hcg1023 / vue3-dnd

React Dnd implementation in Vue Composition-api.
https://www.vue3-dnd.com
MIT License
643 stars 52 forks source link

useDrag 如何实时获得 鼠标 的 offsetXY ? #27

Closed poerlang closed 2 years ago

poerlang commented 2 years ago

文档中提到,end 时,已经不再拖拽了,所以返回的 monitor.getXXXOffset 是 null,但我依然想获得鼠标松开时的坐标,如何做比较好?

hcg1023 commented 2 years ago

你可以试试再collect中持续记录鼠标位置,但是在monitor.getXXXOffset为null的时候,不修改你的collect值

hcg1023 commented 2 years ago

伪代码如下

let oldOffset = null
const [collect] = useDrag({
  end(){
    console.log(collect.value.offset, oldOffset)
  },
  collect(monitor) {
   const offset = monitor. getClientOffset()
   oldOffset = offset === null ? oldOffset : offset
   return {
      offset: oldOffset
   }
  }
})
poerlang commented 2 years ago

https://user-images.githubusercontent.com/3243514/184618861-17dcad92-d8b6-4ab6-8ec4-8fe65c57a3ce.mov

poerlang commented 2 years ago

我按你的写法再写一下试试

poerlang commented 2 years ago

image

奇怪了,得出的数值都是一样的,而且拖拽几毫秒后,数值就不再输出了。

可能是我这边的问题,我明天写个小 demo 测试测试。

hcg1023 commented 2 years ago

你可以试试用JSON.stringify,可能是对象log的问题

poerlang commented 2 years ago

OK,我试试

poerlang commented 2 years ago

image 还是一样,我回头建个新项目,测试一个官方例子,再看看

hcg1023 commented 2 years ago

ok,后续有问题继续沟通

poerlang commented 2 years ago

好的

hcg1023 commented 2 years ago

仔细看了你的代码,我觉得不变就是对的了吧?你只需要在end里边把这个oldOffset消费掉,再重置为null就可以了,因为你log的是oldOffset,按照我们的逻辑,当offset为null就取oldOffset

poerlang commented 2 years ago

我希望得到的是鼠标的轨迹,一系列变动的 {x,y}, 但 end 的时候得到的 xy 和 刚开始拖拽时得到的 xy 却是完全相同的 ...

poerlang commented 2 years ago

我先写个小测试看看

poerlang commented 2 years ago

https://oss.poerlang.com/github_test/vuednd/01/index.html drag-end-xy-test.zip

poerlang commented 2 years ago

https://user-images.githubusercontent.com/3243514/184784579-e5ebea27-eaf4-448f-9c2e-d687ef0f062a.mov

poerlang commented 2 years ago

image

poerlang commented 2 years ago

也许是我的理解错了, 这可能不是 bug,而是新需求:

期望: 当用户拖拽后保持悬停但未放开鼠标时,获得鼠标的实时轨迹,以便于向用户显示当前即将插入点的位置(插入到目标容器的上方、下方或别的位置)

但我目前获得的只是刚开始拖拽的起始点。

hcg1023 commented 2 years ago

我觉得我理解你的意思了,你希望做到拿到落点位置,并在drop容器的前边或者后边插入一个提示

这样的逻辑其实是要通过useDrop来实现,而不是通过useDrag

useDrop的hover函数以及drop函数都可以获取到你要的内容,并且当前drop元素就是你要的,你只需要对比当前hover的位置,你就能知道应该在前边还是后边

hcg1023 commented 2 years ago

Kapture 2022-08-16 at 10 38 54 确认一下是否是这个功能?类似我这个gif中的蓝色竖线

poerlang commented 2 years ago

对对对,就是这样的功能

poerlang commented 2 years ago

https://user-images.githubusercontent.com/3243514/184788201-59221a11-9806-4c39-8a4b-477d2cd82773.mov

https://oss.poerlang.com/github_test/vuednd/02/index.html

按你的说法,我把代码写到 useDrop 的 hover 回调中,这次拿到了实时坐标

poerlang commented 2 years ago

如果 useDrag 也能有 hover,那就好了

poerlang commented 2 years ago

当然,目前看来,useDrop 的 hover 暂时够用,只是阅读文档时容易错过。

hcg1023 commented 2 years ago

应该是够用的,而且这样最符合逻辑,让drop元素处理关于drop和hover的逻辑,drag不关注自己在哪个位置,只关心自己dragstar和dragend以后的逻辑

poerlang commented 2 years ago

image

我分析了一下我错过 hover 的原因,是以为 getClientOffset() 够用,并且认为这个函数是实时轨迹,但花了不少时间才发现,它只是起始点。

hcg1023 commented 2 years ago

我觉得我们可以在文档里提示一下,如果需要获取实时轨迹,应该关注一下DropTargetMonitor,这里的文档大部分是参照react-dnd翻译的,所以难免很简陋,如果你有兴趣的话,可以提一个Pull Request来补充一下

poerlang commented 2 years ago

28