From 21057b1a6beff9a3d8a439b220b2c274ba5a54ff Mon Sep 17 00:00:00 2001 From: ji ruo <79234113+RuoJi6@users.noreply.github.com> Date: Fri, 30 Oct 2026 13:07:49 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=94=AF=E6=8C=81=E6=88=AA=E5=9B=BE?= =?UTF-8?q?=E6=94=BE=E5=A4=A7=E6=8B=96=E5=8A=A8=E5=B9=B6=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E7=BC=A9=E6=94=BE=E6=AF=94=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/markdown.tsx | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/web/src/components/markdown.tsx b/web/src/components/markdown.tsx index 8344cb4..f5b9070 100644 --- a/web/src/components/markdown.tsx +++ b/web/src/components/markdown.tsx @@ -18,6 +18,8 @@ function AuthenticatedImage({ const [captureTimestamp, setCaptureTimestamp] = React.useState(null); const [zoomed, setZoomed] = React.useState(false); const [zoomScale, setZoomScale] = React.useState(1); + const [pan, setPan] = React.useState({ x: 0, y: 0 }); + const dragRef = React.useRef<{ x: number; y: number; panX: number; panY: number } | null>(null); const imageSrc = typeof src === "string" ? src : undefined; React.useEffect(() => { @@ -29,6 +31,7 @@ function AuthenticatedImage({ setCaptureTimestamp(null); setZoomed(false); setZoomScale(1); + setPan({ x: 0, y: 0 }); return () => { cancelled = true; }; @@ -82,15 +85,36 @@ function AuthenticatedImage({ open={zoomed} onOpenChange={(next) => { setZoomed(next); - if (!next) setZoomScale(1); + if (!next) { + setZoomScale(1); + setPan({ x: 0, y: 0 }); + } }} > -
-
+
{ + if (zoomScale <= 1 || event.button !== 0) return; + event.currentTarget.setPointerCapture(event.pointerId); + dragRef.current = { x: event.clientX, y: event.clientY, panX: pan.x, panY: pan.y }; + }} + onPointerMove={(event) => { + const drag = dragRef.current; + if (!drag) return; + setPan({ x: drag.panX + event.clientX - drag.x, y: drag.panY + event.clientY - drag.y }); + }} + onPointerUp={(event) => { + dragRef.current = null; + event.currentTarget.releasePointerCapture?.(event.pointerId); + }} + onPointerCancel={() => { dragRef.current = null; }} + style={{ cursor: zoomScale > 1 ? (dragRef.current ? "grabbing" : "grab") : "default" }} + > +
{alt
+ {Math.round(zoomScale * 100)}%