Fix blurry PDF rendering when zoomed in Chrome PWA
Zoom is now baked into the canvas render scale instead of being applied via CSS zoom. CSS zoom only scales pixels already on the canvas, causing blurriness at high DPR (e.g. PWA on mobile). Now the canvas is rendered at the correct resolution for the chosen zoom level. Also: stop nulling currentPdfDoc on re-render so PDF.js page cache is preserved, making zoom re-renders significantly faster. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e5dc58d84f
commit
f5c141626f
2 changed files with 7 additions and 17 deletions
|
|
@ -1554,6 +1554,7 @@ body.dnd-mode .timer-display {
|
||||||
.reader-content {
|
.reader-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
overflow-x: auto;
|
||||||
padding: 24px 16px;
|
padding: 24px 16px;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
font-family: Georgia, 'Times New Roman', serif;
|
font-family: Georgia, 'Times New Roman', serif;
|
||||||
|
|
|
||||||
|
|
@ -2996,7 +2996,6 @@ async function renderPdf(arrayBuffer, contentEl, scaleOverride) {
|
||||||
// Viewport wrapper: CSS zoom controls display scale without re-rendering
|
// Viewport wrapper: CSS zoom controls display scale without re-rendering
|
||||||
const pdfVp = document.createElement('div');
|
const pdfVp = document.createElement('div');
|
||||||
pdfVp.id = 'pdf-viewport';
|
pdfVp.id = 'pdf-viewport';
|
||||||
if (scaleOverride == null) pdfVp.style.zoom = readerSettings.pdfZoom / 100;
|
|
||||||
contentEl.appendChild(pdfVp);
|
contentEl.appendChild(pdfVp);
|
||||||
|
|
||||||
const containerWidth = readerSettings.pdfSpread
|
const containerWidth = readerSettings.pdfSpread
|
||||||
|
|
@ -3010,8 +3009,9 @@ async function renderPdf(arrayBuffer, contentEl, scaleOverride) {
|
||||||
const page = await pdf.getPage(pageNum);
|
const page = await pdf.getPage(pageNum);
|
||||||
const naturalVp = page.getViewport({scale: 1});
|
const naturalVp = page.getViewport({scale: 1});
|
||||||
const pageWidth = readerSettings.pdfSpread ? (containerWidth - 8) / 2 : containerWidth;
|
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
|
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 viewport = page.getViewport({scale});
|
||||||
|
|
||||||
const wrapper = document.createElement('div');
|
const wrapper = document.createElement('div');
|
||||||
|
|
@ -3654,7 +3654,7 @@ function toggleSettingsPanel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyPdfZoom(newZoom) {
|
async function applyPdfZoom(newZoom) {
|
||||||
const contentEl2 = $('reader-content');
|
const contentEl2 = $('reader-content');
|
||||||
const fraction = contentEl2
|
const fraction = contentEl2
|
||||||
? contentEl2.scrollTop / (contentEl2.scrollHeight - contentEl2.clientHeight || 1)
|
? contentEl2.scrollTop / (contentEl2.scrollHeight - contentEl2.clientHeight || 1)
|
||||||
|
|
@ -3668,12 +3668,9 @@ function applyPdfZoom(newZoom) {
|
||||||
if (readerSettings.pdfPaginated) {
|
if (readerSettings.pdfPaginated) {
|
||||||
pdfSmartZoomPage(pdfCurrentPage);
|
pdfSmartZoomPage(pdfCurrentPage);
|
||||||
} else {
|
} else {
|
||||||
const vp = document.getElementById('pdf-viewport');
|
await reRenderPdf();
|
||||||
if (vp) vp.style.zoom = readerSettings.pdfZoom / 100;
|
|
||||||
if (contentEl2 && fraction > 0) {
|
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;
|
if (!currentPdfBuffer) return;
|
||||||
const contentEl = $('reader-content');
|
const contentEl = $('reader-content');
|
||||||
if (!contentEl) return;
|
if (!contentEl) return;
|
||||||
currentPdfDoc = null; // force re-parse with same buffer
|
|
||||||
await renderPdf(currentPdfBuffer, contentEl);
|
await renderPdf(currentPdfBuffer, contentEl);
|
||||||
if (readerSettings.pdfPaginated) enterPdfPaginatedMode();
|
if (readerSettings.pdfPaginated) enterPdfPaginatedMode();
|
||||||
}
|
}
|
||||||
|
|
@ -3716,14 +3712,7 @@ function exitPdfPaginatedMode() {
|
||||||
contentEl.classList.remove('pdf-paginated');
|
contentEl.classList.remove('pdf-paginated');
|
||||||
contentEl.style.overflow = '';
|
contentEl.style.overflow = '';
|
||||||
contentEl.removeEventListener('click', _pdfPaginatedClick);
|
contentEl.removeEventListener('click', _pdfPaginatedClick);
|
||||||
const wrappers = contentEl.querySelectorAll('.pdf-page-wrapper');
|
reRenderPdf();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _pdfPaginatedClick(e) {
|
function _pdfPaginatedClick(e) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue