From 7ff1a4269aa80ccc31e7d4ede3febcd207f40cf3 Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Thu, 9 Jul 2026 14:22:17 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=89=8D=E7=AB=AF=E7=95=8C=E9=9D=A2):=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8C=89=E6=AF=94=E4=BE=8B=E7=BC=A9=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/webui/ofdgo.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/assets/webui/ofdgo.js b/assets/webui/ofdgo.js index 89ee969..d10193c 100644 --- a/assets/webui/ofdgo.js +++ b/assets/webui/ofdgo.js @@ -2009,6 +2009,7 @@ function applyFit(updateStatus = true) { } function setScale(nextScale, updateStatus = true, fitMode = "free") { + const anchor = updateStatus && fitMode === "free" ? scaleAnchor() : null; const scale = Math.min(4, Math.max(0.2, nextScale)); const scaleChanged = Math.abs(scale - state.scale) > 0.001; state.fitMode = fitMode; @@ -2018,6 +2019,9 @@ function setScale(nextScale, updateStatus = true, fitMode = "free") { layoutPages(); } updateFitSpace(); + if (scaleChanged) { + restoreScaleAnchor(anchor); + } el.zoomLabel.textContent = `${Math.round(state.scale * 100)}%`; if (updateStatus && state.doc) { setStatus(`第 ${state.pageIndex + 1} / ${state.doc.pageCount} 页`); @@ -2025,6 +2029,34 @@ function setScale(nextScale, updateStatus = true, fitMode = "free") { updateControls(); } +function scaleAnchor() { + const shell = pageShellFromView() || pageShell(state.pageIndex); + if (!shell) { + return null; + } + const viewerRect = el.viewerPanel.getBoundingClientRect(); + const shellRect = shell.getBoundingClientRect(); + return { + index: Number.parseInt(shell.dataset.pageIndex, 10), + x: (viewerRect.left + viewerRect.width / 2 - shellRect.left) / Math.max(1, shellRect.width), + y: (viewerRect.top + viewerRect.height * 0.45 - shellRect.top) / Math.max(1, shellRect.height), + }; +} + +function restoreScaleAnchor(anchor) { + if (!anchor) { + return; + } + const shell = pageShell(anchor.index); + if (!shell) { + return; + } + const viewerRect = el.viewerPanel.getBoundingClientRect(); + const shellRect = shell.getBoundingClientRect(); + el.viewerPanel.scrollLeft += shellRect.left + shellRect.width * anchor.x - viewerRect.left - viewerRect.width / 2; + el.viewerPanel.scrollTop += shellRect.top + shellRect.height * anchor.y - viewerRect.top - viewerRect.height * 0.45; +} + function currentPageInfo() { return state.doc?.pages?.[state.pageIndex] || null; }