JavaScript implements handwritten signatures, can be handwritten on the touch screen, and supports dual-end saving on mobile and PC.

Table of Contents

1.HTML template

2. Get DOM elements and define variables

3. Create two canvas elements and set their width and height

4. Bind touch events: touchstart, touchmove, touchend and click

5. Implement touch event callback functions: startDrawing, draw and stopDrawing

6. Implement the function of drawing line segments: drawLine

7. Implement the function to clear the signature: clearSignature

8. Implement the function to save the signature: saveSignature

9. Insert the canvas element into the DOM tree

10. Complete code

11.Renderings


1.HTML template
<!DOCTYPE html>
<html>
<head>
  <title></title>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
  <style>
    /* style sheet */
  </style>
</head>
<body>
  <!-- Signature area -->
  <div id="signatureArea"></div>

  <!-- Action buttons: Clear and Save -->
  <button id="clearButton">Clear</button>
  <button id="saveButton">Save signature</button>

  <!-- JavaScript code -->
  <script type="text/javascript">
    // JavaScript code
  </script>
</body>
</html>
2. Get DOM elements and define variables
//Get DOM elements
var signatureArea = document.getElementById('signatureArea');
var clearButton = document.getElementById('clearButton');
var saveButton = document.getElementById('saveButton');

//define variables
var isDrawing = false; // Whether drawing is taking place
var lastX, lastY; //Coordinates of the last touch point
3. Create two canvas elements and set their width and height
//Create two canvas elements
var drawingCanvas = document.createElement('canvas'); // used to draw signatures
var backgroundCanvas = document.createElement('canvas'); // Used to save the signature image with a white background
var drawingCtx = drawingCanvas.getContext('2d'); // Get the context object of the drawing canvas
var backgroundCtx = backgroundCanvas.getContext('2d'); // Get the context object of the background canvas
drawingCanvas.width = signatureArea.offsetWidth;
drawingCanvas.height = signatureArea.offsetHeight;
backgroundCanvas.width = drawingCanvas.width;
backgroundCanvas.height = drawingCanvas.height;
4. Bind touch events: touchstart, touchmove, touchend and click
//Bind touch events
signatureArea.addEventListener('touchstart', startDrawing);
signatureArea.addEventListener('touchmove', draw);
signatureArea.addEventListener('touchend', stopDrawing);
clearButton.addEventListener('click', clearSignature);
saveButton.addEventListener('click', saveSignature);
5. Implement touch event callback functions: startDrawing, draw and stopDrawing
//Start drawing
function startDrawing(e) {
  e.preventDefault(); // Prevent default event
  var touch = e.touches[0]; // Get the coordinates of the touch point
  var rect = signatureArea.getBoundingClientRect(); // Get the location and size of the signature area
  lastX = touch.clientX - rect.left;
  lastY = touch.clientY - rect.top;
  isDrawing = true;
}

// drawing
function draw(e) {
  if (!isDrawing) return;
  var touch = e.touches[0];
  var rect = signatureArea.getBoundingClientRect();
  var x = touch.clientX - rect.left;
  var y = touch.clientY - rect.top;
  drawLine(lastX, lastY, x, y);
  lastX = x;
  lastY = y;
}

// Stop drawing
function stopDrawing() {
  isDrawing = false;
}
6. Implement the function of drawing line segments: drawLine
//Draw a solid line
function drawLine(x1, y1, x2, y2) {
  drawingCtx.beginPath(); // Start a new path
  drawingCtx.moveTo(x1, y1); // Move the brush to the starting point
  drawingCtx.lineTo(x2, y2); // Draw a straight line to the end point
  drawingCtx.lineWidth = 1; // Set the width of the line to 1 pixel
  drawingCtx.strokeStyle = '#000'; //Set the line color to black
  drawingCtx.stroke(); // Draw lines
}
7. Implement the function to clear the signature: clearSignature
//Clear signature
function clearSignature() {
  drawingCtx.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height); // Clear the contents of the drawing canvas
  backgroundCtx.clearRect(0, 0, backgroundCanvas.width, backgroundCanvas.height); // Clear the contents of the background canvas
}
8. Implement the function to save the signature: saveSignature
//Save signature
function saveSignature() {
  // draw white background
  backgroundCtx.fillStyle = 'white';
  backgroundCtx.fillRect(0, 0, backgroundCanvas.width, backgroundCanvas.height);

  // Copy the drawn signature to the canvas with a white background
  backgroundCtx.drawImage(drawingCanvas, 0, 0);

  //Convert the canvas content with white background to DataURL in PNG format
  var dataURL = backgroundCanvas.toDataURL("image/png");

  // Create a link element and set the download attribute
  var link = document.createElement('a');
  link.href = dataURL;
  link.download = 'Signature.png'; //Set the name of the downloaded file

  // Check whether saving to photo album is supported
  if ("download" in link) {
    link.style.display = "none";
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  } else {
    // If saving to the album is not supported, you can provide other methods or prompt the user to save manually
    alert("Cannot be saved directly to the album, please save the signature image manually.");
  }
}
9. Insert the canvas element into the DOM tree
//Insert the canvas element into the DOM tree
signatureArea.appendChild(drawingCanvas);
10.Full code
<!DOCTYPE html>
<html>
<head>
  <title></title>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
  <style>
    body {
      font-family: Arial, sans-serif;
    }

    #signatureArea {
      width: 100%;
      height: 300px;
      border: 1px solid #ccc;
      margin-bottom: 20px;
    }

    button {
      padding: 10px 20px;
      font-size: 16px;
      background-color: #4CAF50;
      color: white;
      border: none;
      cursor: pointer;
      border-radius: 4px;
    }

    button:hover {
      background-color: #45a049;
    }
  </style>
