使用pdf.js点击添加图片时坐标位置不准确问题求助
Let's walk through the key problems causing your image position mismatch and how to fix them step by step:
Common Root Causes & Solutions
1. Incorrect Page Indexing
pdf.js's getPageView() uses a 0-based index, but currentPageNumber is 1-based. Using the wrong index means you're targeting the wrong page's viewport, which throws off coordinates immediately.
2. Coordinate System Mismatch
PDFs use a bottom-left origin, while browser canvas uses top-left. Plus, zoom levels scale the rendered page, so pixel coordinates from clicks don't directly map to PDF content without conversion.
3. Not Handling Zoom/Resize Events
When users zoom the PDF, the page viewport changes size. If your canvas doesn't resize and redraw images using the new viewport, positions will shift.
Corrected Code Implementation
First, create a global store to track images per page using PDF-native coordinates (consistent across zoom levels):
// Store image data (PDF coordinates) per page (1-based page number) const pageImages = {};
Click Handler for Adding Images
$('.page').on('click', function(e) { if ($("#hotspotTool").hasClass('active')) { // Get correct page view (0-based index) const pageNumber = window.PDFViewerApplication.pdfViewer.currentPageNumber; const pageIndex = pageNumber - 1; const pageView = window.PDFViewerApplication.pdfViewer.getPageView(pageIndex); const viewport = pageView.viewport; // Calculate click position relative to the page element const pageRect = pageView.element.getBoundingClientRect(); const relativeX = e.clientX - pageRect.left; const relativeY = e.clientY - pageRect.top; // Convert click coordinates to PDF's native system (bottom-left origin) const pdfCoords = viewport.convertToPdfPoint(relativeX, relativeY); const pdfX = pdfCoords[0]; const pdfY = pdfCoords[1]; // Save image data to our global store if (!pageImages[pageNumber]) pageImages[pageNumber] = []; pageImages[pageNumber].push({ src: 'path/to/your/image.png', // Replace with your image URL x: pdfX, y: pdfY }); // Redraw images for the current page redrawPageImages(pageView); } });
Redraw Function for Consistent Positioning
This function converts stored PDF coordinates to the current viewport's pixel coordinates and redraws images:
function redrawPageImages(pageView) { const pageNumber = pageView.pageNumber; const viewport = pageView.viewport; // Get or create overlay canvas let canvas = pageView.element.querySelector('.overlay-canvas'); if (!canvas) { canvas = document.createElement('canvas'); canvas.className = 'overlay-canvas'; canvas.style.position = 'absolute'; canvas.style.top = '0'; canvas.style.left = '0'; canvas.style.pointerEvents = 'auto'; // Allow clicks when tool is active pageView.element.appendChild(canvas); } // Resize canvas to match current viewport canvas.width = viewport.width; canvas.height = viewport.height; const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw all images stored for this page const images = pageImages[pageNumber] || []; images.forEach(imgData => { const img = new Image(); img.src = imgData.src; img.onload = () => { // Convert PDF coordinates back to canvas (top-left origin) const viewportCoords = viewport.convertToViewportPoint(imgData.x, imgData.y); const canvasY = viewport.height - viewportCoords[1]; // Flip Y-axis ctx.drawImage(img, viewportCoords[0], canvasY); }; }); }
Handle Zoom & Page Updates
Ensure images stay in place when zooming or pages are re-rendered:
// Listen for zoom changes to redraw all pages window.PDFViewerApplication.eventBus.on('zoom', () => { const pages = window.PDFViewerApplication.pdfViewer.getPages(); pages.forEach(page => redrawPageImages(page)); }); // Listen for page view updates (e.g., after scrolling to a new page) window.PDFViewerApplication.eventBus.on('pageviewupdated', (e) => { redrawPageImages(e.pageView); });
Toggle Canvas Interaction
Prevent the canvas from blocking PDF interactions (like scrolling) when the hotspot tool is inactive:
$("#hotspotTool").on('click', function() { $(this).toggleClass('active'); $('.overlay-canvas').css('pointer-events', $(this).hasClass('active') ? 'auto' : 'none'); });
Key Takeaways
- Use PDF-native coordinates to store positions (they stay consistent regardless of zoom).
- Always convert between browser canvas (top-left) and PDF (bottom-left) coordinate systems.
- Redraw images whenever the viewport changes (zoom, page resize).
- Correctly index pages (0-based for
getPageView()).
内容的提问来源于stack exchange,提问作者Vishnu

