diff --git a/static/css/app.css b/static/css/app.css index 4625ee2..7429252 100644 --- a/static/css/app.css +++ b/static/css/app.css @@ -1554,6 +1554,7 @@ body.dnd-mode .timer-display { .reader-content { flex: 1; overflow-y: scroll; + overflow-x: auto; padding: 24px 16px; line-height: 1.8; font-family: Georgia, 'Times New Roman', serif; diff --git a/static/js/app.js b/static/js/app.js index b4474f5..dcdee81 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -2996,7 +2996,6 @@ async function renderPdf(arrayBuffer, contentEl, scaleOverride) { // 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 = readerSettings.pdfSpread @@ -3010,8 +3009,9 @@ async function renderPdf(arrayBuffer, contentEl, scaleOverride) { const page = await pdf.getPage(pageNum); const naturalVp = page.getViewport({scale: 1}); const pageWidth = readerSettings.pdfSpread ? (containerWidth - 8) / 2 : containerWidth; + // Zoom baked into canvas resolution — no CSS zoom, stays sharp at any DPR const scale = scaleOverride != null ? scaleOverride - : Math.max(0.5, pageWidth / naturalVp.width); + : Math.max(0.5, pageWidth / naturalVp.width) * (readerSettings.pdfZoom / 100); const viewport = page.getViewport({scale}); const wrapper = document.createElement('div'); @@ -3654,7 +3654,7 @@ function toggleSettingsPanel() { } } -function applyPdfZoom(newZoom) { +async function applyPdfZoom(newZoom) { const contentEl2 = $('reader-content'); const fraction = contentEl2 ? contentEl2.scrollTop / (contentEl2.scrollHeight - contentEl2.clientHeight || 1) @@ -3668,12 +3668,9 @@ function applyPdfZoom(newZoom) { if (readerSettings.pdfPaginated) { pdfSmartZoomPage(pdfCurrentPage); } else { - const vp = document.getElementById('pdf-viewport'); - if (vp) vp.style.zoom = readerSettings.pdfZoom / 100; + await reRenderPdf(); if (contentEl2 && fraction > 0) { - requestAnimationFrame(() => { - contentEl2.scrollTop = fraction * (contentEl2.scrollHeight - contentEl2.clientHeight); - }); + contentEl2.scrollTop = fraction * (contentEl2.scrollHeight - contentEl2.clientHeight); } } } @@ -3682,7 +3679,6 @@ async function reRenderPdf() { if (!currentPdfBuffer) return; const contentEl = $('reader-content'); if (!contentEl) return; - currentPdfDoc = null; // force re-parse with same buffer await renderPdf(currentPdfBuffer, contentEl); if (readerSettings.pdfPaginated) enterPdfPaginatedMode(); } @@ -3716,14 +3712,7 @@ function exitPdfPaginatedMode() { contentEl.classList.remove('pdf-paginated'); contentEl.style.overflow = ''; contentEl.removeEventListener('click', _pdfPaginatedClick); - const wrappers = contentEl.querySelectorAll('.pdf-page-wrapper'); - wrappers.forEach(w => { - w.style.display = ''; - const canvas = w.querySelector('canvas'); - if (canvas) canvas.style.transform = ''; - }); - const pdfVp = document.getElementById('pdf-viewport'); - if (pdfVp) pdfVp.style.zoom = readerSettings.pdfZoom / 100; + reRenderPdf(); } function _pdfPaginatedClick(e) {