我们在做一些有趣的交互的时候,让元素可以拖动是一个非常常见的需求。在motion元素上,我们可以非常方便地让一个元素可以被拖动,只要给元素设置一个drag属性就可以:

<motion.div
   // 只设置一个属性名,其实相当于设置改属性的值为true
   drag
/>

drag(拖拽)相配合的属性有很多,我大体上把他们分为三类:

👉基本设定 👉相关事件 👉交互控制

我们先介绍下前两个,最后一个内容比较多,我们放到下一篇文章中单独讲。

#

基本设定

dragMomentum

元素在拖拽放手后是否有惯性

布尔值

默认是true

如果设置为false,元素在放手后会直接停在原地,不会有任何后续运动

drag

是否让元素可以拖拽

可选值

布尔值

true或者是false,默认是false,即不能拖拽,true为可以任意方向拖拽

'x'

只能水平方向拖拽

'y'

只能垂直方向拖拽

dragTransition

这个设置的内容就是三种变化模式中的Inertia模式

#

拖拽事件

onDrag(event, info): void

当元素被拖拽时触发,一直拖一直触发

event:MouseEvent | TouchEvent | PointerEvent

info: PanInfo

<motion.div
  drag
  onDrag={
    (event, info) => console.log(info.point.x, info.point.y)
  }
/>

拖拽事件回调函数常见的参数设置一般是两个,前一个是事件对象,后一个是motion提供的和拖拽相关的信息,因为drag(拖拽)其实是pan行为的衍生,所以后面这个拖拽信息的对象被定义为是PanInfo

当需要和拖拽行为相关的数据时,一般通过PanInfo对象来获取。

Pan的行为可以理解成是手指按住屏幕或者鼠标按下按键状态下移动,只要手指或者鼠标移动超过3个像素,就可以理解为是pan,简单的说就是按住然后拖动(不管元素动没动)

PanInfo

这个对象有这些数据信息,这个信息都有x和y的值

point: 事件触发点的坐标值

delta: 和上一次触发点的距离

offset: 和一开始触发点的相比的偏移量

velocity: 当前触发点的速度值

onDragStart(event, info): void

当元素被拖拽开始时触发,只在开始时触发一次

event:MouseEvent | TouchEvent | PointerEvent

info: PanInfo

<motion.div
  drag
  onDragStart={
    (event, info) => console.log(info.point.x, info.point.y)
  }
/>

onDragEnd(event, info): void

当元素被拖拽结束时触发,只在结束时触发一次

event:MouseEvent | TouchEvent | PointerEvent

info: PanInfo

<motion.div
  drag
  onDragEnd={
    (event, info) => console.log(info.point.x, info.point.y)
  }
/>

onDirectionLock(axis): void

如果拖拽时元素被限制了拖拽的方向会触发

axis:"x" | "y"

<motion.div
  drag={'x'}
  onDirectionLock={axis => console.log(axis)}
/>

最后还有一个whileDrag,这个是比较特殊的,不是用来接回调函数的,而是用来设置某个变化信息对象或者状态名称的,我们在动画实现逻辑那篇内容中介绍过它了。

上一篇