fix(web): lecteur mobile — stabiliser le pinch-zoom (ancrage du point médian sous les doigts avec restauration du scroll par page, gel du commit vertical via data-reader-pinch-active pendant le pincement, preventDefault sur touchstart et touch-action: pan-x pan-y pour bloquer le zoom natif — correctif bug #43)
This commit is contained in:
@ -5,7 +5,7 @@ import { CbzReader } from "../reader/CbzReader";
|
||||
import { EpubReader } from "../reader/EpubReader";
|
||||
import { pageLocator, parseCbrPageLocator, parseCbzPageLocator, parsePdfPageLocator, pdfPagePercent } from "../reader/locators";
|
||||
import { PdfReader } from "../reader/PdfReader";
|
||||
import { ReaderShell, type ReaderControls, type ReaderModeControls, type ReaderZoomControls } from "../reader/ReaderShell";
|
||||
import { ReaderShell, type ReaderControls, type ReaderModeControls, type ReaderZoomAnchor, type ReaderZoomControls } from "../reader/ReaderShell";
|
||||
import { clampReaderZoom, READER_ZOOM_DEFAULT, READER_ZOOM_STEP } from "../reader/readerLayout";
|
||||
import { majorityVisiblePage, type ReaderMode } from "../reader/readerScroll";
|
||||
import { useReaderPreferences } from "../reader/useReaderPreferences";
|
||||
@ -159,7 +159,7 @@ export function ReaderPage({ bookId }: { bookId: number }) {
|
||||
setMode("horizontal");
|
||||
saveReaderMode("horizontal");
|
||||
}, [currentVisiblePage, page, saveReaderMode]);
|
||||
const changeZoom = useCallback((nextZoom: number | ((currentZoom: number) => number)) => {
|
||||
const changeZoom = useCallback((nextZoom: number | ((currentZoom: number) => number), anchor?: ReaderZoomAnchor) => {
|
||||
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.scrollHeight - stage.clientHeight) : 0;
|
||||
@ -169,6 +169,14 @@ export function ReaderPage({ bookId }: { bookId: number }) {
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
if (!stage) return;
|
||||
if (anchor) {
|
||||
const target = stage.querySelector<HTMLElement>(`[data-reader-page="${anchor.page}"]`);
|
||||
if (!target) return;
|
||||
const rect = target.getBoundingClientRect();
|
||||
stage.scrollLeft += rect.left + anchor.offsetX - anchor.clientX;
|
||||
stage.scrollTop += rect.top + anchor.offsetY - anchor.clientY;
|
||||
return;
|
||||
}
|
||||
stage.scrollLeft = Math.max(0, stage.scrollWidth * scrollRatioX - stage.clientWidth / 2);
|
||||
stage.scrollTop = Math.max(0, (stage.scrollHeight - stage.clientHeight) * scrollRatioY);
|
||||
});
|
||||
@ -179,7 +187,7 @@ export function ReaderPage({ bookId }: { bookId: number }) {
|
||||
supportsZoom
|
||||
? {
|
||||
zoom,
|
||||
onZoomChange: (nextZoom) => changeZoom(nextZoom),
|
||||
onZoomChange: (nextZoom, anchor) => changeZoom(nextZoom, anchor),
|
||||
onZoomOut: () => changeZoom((currentZoom) => currentZoom - READER_ZOOM_STEP),
|
||||
onZoomIn: () => changeZoom((currentZoom) => currentZoom + READER_ZOOM_STEP),
|
||||
onZoomReset: () => changeZoom(READER_ZOOM_DEFAULT)
|
||||
|
||||
Reference in New Issue
Block a user