From 1d99465df27d064d8a08412b365f0737bdc76ace Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Wed, 8 Jul 2026 22:23:18 +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=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/webui/ofdgo.js | 58 ++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/assets/webui/ofdgo.js b/assets/webui/ofdgo.js index 5a6c74e..24d9abb 100644 --- a/assets/webui/ofdgo.js +++ b/assets/webui/ofdgo.js @@ -951,9 +951,6 @@ async function renderPage(index, options = {}) { scrollToPage(index); } queueNearbyPages(index, openSeq); - updatePageListCurrent(); - updateControls(); - setStatus(pageStatus(index, pageCount)); } catch (err) { if (openSeq === state.openSeq) { showError(err, false); @@ -1199,6 +1196,7 @@ async function processPageRenderQueue() { while (state.pageRenderQueue.length) { state.pageRenderQueue.sort(comparePageRenderTask); const task = state.pageRenderQueue.shift(); + let delayed = false; try { if (task.openSeq !== state.openSeq) { task.resolve(null); @@ -1213,6 +1211,11 @@ async function processPageRenderQueue() { task.resolve(null); continue; } + if (shouldDelayPageTask(task)) { + state.pageRenderQueue.push(task); + delayed = true; + continue; + } const page = callWASM("ofdgoRenderPage", task.index); if (task.openSeq === state.openSeq) { state.pageCache.set(task.index, page); @@ -1222,7 +1225,9 @@ async function processPageRenderQueue() { } catch (err) { task.reject(err); } finally { - state.pageInFlight.delete(task.key); + if (!delayed) { + state.pageInFlight.delete(task.key); + } } } } finally { @@ -1233,6 +1238,10 @@ async function processPageRenderQueue() { } } +function shouldDelayPageTask(task) { + return state.pageRenderQueue.some((next) => next.openSeq === state.openSeq && comparePageRenderTask(next, task) < 0); +} + function comparePageRenderTask(a, b) { return a.priority - b.priority || Math.abs(a.index - state.pageIndex) - Math.abs(b.index - state.pageIndex); } @@ -1298,28 +1307,29 @@ function schedulePageSync() { } function syncCurrentPageFromScroll() { - const shells = Array.from(el.svgHost.querySelectorAll(".page-shell")); - if (!shells.length) { + const shell = pageShellFromView(); + if (!shell) { return; } - const viewerRect = el.viewerPanel.getBoundingClientRect(); - const targetY = viewerRect.top + Math.min(viewerRect.height * 0.45, 280); - let nextIndex = state.pageIndex; - let best = Number.POSITIVE_INFINITY; - for (const shell of shells) { - const rect = shell.getBoundingClientRect(); - const distance = Math.abs(rect.top - targetY); - if (distance < best) { - best = distance; - nextIndex = Number.parseInt(shell.dataset.pageIndex, 10); - } - } + const nextIndex = Number.parseInt(shell.dataset.pageIndex, 10); if (Number.isFinite(nextIndex) && nextIndex !== state.pageIndex) { setCurrentPage(nextIndex); queueNearbyPages(nextIndex); } } +function pageShellFromView() { + const rect = el.viewerPanel.getBoundingClientRect(); + const x = rect.left + rect.width / 2; + return pageShellAtPoint(x, rect.top + rect.height * 0.45) + || pageShellAtPoint(x, rect.top + rect.height * 0.25) + || pageShellAtPoint(x, rect.top + rect.height * 0.65); +} + +function pageShellAtPoint(x, y) { + return document.elementFromPoint(x, y)?.closest?.(".page-shell") || null; +} + function setCurrentPage(index) { state.pageIndex = index; updatePageListCurrent(); @@ -1330,8 +1340,16 @@ function setCurrentPage(index) { } function updatePageListCurrent() { - for (const item of el.pageList.querySelectorAll(".page-list-item")) { - setPageItemCurrent(item, Number.parseInt(item.dataset.pageIndex, 10) === state.pageIndex); + const current = el.pageList.querySelector(".page-list-item[aria-current]"); + if (current) { + if (Number.parseInt(current.dataset.pageIndex, 10) === state.pageIndex) { + return; + } + current.removeAttribute("aria-current"); + } + const next = el.pageList.querySelector(`.page-list-item[data-page-index="${state.pageIndex}"]`); + if (next) { + setPageItemCurrent(next, true); } }