Skip to content

Commit fc18ae3

Browse files
committed
fix: fixed trackpad zoom sensitivity and page jitter during wheel zoom
1 parent 10886ea commit fc18ae3

1 file changed

Lines changed: 29 additions & 11 deletions

File tree

src/components/newPdfViewer.tsx

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -248,25 +248,43 @@ const Controls = memo(function Controls({documentId, toggleFullscreen, isFullscr
248248
)
249249
});
250250

251-
function WheelZoom({documentId, viewerRef}: WheelZoomProps){
251+
function WheelZoom({ documentId, viewerRef }: WheelZoomProps) {
252252
const { provides: zoomProv } = useZoom(documentId);
253+
const accumulatedDelta = useRef(0);
254+
const rafId = useRef<number | null>(null);
253255

254-
const handleWheel = useCallback((e: WheelEvent) => {
255-
if (e.ctrlKey && zoomProv) {
256+
const handleWheel = useCallback(
257+
(e: WheelEvent) => {
258+
if (!e.ctrlKey || !zoomProv) return;
256259
e.preventDefault();
257-
if (e.deltaY < 0) {
258-
zoomProv.zoomIn();
259-
} else {
260-
zoomProv.zoomOut();
261-
}
262-
}
263-
}, [zoomProv]);
260+
261+
// Trackpad pinch sends fractional deltaY (often < 1),
262+
// mouse wheel sends large discrete steps (typically 100–120).
263+
const isTrackpad = Math.abs(e.deltaY) < 50;
264+
const scaleFactor = isTrackpad ? 0.007 : 0.08;
265+
266+
accumulatedDelta.current += -e.deltaY * scaleFactor;
267+
268+
// Flush on the next animation frame to batch rapid events
269+
if (rafId.current !== null) cancelAnimationFrame(rafId.current);
270+
rafId.current = requestAnimationFrame(() => {
271+
const clamped = Math.max(-0.15, Math.min(accumulatedDelta.current, 0.15));
272+
zoomProv.requestZoomBy(clamped);
273+
accumulatedDelta.current = 0;
274+
rafId.current = null;
275+
});
276+
},
277+
[zoomProv]
278+
);
264279

265280
useEffect(() => {
266281
const viewer = viewerRef.current;
267282
if (!viewer) return;
268283
viewer.addEventListener("wheel", handleWheel, { passive: false });
269-
return () => viewer.removeEventListener("wheel", handleWheel);
284+
return () => {
285+
viewer.removeEventListener("wheel", handleWheel);
286+
if (rafId.current !== null) cancelAnimationFrame(rafId.current);
287+
};
270288
}, [handleWheel]);
271289

272290
return null;

0 commit comments

Comments
 (0)