From bcacba59a12baaf892013e1c7625e17268a48ddc Mon Sep 17 00:00:00 2001 From: AfyerCu <20569838@qq.com> Date: Tue, 21 Oct 2025 09:55:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=89=8B=E5=8A=BF?= =?UTF-8?q?=E7=BC=A9=E6=94=BE=E5=8A=9F=E8=83=BD=E8=87=B3MarkingImageViewer?= =?UTF-8?q?New=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../renderer/MarkingImageViewerNew.vue | 83 ++++++++++++++++--- .../marking/composables/useSmartScale.ts | 61 +++++--------- 2 files changed, 94 insertions(+), 50 deletions(-) diff --git a/src/components/marking/components/renderer/MarkingImageViewerNew.vue b/src/components/marking/components/renderer/MarkingImageViewerNew.vue index d8fb1f3..06b9608 100644 --- a/src/components/marking/components/renderer/MarkingImageViewerNew.vue +++ b/src/components/marking/components/renderer/MarkingImageViewerNew.vue @@ -3,7 +3,6 @@ import type { KonvaMarkingData } from '../../composables/renderer/useMarkingKonv import type { ExamStudentMarkingQuestionResponse } from '@/api' import { markingSettings } from '../../composables/useMarkingSettings' import { useSmartScale } from '../../composables/useSmartScale' -import ScaleControlPanel from '../ScaleControlPanel.vue' import QuestionRenderer from './QuestionRenderer.vue' interface Props { @@ -21,6 +20,62 @@ const smartScale = useSmartScale(props.imageSize) const questionData = defineModel('questionData') +// 手势缩放相关 +const containerRef = ref() +const initialDistance = ref(0) +const initialScale = ref(1) +const isGesturing = ref(false) + +/** + * 计算两点之间的距离 + */ +function getDistance(touch1: Touch, touch2: Touch): number { + const dx = touch2.clientX - touch1.clientX + const dy = touch2.clientY - touch1.clientY + return Math.sqrt(dx * dx + dy * dy) +} + +/** + * 处理触摸开始 + */ +function handleTouchStart(e: TouchEvent) { + if (e.touches.length === 2) { + // 双指触摸,开始缩放手势 + isGesturing.value = true + initialDistance.value = getDistance(e.touches[0], e.touches[1]) + initialScale.value = smartScale.userScaleFactor.value + e.preventDefault() + } +} + +/** + * 处理触摸移动 + */ +function handleTouchMove(e: TouchEvent) { + if (e.touches.length === 2 && isGesturing.value) { + // 计算新的距离 + const currentDistance = getDistance(e.touches[0], e.touches[1]) + + // 计算缩放比例变化 + const scaleChange = currentDistance / initialDistance.value + + // 应用新的缩放比例 + const newScale = initialScale.value * scaleChange + smartScale.setScale(newScale) + + e.preventDefault() + } +} + +/** + * 处理触摸结束 + */ +function handleTouchEnd(e: TouchEvent) { + if (e.touches.length < 2) { + isGesturing.value = false + } +} + // 计算题目布局类 const questionsLayoutClass = computed(() => ({ 'questions-vertical': true, // 多题总是竖排 @@ -51,17 +106,20 @@ function handleMarkingChange(questionIndex: number, imageIndex: number, data: Ko