admin管理员组

文章数量:1181399

I'm looking for a solution to add a signature to a form. One where someone can sign with their mouse or with their finger on a touch device. I'm wondering if I can use something like jSignature / to create an image, the process the form with php and create a PDF and then add the image to the PDF.

I've researched a bit and haven't found a clear solution for this. Basically I'm wanting to create a simple freelancer website contract that clients would sign online.

I'm looking for a solution to add a signature to a form. One where someone can sign with their mouse or with their finger on a touch device. I'm wondering if I can use something like jSignature https://willowsystems.github.io/jSignature/#/about/ to create an image, the process the form with php and create a PDF and then add the image to the PDF.

I've researched a bit and haven't found a clear solution for this. Basically I'm wanting to create a simple freelancer website contract that clients would sign online.

Share Improve this question asked Mar 21, 2017 at 18:42 droohdrooh 6784 gold badges20 silver badges52 bronze badges 4
  • 1 it looks like the library you linked allows for output of base64 Image. So you could have a javascript submit button that would export the image and and set that value to a <input type="hidden" name="signature-image" /> and then have the form post with javascript. – Jpsh Commented Mar 21, 2017 at 18:52
  • 1 Thanks, that's along the lines of what I was thinking. It looks like signatureconfirm.com is using jSignature in a way that I'm asking about. – drooh Commented Mar 21, 2017 at 19:15
  • glad I could point you in the right direction – Jpsh Commented Mar 21, 2017 at 19:20
  • Please keep in mind: maybe you can save an image that looks like a written signature, it may even be written by hand, just like the original, but that does not need to mean that it fulfills your country’s legal requirements. Most contracts are form-free, but when in dispute, you want to be able to demonstrate that undoubtedly person X entered a contract.. – Zim84 Commented Jan 23, 2023 at 15:19
Add a comment  | 

2 Answers 2

Reset to default 32

I've created a fairly minimum prototype that uses the <canvas> element to allow signature drawings. This drawing is then added to the form as a base64 url.

Short explanation of the code:

  • Create a <canvas> element
  • Define events for mousedown (pencil down), mousemove (continue drawing) and mouseup (pencil up)
  • Draw on the canvas by creating a line between the previous and current coordinates. Note that if you would draw a lot of dots on the current coordinate, you will not get a smooth line when moving fast with your mouse.
  • When you stop drawing, we get the canvas contents as an image using canvas.toDataUrl(). This is then set on a hidden input on the form.

var canvas = document.getElementById('signature');
var ctx = canvas.getContext("2d");
var drawing = false;
var prevX, prevY;
var currX, currY;
var signature = document.getElementsByName('signature')[0];

canvas.addEventListener("mousemove", draw);
canvas.addEventListener("mouseup", stop);
canvas.addEventListener("mousedown", start);

function start(e) {
  drawing = true;
}

function stop() {
  drawing = false;
  prevX = prevY = null;
  signature.value = canvas.toDataURL();
}

function draw(e) {
  if (!drawing) {
    return;
  }
  // Test for touchmove event, this requires another property.
  var clientX = e.type === 'touchmove' ? e.touches[0].clientX : e.clientX;
  var clientY = e.type === 'touchmove' ? e.touches[0].clientY : e.clientY;
  currX = clientX - canvas.offsetLeft;
  currY = clientY - canvas.offsetTop;
  if (!prevX && !prevY) {
    prevX = currX;
    prevY = currY;
  }

  ctx.beginPath();
  ctx.moveTo(prevX, prevY);
  ctx.lineTo(currX, currY);
  ctx.strokeStyle = 'black';
  ctx.lineWidth = 2;
  ctx.stroke();
  ctx.closePath();

  prevX = currX;
  prevY = currY;
}

function onSubmit(e) {
  console.log({
    'name': document.getElementsByName('name')[0].value,
    'signature': signature.value,
  });
  return false;
}
canvas#signature {
  border: 2px solid black;
}

form>* {
  margin: 10px;
}
<form action="submit.php" onsubmit="return onSubmit(this)" method="post">
  <div>
    <input name="name" placeholder="Your name" required />
  </div>
  <div>
    <canvas id="signature" width="300" height="100"></canvas>
  </div>
  <div>
    <input type="hidden" name="signature" />
  </div>
  <button type="submit">Send</button>
  <form>

On the PHP side, you should then be able to decode that base64 string and save it to a file like this:

$img = $_POST['signature'];
$data = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $img));
file_put_contents('storage/signature.png', $data);

Note for mobile touch events

If you need mobile/touch capability, simply change the events to:

  • mousemove : touchmove
  • mouseup : touchend
  • mousedown : touchstart

If you need both mobile and mouse inputs, you can duplicate the 3 addEventListener lines so all 6 events are tracked.

Tnx so much! Instead of canvas.offsetLeft and offsetTop I corrected the offset by;

        var rect = canvas.getBoundingClientRect();
        var xoff = rect.left;
        var yoff = rect.top; 

本文标签: javascriptCreate an HTML form with DigitalElectronic Signature using phpStack Overflow