From ca3b74f939f897c71e75998f3000f9a0cb9974ea Mon Sep 17 00:00:00 2001 From: TekH Date: Sat, 6 Jun 2026 11:16:05 +0200 Subject: [PATCH] Improve PDF rendering quality and user experience Added `image-rendering` properties and opacity transitions to `.pdf-canvas` for smoother visual effects during rendering. Introduced a `.pdf-canvas.rendering` class to indicate rendering state. Enhanced `renderPage` method to support HiDPI displays by scaling the viewport based on device pixel ratio (up to 2) and setting both internal resolution and CSS display size for better rendering quality. Enabled high-quality rendering with `imageSmoothingEnabled` and `imageSmoothingQuality`. Updated scroll container reference to `.pdf-canvas-wrapper` for proper alignment. Added logic to manage the `rendering` class during and after rendering, including error handling to ensure UI consistency. These changes improve both functionality and aesthetics of the PDF viewer. --- .../wwwroot/css/envelope-viewer.css | 7 ++++++ .../wwwroot/js/pdf-viewer.js | 25 ++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/EnvelopeGenerator.ReceiverUI/wwwroot/css/envelope-viewer.css b/EnvelopeGenerator.ReceiverUI/wwwroot/css/envelope-viewer.css index f3e5877b..04602a9b 100644 --- a/EnvelopeGenerator.ReceiverUI/wwwroot/css/envelope-viewer.css +++ b/EnvelopeGenerator.ReceiverUI/wwwroot/css/envelope-viewer.css @@ -432,6 +432,13 @@ body.resizing { display: inline-block; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); vertical-align: top; + image-rendering: -webkit-optimize-contrast; + image-rendering: crisp-edges; + transition: opacity 0.15s ease-out; +} + +.pdf-canvas.rendering { + opacity: 0; } .error-container { diff --git a/EnvelopeGenerator.ReceiverUI/wwwroot/js/pdf-viewer.js b/EnvelopeGenerator.ReceiverUI/wwwroot/js/pdf-viewer.js index cf5556b3..3c677760 100644 --- a/EnvelopeGenerator.ReceiverUI/wwwroot/js/pdf-viewer.js +++ b/EnvelopeGenerator.ReceiverUI/wwwroot/js/pdf-viewer.js @@ -97,10 +97,13 @@ window.pdfViewer = { async renderPage(num) { this.pageRendering = true; + + // Add rendering class for smooth transition + this.canvas.classList.add('rendering'); try { // Get scroll container - const container = this.canvas.closest('.pdf-frame'); + const container = this.canvas.closest('.pdf-canvas-wrapper'); // Store scroll position and viewport center BEFORE rendering let scrollLeft = 0, scrollTop = 0; @@ -116,10 +119,18 @@ window.pdfViewer = { } const page = await this.pdfDoc.getPage(num); - const viewport = page.getViewport({ scale: this.scale }); + + // HiDPI support for main canvas + const dpr = window.devicePixelRatio || 1; + const viewport = page.getViewport({ scale: this.scale * Math.min(dpr, 2) }); - this.canvas.height = viewport.height; + // Set internal canvas resolution (high quality) this.canvas.width = viewport.width; + this.canvas.height = viewport.height; + + // Set CSS display size (visual size) + this.canvas.style.width = `${viewport.width / dpr}px`; + this.canvas.style.height = `${viewport.height / dpr}px`; const renderContext = { canvasContext: this.ctx, @@ -130,6 +141,10 @@ window.pdfViewer = { this.currentRenderTask.cancel(); } + // Enable high-quality rendering + this.ctx.imageSmoothingEnabled = true; + this.ctx.imageSmoothingQuality = 'high'; + this.currentRenderTask = page.render(renderContext); await this.currentRenderTask.promise; @@ -145,6 +160,9 @@ window.pdfViewer = { container.scrollTop = newCenterY - container.clientHeight / 2; } + // Remove rendering class after completion + this.canvas.classList.remove('rendering'); + this.currentRenderTask = null; this.pageRendering = false; @@ -156,6 +174,7 @@ window.pdfViewer = { if (error.name !== 'RenderingCancelledException') { console.error('Render error:', error); } + this.canvas.classList.remove('rendering'); this.currentRenderTask = null; this.pageRendering = false; }