PDF zoom: use CSS zoom instead of re-render, abort stale renders
- Add render generation counter (_pdfRenderGen) to abort overlapping renders - Wrap all pages in #pdf-viewport div; zoom slider just updates style.zoom - Use 'input' event on zoom slider for live preview without re-rendering - enterPdfPaginatedMode resets viewport zoom to 1; exitPdfPaginatedMode restores it - Remove pdfZoom factor from renderPdf scale (CSS zoom handles it now) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1cba67b3ed
commit
1026ed09a7
2 changed files with 26 additions and 4 deletions
|
|
@ -1637,6 +1637,9 @@ body.dnd-mode .timer-display {
|
|||
}
|
||||
.reader-settings-panel input[type="range"] { width:80px; }
|
||||
|
||||
/* PDF viewport wrapper — CSS zoom applied here for smooth zoom without re-render */
|
||||
#pdf-viewport { transform-origin: top left; }
|
||||
|
||||
/* PDF inner container — shares origin with canvas so text layer aligns exactly */
|
||||
.pdf-page-inner { position:relative; display:inline-block; line-height:0; }
|
||||
|
||||
|
|
|
|||
|
|
@ -2594,6 +2594,7 @@ let readerSearchOpen = false;
|
|||
let pdfCurrentPage = 1;
|
||||
let pdfTotalPages = 0;
|
||||
let _pdfPageTextBoxCache = {};
|
||||
let _pdfRenderGen = 0;
|
||||
let _touchStartX = 0;
|
||||
|
||||
if (typeof pdfjsLib !== 'undefined') {
|
||||
|
|
@ -2836,7 +2837,9 @@ async function _parsePdfOutline(pdf, items, depth) {
|
|||
}
|
||||
|
||||
async function renderPdf(arrayBuffer, contentEl, scaleOverride) {
|
||||
const myGen = ++_pdfRenderGen;
|
||||
const pdf = currentPdfDoc || await pdfjsLib.getDocument({data: new Uint8Array(arrayBuffer.slice(0))}).promise;
|
||||
if (_pdfRenderGen !== myGen) return null;
|
||||
currentPdfDoc = pdf;
|
||||
|
||||
let pdfTitle = '', pdfAuthor = '';
|
||||
|
|
@ -2854,13 +2857,20 @@ async function renderPdf(arrayBuffer, contentEl, scaleOverride) {
|
|||
|
||||
contentEl.innerHTML = '';
|
||||
|
||||
// Viewport wrapper: CSS zoom controls display scale without re-rendering
|
||||
const pdfVp = document.createElement('div');
|
||||
pdfVp.id = 'pdf-viewport';
|
||||
if (scaleOverride == null) pdfVp.style.zoom = readerSettings.pdfZoom / 100;
|
||||
contentEl.appendChild(pdfVp);
|
||||
|
||||
const containerWidth = Math.min(contentEl.clientWidth - 32, 900);
|
||||
|
||||
for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {
|
||||
if (_pdfRenderGen !== myGen) { contentEl.innerHTML = ''; return null; }
|
||||
const page = await pdf.getPage(pageNum);
|
||||
const naturalVp = page.getViewport({scale: 1});
|
||||
const scale = scaleOverride != null ? scaleOverride
|
||||
: Math.max(0.5, (containerWidth / naturalVp.width) * (readerSettings.pdfZoom / 100));
|
||||
: Math.max(0.5, containerWidth / naturalVp.width);
|
||||
const viewport = page.getViewport({scale});
|
||||
|
||||
const wrapper = document.createElement('div');
|
||||
|
|
@ -2878,7 +2888,7 @@ async function renderPdf(arrayBuffer, contentEl, scaleOverride) {
|
|||
canvas.height = viewport.height;
|
||||
inner.appendChild(canvas);
|
||||
wrapper.appendChild(inner);
|
||||
contentEl.appendChild(wrapper);
|
||||
pdfVp.appendChild(wrapper);
|
||||
|
||||
await page.render({canvasContext: canvas.getContext('2d'), viewport}).promise;
|
||||
|
||||
|
|
@ -3424,11 +3434,16 @@ function toggleSettingsPanel() {
|
|||
} else {
|
||||
const zoomRange = panel.querySelector('#rs-zoom');
|
||||
const zoomVal = panel.querySelector('#rs-zoom-val');
|
||||
zoomRange.addEventListener('change', () => {
|
||||
zoomRange.addEventListener('input', () => {
|
||||
readerSettings.pdfZoom = parseInt(zoomRange.value, 10);
|
||||
zoomVal.textContent = readerSettings.pdfZoom + '%';
|
||||
saveReaderSettings();
|
||||
reRenderPdf();
|
||||
if (readerSettings.pdfPaginated) {
|
||||
pdfSmartZoomPage(pdfCurrentPage);
|
||||
} else {
|
||||
const vp = document.getElementById('pdf-viewport');
|
||||
if (vp) vp.style.zoom = readerSettings.pdfZoom / 100;
|
||||
}
|
||||
});
|
||||
|
||||
panel.querySelector('#rs-invert').addEventListener('click', function () {
|
||||
|
|
@ -3469,6 +3484,8 @@ function enterPdfPaginatedMode() {
|
|||
if (!contentEl) return;
|
||||
contentEl.classList.add('pdf-paginated');
|
||||
contentEl.style.overflow = 'hidden';
|
||||
const pdfVp = document.getElementById('pdf-viewport');
|
||||
if (pdfVp) pdfVp.style.zoom = 1;
|
||||
|
||||
const wrappers = contentEl.querySelectorAll('.pdf-page-wrapper');
|
||||
wrappers.forEach((w, i) => {
|
||||
|
|
@ -3493,6 +3510,8 @@ function exitPdfPaginatedMode() {
|
|||
const canvas = w.querySelector('canvas');
|
||||
if (canvas) canvas.style.transform = '';
|
||||
});
|
||||
const pdfVp = document.getElementById('pdf-viewport');
|
||||
if (pdfVp) pdfVp.style.zoom = readerSettings.pdfZoom / 100;
|
||||
}
|
||||
|
||||
function _pdfPaginatedClick(e) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue