import { ref } from 'vue' import { getTouchDistance, getClientPosition } from '../utils/touchGestures' /** * 手机拍照模式的取景逻辑 * 支持缩放和拖拽功能 */ export function useViewfinderA() { // 缩放限制 const MIN_ZOOM = 1 const MAX_ZOOM = 3 // 缩放级别 (保留用于点击按钮) const zoomLevels = [3, 2, 1] const currentZoom = ref(1) const isCapturing = ref(false) // 拍照闪光效果 // 拖拽相关状态 const isDragging = ref(false) const dragStartX = ref(0) const dragStartY = ref(0) const offsetX = ref(0) const offsetY = ref(0) const currentOffsetX = ref(0) const currentOffsetY = ref(0) // 双指缩放相关 const isPinching = ref(false) const pinchStartDistance = ref(0) const pinchStartZoom = ref(1) // 计算边界限制 const limitOffset = () => { const containerWidth = 871 const containerHeight = 420 const scale = currentZoom.value // 计算图片缩放后的尺寸 const scaledWidth = containerWidth * scale const scaledHeight = containerHeight * scale // 计算最大偏移量(图片边缘不能超出容器中心) const maxOffsetX = (scaledWidth - containerWidth) / 2 const maxOffsetY = (scaledHeight - containerHeight) / 2 // 限制偏移量 currentOffsetX.value = Math.max(-maxOffsetX, Math.min(maxOffsetX, currentOffsetX.value)) currentOffsetY.value = Math.max(-maxOffsetY, Math.min(maxOffsetY, currentOffsetY.value)) } // 设置缩放级别 const setZoom = (zoom: number) => { currentZoom.value = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, zoom)) limitOffset() } // 鼠标滚轮缩放 const handleWheel = (e: WheelEvent) => { e.preventDefault() // 滚轮向下是正数(缩小),向上是负数(放大) const delta = -e.deltaY * 0.001 const newZoom = currentZoom.value + delta setZoom(newZoom) } // 开始拖拽 / 触摸 const startDrag = (e: MouseEvent | TouchEvent) => { // 双指缩放 if ('touches' in e && e.touches.length === 2) { isPinching.value = true isDragging.value = false pinchStartDistance.value = getTouchDistance(e.touches[0], e.touches[1]) pinchStartZoom.value = currentZoom.value e.preventDefault() return } // 单指拖拽 if ('touches' in e && e.touches.length !== 1) return isDragging.value = true isPinching.value = false const { x: clientX, y: clientY } = getClientPosition(e) dragStartX.value = clientX dragStartY.value = clientY offsetX.value = currentOffsetX.value offsetY.value = currentOffsetY.value } // 拖拽中 / 缩放中 const onDrag = (e: MouseEvent | TouchEvent) => { // 处理双指缩放 if (isPinching.value && 'touches' in e && e.touches.length === 2) { const currentDistance = getTouchDistance(e.touches[0], e.touches[1]) const scale = currentDistance / pinchStartDistance.value setZoom(pinchStartZoom.value * scale) e.preventDefault() return } if (!isDragging.value) return const { x: clientX, y: clientY } = getClientPosition(e) const deltaX = clientX - dragStartX.value const deltaY = clientY - dragStartY.value currentOffsetX.value = offsetX.value + deltaX currentOffsetY.value = offsetY.value + deltaY limitOffset() // 防止滚动 if (e.cancelable) { e.preventDefault() } } // 结束拖拽 const endDrag = () => { isDragging.value = false isPinching.value = false } // 计算transform样式 const getTransform = () => { return `translate(${currentOffsetX.value}px, ${currentOffsetY.value}px) scale(${currentZoom.value})` } return { // 状态 zoomLevels, currentZoom, isCapturing, isDragging, currentOffsetX, currentOffsetY, // 方法 setZoom, startDrag, onDrag, endDrag, handleWheel, getTransform } }