An e-signature is a digital form of a handwritten signature that allows individuals to sign documents electronically. It has become an essential tool for businesses and organizations to streamline the signing process, enabling documents to be signed in just a few clicks from anywhere in the world. In this article, we will explore how to insert a signature into PDF documents using HTML5, JavaScript, and Dynamsoft Document Viewer.
Demo Video: Sign PDF Documents with Electronic Signature
Online Demo
https://yushulx.me/web-document-annotation/
Prerequisites
Dynamsoft Capture Vision Trial License: Obtain a 30-day free trial license to unlock the full capabilities of Dynamsoft Products.
Dynamsoft Document Viewer: This JavaScript SDK enables seamless viewing of PDF, JPEG, PNG, TIFF, and BMP files. It also features PDF annotation rendering and saving. Download link: https://www.npmjs.com/package/dynamsoft-document-viewer.
Implementing Signature Functionality for Web PDF Editor
Our web document annotation project, built with the Dynamsoft Document Viewer, is highly extensible. It currently includes barcode detection for PDF documents. In the following sections, we will guide you through the process of adding an electronic signature to PDF documents step by step.
Step 1: Get the Source Code
-
Clone the source code from the GitHub repository:
git clone https://github.com/yushulx/web-twain-document-scan-management.git
-
Navigate to the
document_annotation
directory:
cd web-twain-document-scan-management/examples/document_annotation
Open the project in Visual Studio Code.
Step 2: Add a Signature Button
-
In
main.css
, add a material icon for the signature button:
.icon-stylus::before { content: "edit"; } .icon-stylus { display: flex; font-size: 1.5em; }
-
Define the signature button and add it to the toolbar in
main.js
:
const signatureButton = { type: Dynamsoft.DDV.Elements.Button, className: "material-icons icon-stylus", tooltip: "Sign the document", events: { click: "sign", } } const pcEditViewerUiConfig = { type: Dynamsoft.DDV.Elements.Layout, flexDirection: "column", className: "ddv-edit-viewer-desktop", children: [ { type: Dynamsoft.DDV.Elements.Layout, className: "ddv-edit-viewer-header-desktop", children: [ { type: Dynamsoft.DDV.Elements.Layout, children: [ Dynamsoft.DDV.Elements.ThumbnailSwitch, Dynamsoft.DDV.Elements.Zoom, Dynamsoft.DDV.Elements.FitMode, Dynamsoft.DDV.Elements.Crop, Dynamsoft.DDV.Elements.Filter, Dynamsoft.DDV.Elements.Undo, Dynamsoft.DDV.Elements.Redo, Dynamsoft.DDV.Elements.DeleteCurrent, Dynamsoft.DDV.Elements.DeleteAll, Dynamsoft.DDV.Elements.Pan, Dynamsoft.DDV.Elements.AnnotationSet, qrButton, checkButton, scanButton, clearButton, signatureButton, ], }, { type: Dynamsoft.DDV.Elements.Layout, children: [ { type: Dynamsoft.DDV.Elements.Pagination, className: "ddv-edit-viewer-pagination-desktop", }, loadButton, downloadButton, ], }, ], }, Dynamsoft.DDV.Elements.MainView, ], };
-
Add the click event handler for the signature button:
editViewer.on("sign", sign); function sign() { ... }
Step 3: Create a Pop-up Dialog for Signature Input
The pop-up dialog for signature input includes the following elements:
- A canvas element for drawing the signature.
- Color options for changing the signature color.
- A stroke slider to adjust signature thickness.
- X and Y coordinates for positioning the signature.
- A save button to insert the signature into the PDF document.
- A cancel button to close the dialog.
- A redraw button to erase the signature.
HTML Code
<div id="signature-input" class="overlay">
<div class="signature-container">
<h2>Create New Signature</h2>
<canvas id="signatureCanvas"></canvas>
<div class="form-group">
<span>Color Style:</span>
<div id="blue" class="color-button" style="background-color: blue;"></div>
<div id="red" class="color-button" style="background-color: red;"></div>
<div id="black" class="color-button" style="background-color: black;"></div>
</div>
<div class="form-group">
<span>Stroke:</span>
<input type="range" id="strokeSlider" min="1" max="10" value="3">
</div>
<!-- X -->
<div class="form-group">
<label for="signatureX">X:</label>
<input type="text" id="signatureX" name="signatureX" placeholder="0">
</div>
<!-- Y -->
<div class="form-group">
<label for="signatureY">Y:</label>
<input type="text" id="signatureY" name="signatureY" placeholder="0">
</div>
<div style="margin-top: 10px;">
<input type="checkbox" id="signatureAllPage"> Auto-generate signatures on all pages
</div>
<div class="popup-buttons">
<button id="signatureOK">OK</button>
<button id="signatureRedraw">Redraw</button>
<button id="signatureCancel">Cancel</button>
</div>
</div>
</div>
JavaScript code for the signature input dialog
-
Initialize the canvas and drawing context:
let canvas = document.getElementById("signatureCanvas"); let ctx = canvas.getContext("2d"); let isDrawing = false; let color = "black"; let strokeWidth = 3; let drawingHistory = []; canvas.width = 500; canvas.height = 300;
-
Add event listeners for mouse events:
canvas.addEventListener("mousedown", startDrawing); canvas.addEventListener("mousemove", draw); canvas.addEventListener("mouseup", stopDrawing); canvas.addEventListener("mouseout", stopDrawing);
-
Add event listeners for color and stroke options:
document.getElementById("blue").addEventListener("click", () => { color = "blue"; redrawCanvas(); }); document.getElementById("red").addEventListener("click", () => { color = "red"; redrawCanvas(); }); document.getElementById("black").addEventListener("click", () => { color = "black"; redrawCanvas(); }); document.getElementById("strokeSlider").addEventListener("input", (e) => { strokeWidth = e.target.value; redrawCanvas(); });
-
Implement the drawing functions:
function startDrawing(event) { isDrawing = true; let currentPath = { color: color, strokeWidth: strokeWidth, points: [{ x: event.offsetX, y: event.offsetY }] }; drawingHistory.push(currentPath); } function draw(event) { if (isDrawing) { let currentPath = drawingHistory[drawingHistory.length - 1]; currentPath.points.push({ x: event.offsetX, y: event.offsetY }); redrawCanvas(); } } function stopDrawing() { isDrawing = false; } function redrawCanvas() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawingHistory.forEach(path => { ctx.beginPath(); ctx.moveTo(path.points[0].x, path.points[0].y); for (let i = 1; i < path.points.length; i++) { ctx.lineTo(path.points[i].x, path.points[i].y); } ctx.strokeStyle = color; ctx.lineWidth = strokeWidth; ctx.stroke(); }); } function clearCanvas() { drawingHistory = []; redrawCanvas(); }
All paths are stored in the
drawingHistory
array. TheredrawCanvas
function iterates through the array and redraws the paths on the canvas. -
Add event listeners for the
OK
,Redraw
, andCancel
buttons:
const signatureOKButton = document.getElementById('signatureOK'); const signatureRedrawButton = document.getElementById('signatureRedraw'); const signatureCancelButton = document.getElementById('signatureCancel'); signatureOKButton.addEventListener('click', async () => { ... }); signatureRedrawButton.addEventListener('click', async () => { drawingHistory = []; redrawCanvas(); }); signatureCancelButton.addEventListener('click', async () => { document.getElementById("signature-input").style.display = "none"; });
Step 4: Insert Signatures into Documents
To insert the signature into the PDF document:
-
Convert the canvas to a blob:
canvas.toBlob(async (blob) => { ... }, 'image/png');
-
Get the current page ID and page data:
let currentPageId = currentDoc.pages[editViewer.getCurrentPageIndex()]; let pageData = await currentDoc.getPageData(currentPageId);
-
Create new stamp annotations with the signature image:
const applyToAllPages = document.getElementById("signatureAllPage").checked; const x = Number(document.getElementById("signatureX").value); const y = Number(document.getElementById("signatureY").value); const option = { stamp: blob, x: x > pageData.mediaBox.width - canvas.width ? pageData.mediaBox.width - canvas.width - 10 : x, y: y > pageData.mediaBox.height - canvas.height ? pageData.mediaBox.height - canvas.height - 10 : y, width: canvas.width, height: canvas.height, opacity: 1.0, flags: { print: false, noView: false, readOnly: false, } } try { if (applyToAllPages) { for (let i = 0; i < currentDoc.pages.length; i++) { let signatureAnnotation = await Dynamsoft.DDV.annotationManager.createAnnotation(currentDoc.pages[i], "stamp", option) signatureAnnotation['name'] = 'signature'; } } else { let signatureAnnotation = await Dynamsoft.DDV.annotationManager.createAnnotation(currentPageId, "stamp", option) signatureAnnotation['name'] = 'signature'; } } catch (e) { console.log(e); }
Source Code
https://github.com/yushulx/web-twain-document-scan-management/tree/main/examples/document_annotation
Top comments (0)