148 lines
3.5 KiB
TypeScript
Raw Normal View History

2024-11-05 10:14:41 +08:00
import { ref } from 'vue'
export interface TouchOptions {
/**
* @description
*/
disabled: boolean
/**
* @description
*/
left: number
/**
* @description
*/
right: number
/**
* @description
*/
top: number
/**
* @description
*/
bottom: number
/**
* @description
*/
faultTolerance: number
}
export const useTouch = () => {
// 触摸事件配置
const options: TouchOptions = {
disabled: false,
left: 0,
right: 0,
top: 0,
bottom: 0,
faultTolerance: 10,
}
// 开始坐标,减去开始坐标
const startX = ref(0)
const startY = ref(0)
// 当前坐标,减去开始坐标
const currentX = ref(0)
const currentY = ref(0)
// 移动偏移量
const deltaX = ref(0)
const deltaY = ref(0)
// 移动距离
const distanceX = ref(0)
const distanceY = ref(0)
// 移动方向
const isVertical = ref(false)
const isHorizontal = ref(false)
// 是否为点击
const isClick = ref(false)
// 标记开始触摸
let touchFlag: 'touch' | 'moving' | 'end'
// 更新配置
const updateOptions = (newOptions: Partial<TouchOptions>) => {
Object.assign(options, newOptions)
}
// 开始触摸事件
const onTouchStart = (event: TouchEvent) => {
if (options.disabled || !event.changedTouches[0]) return
startX.value = _edgeProcessing(event.changedTouches[0].pageX, 'x')
startY.value = _edgeProcessing(event.changedTouches[0].pageY, 'y')
touchFlag = 'touch'
}
// 开始滑动事件
const onTouchMove = (event: TouchEvent) => {
if (options.disabled || !event.changedTouches[0]) return
currentX.value = _edgeProcessing(event.changedTouches[0].pageX, 'x')
currentY.value = _edgeProcessing(event.changedTouches[0].pageY, 'y')
updateDistanceInfo()
touchFlag = 'moving'
}
// 触摸结束事件
const onTouchEnd = (event: TouchEvent) => {
if (options.disabled || !event.changedTouches[0] || touchFlag === 'end')
return
currentX.value = _edgeProcessing(event.changedTouches[0].pageX, 'x')
currentY.value = _edgeProcessing(event.changedTouches[0].pageY, 'y')
updateDistanceInfo()
isVertical.value =
distanceX.value < options.faultTolerance &&
distanceY.value >= options.faultTolerance
isHorizontal.value =
distanceX.value >= options.faultTolerance &&
distanceY.value < options.faultTolerance
isClick.value = !isHorizontal.value && !isVertical.value
touchFlag = 'end'
}
// 更新距离信息
const updateDistanceInfo = () => {
deltaX.value = currentX.value - startX.value
deltaY.value = currentY.value - startY.value
distanceX.value = Math.abs(deltaX.value)
distanceY.value = Math.abs(deltaY.value)
}
// 边缘位置处理
const _edgeProcessing = (
touchPosition: number,
direction: 'x' | 'y'
): number => {
const { left, right, top, bottom } = options
if (direction === 'x') {
if (touchPosition < left) return 0
if (touchPosition > right) return right - left
return touchPosition - left
} else {
if (touchPosition < top) return 0
if (touchPosition > bottom) return bottom - top
return touchPosition - top
}
}
return {
startX,
startY,
currentX,
currentY,
deltaX,
deltaY,
distanceX,
distanceY,
isVertical,
isHorizontal,
isClick,
updateOptions,
onTouchStart,
onTouchMove,
onTouchEnd,
}
}