Skip to content

Virtualize document viewer and add pinch zoom support - #1394

Draft
dnass wants to merge 9 commits into
mainfrom
virtualize-viewer
Draft

dnass wants to merge 9 commits into
mainfrom
virtualize-viewer

Conversation

@dnass

@dnass dnass commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

WIP. Opening a PR so that I can get a preview deploy.

@github-actions

Copy link
Copy Markdown

Preview deployed: https://preview-1394.staging.documentcloud.org

Comment thread package.json
"svelte-octicons": "^18.20.0",
"svelte-preprocess": "^6.0.3",
"sveltekit-flash-message": "^2.4.6",
"virtua": "^0.50.2",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dnass any strong factors for why you picked this particular library?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Virtua seems like the most mature option available for Svelte. It's under active development and has a framework agnostic core plus clients for several different frameworks. It estimates the content height effectively with no config, which I haven't seen in other virtualization libraries.

Other options I checked out:

Comment on lines +208 to +211
// Trackpad pinch gestures arrive as wheel events with ctrlKey set; the browser
// would otherwise page-zoom, so claim them. Plain (non-ctrl) wheel stays a
// normal scroll.
async function onWheel(e: WheelEvent) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the scroll wheel support!

Comment on lines +21 to +39
export interface PinchZoomOptions {
/** Current numeric render scale (e.g. `viewer.scale`). */
getScale: () => number;
/**
* Set the zoom value. Must apply synchronously and flush so the page layout
* reflects the new scale before we read the post-change geometry.
*/
setZoom: (scale: number) => void;
/** Whether pinch-zoom is currently allowed (e.g. only in reading mode). */
enabled: () => boolean;
/** Minimum/maximum scale reachable via pinch. */
min: number;
max: number;
/** Called when a pinch gesture begins (touch or trackpad). */
onPinchStart?: () => void;
/** Called when a pinch gesture ends. */
onPinchEnd?: () => void;
findItemByOffset: (offset: number) => Nullable<HTMLElement>;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonderfully generic, using a Svelte attachment is a great choice here.

@dnass
dnass changed the base branch from 1084-zoom to main September 14, 2026 13:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants