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

DSS签名PDF坐标偏移问题:请求明确DSS坐标计量单位

问题描述

我基于DSS开发了一款运行正常的在线电子签名应用,现在正在集成一个Web应用——该应用允许用户通过JavaScript在PDF中定位签名区域并获取X、Y坐标。但遇到了问题:从前端获取的坐标在DSS层面完成签名后出现偏移。

请问DSS层面的originX和originY使用的是什么计量单位?目前我将前端提供的坐标乘以0.75进行转换,仅能小幅减少偏移,效果不理想。

以下是前端获取PDF坐标的源码:

index.html

<!DOCTYPE html>
<html>
<head>
  <title>Positionnement de la zone de signature dans un PDF</title>
  <style>
   
    #signatureZone {
      position: absolute;
      top: 100px;
      left: 100px;
      width: 150px;
      height: 50px;
      border: 2px dashed #f00;
      cursor: grab;
    }
    #pdfContainer {
      overflow-y: scroll; /* Ajoute une barre de défilement verticale */
      width: 600px;
      height: 600px;
      border: 1px solid #ccc;
    }
    #pdfPages {
      height: 100%; /* Remplit toute la hauteur du conteneur */
    }
    .page {
  display: block;
  margin: 10px auto;
  max-width: 100%;
}
  </style>
</head>
<body>
  <div id="pdfContainer">
        <div id="pdfPages"></div>

  </div>
     <div id="signatureZone"></div>
    <button id="prevPage">Precedent</button>
  <button id="nextPage">Suivant</button>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  <script src="pdf.js"></script>
  <script src="pdf.worker.js"></script>
  <script src="script.js"></script>
</body>
</html>

script.js

let pdfDoc = null;
let pageNum = 1;
let pageRendering = false;
let pageNumPending = null;
const scale = 1.5; // Ajustez la valeur si nécessaire
const signatureZone = document.getElementById('signatureZone');
let offsetX, offsetY;
let isDragging = false;
let currentPage = 1; // Variable pour stocker le numéro de la page actuelle


// Gestionnaires d'événements pour faire glisser la zone de signature
signatureZone.addEventListener('mousedown', startDragging);
signatureZone.addEventListener('mousemove', drag);
signatureZone.addEventListener('mouseup', endDragging);
signatureZone.addEventListener('mouseleave', endDragging);

// Charge le PDF et affiche la première page
pdfjsLib.getDocument('exemple.pdf').promise.then(function (pdf) {
  pdfDoc = pdf;
  renderPage(pageNum);
  // displayPages(pdf.numPages);
});

function displayPages(numPages) {
  const pdfPagesContainer = document.getElementById('pdfPages');

  for (let i = 1; i <= numPages; i++) {
    const pageDiv = document.createElement('div');
    pageDiv.className = 'page';
    pdfPagesContainer.appendChild(pageDiv);

    // Affiche chaque page dans le div créé ci-dessus
    pdfDoc.getPage(i).then(function (page) {
      const canvas = document.createElement('canvas');
      const context = canvas.getContext('2d');
      const viewport = page.getViewport({ scale });
      canvas.height = viewport.height;
      canvas.width = viewport.width;
      const renderContext = {
        canvasContext: context,
        viewport: viewport,
      };
      page.render(renderContext).promise.then(function () {
        pageDiv.appendChild(canvas);
      });
    });
  }
  // Met à jour la variable currentPage avec le numéro de la page actuelle
  currentPage = numPages;
}


function renderPage(num) {
  pageRendering = true;
  pdfDoc.getPage(num).then(function (page) {
    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    const viewport = page.getViewport({ scale });
    canvas.height = viewport.height;
    canvas.width = viewport.width;

    const renderContext = {
      canvasContext: context,
      viewport: viewport,
    };

    page.render(renderContext).promise.then(function () {
      const pdfContainer = document.getElementById('pdfContainer');
      pdfContainer.innerHTML = '';
      pdfContainer.appendChild(canvas);
      pageRendering = false;
      if (pageNumPending !== null) {
        renderPage(pageNumPending);
        pageNumPending = null;
      }
    });
  });
  // Met à jour la variable currentPage avec le numéro de la page actuelle
  currentPage = num;
}

function queueRenderPage(num) {
  if (pageRendering) {
    pageNumPending = num;
  } else {
    renderPage(num);
  }
}

function onPrevPage() {
  if (pageNum <= 1) {
    return;
  }
  pageNum--;
  queueRenderPage(pageNum);
}

function onNextPage() {
  if (pageNum >= pdfDoc.numPages) {
    return;
  }
  pageNum++;
  queueRenderPage(pageNum);
}

function startDragging(e) {
  isDragging = true;
  offsetX = e.clientX - signatureZone.getBoundingClientRect().left;
  offsetY = e.clientY - signatureZone.getBoundingClientRect().top;
}

function drag(e) {
  if (isDragging) {
    e.preventDefault();
    const containerRect = document.getElementById('pdfContainer').getBoundingClientRect();
    const x = e.clientX - containerRect.left - offsetX;
    const y = e.clientY - containerRect.top - offsetY;
    signatureZone.style.left = `${x}px`;
    signatureZone.style.top = `${y}px`;
  }
}

function endDragging() {
  isDragging = false;

  // Enregistrez la position de la zone de signature ici, par exemple avec jQuery AJAX
   const position = {
    page: currentPage,
    left: signatureZone.style.left,
    top: signatureZone.style.top,
  };

  console.log("position : ", position)
  // Vous pouvez ensuite envoyer la position au serveur pour enregistrement
  // $.ajax({
  //   url: '/votre/endpoint',
  //   type: 'POST',
  //   data: position,
  //   success: function (response) {
  //     console.log('Position enregistrée avec succès');
  //   },
  //   error: function (error) {
  //     console.error('Erreur lors de l\'enregistrement de la position', error);
  //   },
  // });
}

// Gestion des boutons précédents/suivants
document.getElementById('prevPage').addEventListener('click', onPrevPage);
document.getElementById('nextPage').addEventListener('click', onNextPage);

内容的提问来源于stack exchange,提问作者Frago Mehdi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 06:03:15