From ea2ddc2620fec182e74350d7c3bccf2d9fc67514 Mon Sep 17 00:00:00 2001 From: kakkokari-gtyih <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sat, 11 Jul 2026 20:15:57 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=94=BB=E9=9D=A2=E5=A4=96=E3=81=AB?= =?UTF-8?q?=E3=83=89=E3=83=A9=E3=83=83=E3=82=B0=E3=81=A7=E3=81=8D=E3=82=8B?= =?UTF-8?q?=E3=81=AE=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/MkImageGallery.item.vue | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/packages/frontend/src/components/MkImageGallery.item.vue b/packages/frontend/src/components/MkImageGallery.item.vue index ba99aed408..7707b61be6 100644 --- a/packages/frontend/src/components/MkImageGallery.item.vue +++ b/packages/frontend/src/components/MkImageGallery.item.vue @@ -317,6 +317,26 @@ const hideForFallback = ref(!canOpenAnimation); const isZooming = ref(false); +function clampZoomTransform(nextTransform: { x: number; y: number; scale: number }) { + if (mainEl.value == null || nextTransform.scale <= 1) { + return { + x: 0, + y: 0, + scale: nextTransform.scale, + }; + } + + const rect = mainEl.value.getBoundingClientRect(); + const minX = rect.width - rect.width * nextTransform.scale; + const minY = rect.height - rect.height * nextTransform.scale; + + return { + x: Math.min(0, Math.max(minX, nextTransform.x)), + y: Math.min(0, Math.max(minY, nextTransform.y)), + scale: nextTransform.scale, + }; +} + function zoomInTo(x: number, y: number, factor = 1.1, withAnimation = false) { if (mainEl.value == null) return; @@ -334,9 +354,11 @@ function zoomInTo(x: number, y: number, factor = 1.1, withAnimation = false) { enableTransition.value = true; } - transform.value.x = newTranslationX; - transform.value.y = newTranslationY; - transform.value.scale = newScale; + transform.value = clampZoomTransform({ + x: newTranslationX, + y: newTranslationY, + scale: newScale, + }); } function resetToNeutral() { @@ -490,8 +512,11 @@ function onPointermove(ev: PointerEvent) { } if (isZooming.value) { - transform.value.x += deltaX; - transform.value.y += deltaY; + transform.value = clampZoomTransform({ + x: transform.value.x + deltaX, + y: transform.value.y + deltaY, + scale: transform.value.scale, + }); } else { if (isVerticalSwiping) { transform.value.y += deltaY; @@ -614,8 +639,11 @@ function updateInertia(timeStamp: number) { if (isDragging) return; if (!isZooming.value) return; if (Math.abs(pointerVec.x) < 0.01 && Math.abs(pointerVec.y) < 0.01) return; - transform.value.x += pointerVec.x * timeDelta; - transform.value.y += pointerVec.y * timeDelta; + transform.value = clampZoomTransform({ + x: transform.value.x + pointerVec.x * timeDelta, + y: transform.value.y + pointerVec.y * timeDelta, + scale: transform.value.scale, + }); pointerVec.x *= inertiaFactor ** (timeDelta / 16.67); pointerVec.y *= inertiaFactor ** (timeDelta / 16.67); }