h5移动端用户手势滑动方向获取

294 阅读1分钟

如何获取用户在移动端上手势操作dom的方向,话不多说,直接上货,看代码~

/**
 *
 * @param limit 手指滑动距离限制
 * @return {*&{touchend: touchend, touchstart: touchstart, touchMove: touchMove}}
 * 
 */
 
export const useTouch = (limit = 0, fun) => {
  const state = reactive({
    startX: '',
    startY: '',
    moveDirection: '', // 移动的方向
    direction: '' // 此刻的方向
  })
  // 滑动距离
  const distanceY = ref(0)
  const distanceX = ref(0)

  const touchstart = (event) => {
    state.startX = event.touches[0].pageX
    state.startY = event.touches[0].pageY
  }
  const getAngle = (angX, angY) => {
    return (Math.atan2(angY, angX) * 180) / Math.PI
  }

  const isShort = (angX, angY) => {
    // 如果滑动距离太短
    if (Math.abs(angX) < limit && Math.abs(angY) < limit) {
      return true
    }
    return false
  }

  const getDirection = (startX, startY, endX, endY) => {
    const angX = endX - startX
    const angY = endY - startY
    const angle = getAngle(angX, angY)
    if (isShort(angX, angY)) {
      // 距离过短
      return 0
    }
    return setDirection(angle)
  }

  /**
   * 设置方向
   * @param angle 角度
   * @return {number} 0|1|2|3|4 未滑动|上|下|左|右
   */
  const setDirection = (angle) => {
    let result = 0
    if (angle >= -135 && angle <= -45) {
      result = 1
    } else if (angle > 45 && angle < 135) {
      result = 2
    } else if (
      (angle >= 135 && angle <= 180) ||
      (angle >= -180 && angle < -135)
    ) {
      result = 3
    } else if (angle >= -45 && angle <= 45) {
      result = 4
    }
    return result
  }

  /**
   * 滑动
   * @param event
   */
  const touchMove = (event) => {
    const moveX = event.changedTouches[0].pageX
    const moveY = event.changedTouches[0].pageY
    distanceX.value = moveX - state.startX
    distanceY.value = moveY - state.startY
    const angle = getAngle(distanceX.value, distanceY.value)
    if (state.direction) {
      return
    }
    state.direction = setDirection(angle)
    if (isShort(distanceX.value, distanceY.value)) {
      // 距离过短
      console.log('距离短')
      return
    }
    console.log('当前的方向', state.direction)
    state.moveDirection = state.direction
  }

  const touchend = (event) => {
    state.direction = '' // 松手则清空方向
    const endX = event.changedTouches[0].pageX
    const endY = event.changedTouches[0].pageY
    state.moveDirection = getDirection(state.startX, state.startY, endX, endY)
    typeof fun === 'function' && fun()
  }

  return {
    ...toRefs(state),
    distanceX,
    distanceY,
    touchstart,
    touchMove,
    touchend
  }
}

给dom绑定监听事件

<div
  class="action-sheet-content"
  ref="actionSheetContent"
  @scroll="scroll"
  @touchstart="touchstart"
  @touchMove="touchMove"
  @touchend="touchend"
>
  <slot></slot>
</div>

hooks

const { moveDirection, touchstart, touchMove, touchend } = useTouch(50, end)