新建useCropperTouch.js
javascript
// 导出一个函数,用于处理触摸事件,配合cropper.js
export function useCropperTouch(cropperRef) {
// 定义是否正在触摸的变量
let isTouching = false
// 定义初始角度
let startAngle = 0
// 定义初始距离
let startDistance = 0
// 定义当前旋转角度
let currentRotate = 0
// 定义当前缩放比例
let currentScale = 1
// 处理触摸开始事件
const handleTouchStart = (e) => {
// 如果触摸点数为2且Cropper存在
if (e.touches.length === 2 && cropperRef.value) {
// 设置正在触摸
isTouching = true
// 获取两个触摸点
const [touch1, touch2] = e.touches
// 计算初始角度
startAngle = Math.atan2(touch2.clientY - touch1.clientY, touch2.clientX - touch1.clientX)
// 计算初始距离
startDistance = Math.hypot(touch2.clientX - touch1.clientX, touch2.clientY - touch1.clientY)
// 获取当前状态
const data = cropperRef.value.getData()
currentRotate = data.rotate || 0
currentScale = data.scaleX || 1
}
}
// 处理触摸移动事件
const handleTouchMove = (e) => {
// 如果正在触摸且触摸点数为2且Cropper存在
if (isTouching && e.touches.length === 2 && cropperRef.value) {
// 阻止默认事件
e.preventDefault()
// 获取两个触摸点
const [touch1, touch2] = e.touches
// 计算当前角度
const currentAngle = Math.atan2(
touch2.clientY - touch1.clientY,
touch2.clientX - touch1.clientX
)
// 计算当前距离
const currentDistance = Math.hypot(
touch2.clientX - touch1.clientX,
touch2.clientY - touch1.clientY
)
// 计算旋转角度变化
const rotateDelta = (currentAngle - startAngle) * (180 / Math.PI)
// 计算缩放比例变化
const scaleDelta = currentDistance / startDistance
// 直接应用到 Cropper
cropperRef.value.rotateTo(currentRotate + rotateDelta)
cropperRef.value.scale(currentScale * scaleDelta)
// 更新初始值
startAngle = currentAngle
startDistance = currentDistance
currentRotate += rotateDelta
currentScale *= scaleDelta
}
}
// 处理触摸结束事件
const handleTouchEnd = () => {
// 设置不再触摸
isTouching = false
}
// 设置事件监听
const setup = (element) => {
if (!element) return
element.addEventListener('touchstart', handleTouchStart)
element.addEventListener('touchmove', handleTouchMove, { passive: false })
element.addEventListener('touchend', handleTouchEnd)
}
// 移除事件监听
const cleanup = (element) => {
if (!element) return
element.removeEventListener('touchstart', handleTouchStart)
element.removeEventListener('touchmove', handleTouchMove)
element.removeEventListener('touchend', handleTouchEnd)
}
// 在组件卸载前移除事件监听
onBeforeUnmount(() => {
if (cropperRef) {
cleanup(cropperRef)
}
})
// 返回设置和清理函数
return { setup, cleanup }
}
使用:
javascript
import { useCropperTouch } from '@/components/useCropperTouch'
const cropper = ref(null)
const { setup } = useCropperTouch(cropper)
// 设置触摸事件,viewImgRef为触摸图片的ref
setup(viewImgRef.value.parentElement)