Add text layer support for PDF rendering and selection

Integrated PDF.js to enable text selection and copy-paste functionality in the PDF viewer. Updated `EnvelopeViewer.razor` to include the necessary scripts and styles, and modified the HTML structure to add a text layer container.

Enhanced `envelope-viewer.css` with styles for the text layer and optimized canvas rendering. Added a `renderTextLayer` method in `pdf-viewer.js` to extract and render text content from PDF pages. Updated the rendering process to overlay the text layer on the canvas.
This commit is contained in:
2026-06-06 16:13:32 +02:00
parent fc267e1eb4
commit d32050ce03
3 changed files with 77 additions and 2 deletions

View File

@@ -176,6 +176,9 @@ window.pdfViewer = {
this.currentRenderTask = page.render(renderContext);
await this.currentRenderTask.promise;
// Render text layer for copy-paste functionality
await this.renderTextLayer(page, viewport, dpr);
// Restore viewport center position AFTER rendering
if (container && oldWidth > 0 && oldHeight > 0) {
const scaleX = this.canvas.width / oldWidth;
@@ -210,6 +213,41 @@ window.pdfViewer = {
}
},
async renderTextLayer(page, viewport, dpr) {
try {
const textLayerDiv = document.getElementById('pdf-text-layer');
if (!textLayerDiv) {
console.warn('Text layer div not found');
return;
}
// Clear previous text layer
textLayerDiv.innerHTML = '';
// Set text layer dimensions to match canvas display size
textLayerDiv.style.width = `${viewport.width / dpr}px`;
textLayerDiv.style.height = `${viewport.height / dpr}px`;
// Get text content from PDF
const textContent = await page.getTextContent();
// Create viewport for text layer (without DPR scaling for positioning)
const textViewport = page.getViewport({ scale: this.scale });
// Render text layer using PDF.js built-in function
const pdfjsLib = window.pdfjsLib;
await pdfjsLib.renderTextLayer({
textContentSource: textContent,
container: textLayerDiv,
viewport: textViewport,
textDivs: []
}).promise;
} catch (error) {
console.error('Error rendering text layer:', error);
}
},
queueRenderPage(num) {
if (this.pageRendering) {
this.pageNumPending = num;