You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pdf.js点击添加图片时坐标位置不准确问题求助

Fixing Image Position Issues in pdf.js Canvas Overlay

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:21:55