From f8916e128e4410e198956976e6c8af60690a093d Mon Sep 17 00:00:00 2001 From: Huang Xin Date: Sat, 27 Jun 2026 17:15:33 +0800 Subject: [PATCH] fix(reader): smooth pinch-zoom and pan for scrolled-mode PDF (#4817) Bumps foliate-js to readest/foliate-js#43. In scrolled-mode PDF the page now zooms live under a pinch and commits without a layout shift (the inter-page gap scales with the zoom so the committed layout matches the transform-scaled preview, and the centre page is restored to its pre-commit on-screen rect), a page zoomed wider than the viewport is pannable horizontally, and the page iframes stay interactive when idle so native text selection keeps working. readest already drives the renderer's pinchZoom on a two-finger gesture, so the only reader-side change is the submodule bump plus a unit test for the new scroll pinch transform. Co-authored-by: Claude Opus 4.8 (1M context) --- .../document/fixed-layout-pinch-zoom.test.ts | 38 +++++++++++++++++++ packages/foliate-js | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 apps/readest-app/src/__tests__/document/fixed-layout-pinch-zoom.test.ts diff --git a/apps/readest-app/src/__tests__/document/fixed-layout-pinch-zoom.test.ts b/apps/readest-app/src/__tests__/document/fixed-layout-pinch-zoom.test.ts new file mode 100644 index 00000000..2ced5ca4 --- /dev/null +++ b/apps/readest-app/src/__tests__/document/fixed-layout-pinch-zoom.test.ts @@ -0,0 +1,38 @@ +import { describe, expect, it } from 'vitest'; + +import { computeScrollPinchTransform } from 'foliate-js/fixed-layout.js'; + +describe('computeScrollPinchTransform', () => { + it('scales by the pinch ratio anchored at the viewport centre in both axes', () => { + // Anchoring the live preview at the viewport centre (in container + // coordinates) matches the post-pinch re-render, which restores the same + // centre point via the center anchor, so the zoom does not jump on release. + expect( + computeScrollPinchTransform({ + ratio: 1.5, + scrollLeft: 0, + scrollTop: 2000, + viewportWidth: 360, + viewportHeight: 640, + }), + ).toEqual({ + transform: 'scale(1.5)', + transformOrigin: '180px 2320px', + }); + }); + + it('offsets the origin by the current scroll position', () => { + expect( + computeScrollPinchTransform({ + ratio: 0.8, + scrollLeft: 90, + scrollTop: 0, + viewportWidth: 360, + viewportHeight: 640, + }), + ).toEqual({ + transform: 'scale(0.8)', + transformOrigin: '270px 320px', + }); + }); +}); diff --git a/packages/foliate-js b/packages/foliate-js index 6f1a1901..0fa407c4 160000 --- a/packages/foliate-js +++ b/packages/foliate-js @@ -1 +1 @@ -Subproject commit 6f1a190184802457f38a9e75a8111fc50e19e068 +Subproject commit 0fa407c4c63f09a5795c808503d1030231c645f0