fix(web): lecteur défilement vertical — calculer le ratio de position sur la plage de défilement réelle pour ne plus rouvrir au milieu du livre (bug #39)

This commit is contained in:
Git Agent
2026-08-26 10:10:57 +02:00
parent f53419c9c8
commit fa2d4b8d98
2 changed files with 10 additions and 2 deletions

View File

@ -162,7 +162,7 @@ export function ReaderPage({ bookId }: { bookId: number }) {
const changeZoom = useCallback((nextZoom: number | ((currentZoom: number) => number)) => {
const stage = document.querySelector(".reader-stage") as HTMLElement | null;
const scrollRatioX = stage && stage.scrollWidth > stage.clientWidth ? (stage.scrollLeft + stage.clientWidth / 2) / stage.scrollWidth : 0.5;
const scrollRatioY = stage && stage.scrollHeight > stage.clientHeight ? (stage.scrollTop + stage.clientHeight / 2) / stage.scrollHeight : 0.5;
const scrollRatioY = stage && stage.scrollHeight > stage.clientHeight ? stage.scrollTop / (stage.scrollHeight - stage.clientHeight) : 0;
setZoom((currentZoom) => clampReaderZoom(typeof nextZoom === "function" ? nextZoom(currentZoom) : nextZoom));
@ -170,7 +170,7 @@ export function ReaderPage({ bookId }: { bookId: number }) {
requestAnimationFrame(() => {
if (!stage) return;
stage.scrollLeft = Math.max(0, stage.scrollWidth * scrollRatioX - stage.clientWidth / 2);
stage.scrollTop = Math.max(0, stage.scrollHeight * scrollRatioY - stage.clientHeight / 2);
stage.scrollTop = Math.max(0, (stage.scrollHeight - stage.clientHeight) * scrollRatioY);
});
});
}, []);

View File

@ -8,4 +8,12 @@ describe("ReaderPage vertical restore", () => {
expect(bookResetEffect).toContain("setPage(1)");
});
it("does not restore an unknown vertical scroll anchor to the middle of the book", () => {
const source = readFileSync(new URL("./ReaderPage.tsx", import.meta.url), "utf8");
const changeZoomBlock = source.slice(source.indexOf("const changeZoom = useCallback"), source.indexOf(" const zoomControls", source.indexOf("const changeZoom = useCallback")));
expect(changeZoomBlock).toContain("scrollRatioY");
expect(changeZoomBlock).not.toMatch(/scrollRatioY[\s\S]*:\s*0\.5/);
});
});