</head>
<body>
  <div id="signatureArea"></div>
  <button id="clearButton">Clear</button>
  <button id="saveButton">Save signature</button>

  <script type="text/javascript">
// Get DOM elements
var signatureArea = document.getElementById('signatureArea');
var clearButton = document.getElementById('clearButton');
var saveButton = document.getElementById('saveButton');

//define variables
var isDrawing = false; // Whether drawing is taking place
var lastX, lastY; //Coordinates of the last touch point

//Create two canvas elements
var drawingCanvas = document.createElement('canvas'); // used to draw signatures
var backgroundCanvas = document.createElement('canvas'); // Used to save the signature image with a white background
var drawingCtx = drawingCanvas.getContext('2d');
var backgroundCtx = backgroundCanvas.getContext('2d');
drawingCanvas.width = signatureArea.offsetWidth;
drawingCanvas.height = signatureArea.offsetHeight;
backgroundCanvas.width = drawingCanvas.width;
backgroundCanvas.height = drawingCanvas.height;

// Bind touch event
signatureArea.addEventListener('touchstart', startDrawing);
signatureArea.addEventListener('touchmove', draw);
signatureArea.addEventListener('touchend', stopDrawing);
clearButton.addEventListener('click', clearSignature);
saveButton.addEventListener('click', saveSignature);

// Start drawing
function startDrawing(e) {
  e.preventDefault();
  var touch = e.touches[0];
  var rect = signatureArea.getBoundingClientRect();
  lastX = touch.clientX - rect.left;
  lastY = touch.clientY - rect.top;
  isDrawing = true;
}

// drawing
function draw(e) {
  if (!isDrawing) return;
  var touch = e.touches[0];
  var rect = signatureArea.getBoundingClientRect();
  var x = touch.clientX - rect.left;
  var y = touch.clientY - rect.top;
  drawLine(lastX, lastY, x, y);
  lastX = x;
  lastY = y;
}

// Stop drawing
function stopDrawing() {
  isDrawing = false;
}

// draw solid line
function drawLine(x1, y1, x2, y2) {
  drawingCtx.beginPath();
  drawingCtx.moveTo(x1, y1);
  drawingCtx.lineTo(x2, y2);
  drawingCtx.lineWidth = 1;
  drawingCtx.strokeStyle = '#000';
  drawingCtx.stroke();
}

// clear signature
function clearSignature() {
  drawingCtx.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height);
  backgroundCtx.clearRect(0, 0, backgroundCanvas.width, backgroundCanvas.height);
}

//Save signature
function saveSignature() {
  // draw white background
  backgroundCtx.fillStyle = 'white';
  backgroundCtx.fillRect(0, 0, backgroundCanvas.width, backgroundCanvas.height);

  // Copy the drawn signature to the canvas with a white background
  backgroundCtx.drawImage(drawingCanvas, 0, 0);

  //Convert the canvas content with white background to DataURL in PNG format
  var dataURL = backgroundCanvas.toDataURL("image/png");

  // Create a link element and set the download attribute
  var link = document.createElement('a');
  link.href = dataURL;
  link.download = 'Signature.png'; // Set the name of the downloaded file

  // Check whether saving to photo album is supported
  if ("download" in link) {
    link.style.display = "none";
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  } else {
    // If saving to the album is not supported, you can provide other methods or prompt the user to save manually
    alert("Cannot be saved directly to the album, please save the signature image manually.");
  }
}

//Insert the canvas element into the DOM tree
signatureArea.appendChild(drawingCanvas);

  </script>
</body>
</html>
11. Rendering