I've been on the hunt for a reliable signature capture script that can save signatures to MySQL, and I finally found one that fits the bill. However, there are two issues that need addressing:
The canvas doesn't clear the signature when the clear button is pressed.
The image isn't submitted to MySQL when the save signature button is clicked.
Despite reaching out to the developer without any response, I'm optimistic that someone here can help me with this code conundrum.
Here's the HTML snippet:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Signature Pad</title>
<script type="text/javascript" src="jquery.min.js"></script>
</head>
<body>
<center>
<fieldset style="width: 435px">
<br/>
<br/>
<div id="signaturePad" style="border: 1px solid #ccc; height: 55px; width: 400px;"></div>
<br/>
<button id="clearSig" type="button">Clear Signature</button>
<button id="saveSig" type="button">Save Signature</button>
<div id="imgData"></div>
<div id="imgData"></div>
<br/>
<br/>
</fieldset>
</center>
</body>
</html>
On top of that, we have the necessary PHP and scripts:
$(document).ready(function () {
/** Set Canvas Size **/
var canvasWidth = 400;
var canvasHeight = 75;
/** IE SUPPORT **/
var canvasDiv = document.getElementById('signaturePad');
canvas = document.createElement('canvas');
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
canvas.setAttribute('id', 'canvas');
canvasDiv.appendChild(canvas);
if (typeof G_vmlCanvasManager != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
}
context = canvas.getContext("2d");
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
/** Redraw the Canvas **/
function redraw() {
canvas.width = canvas.width; // Clears the canvas
context.strokeStyle = "#000000";
context.lineJoin = "miter";
context.lineWidth = 2;
for (var i = 0; i < clickX.length; i++) {
context.beginPath();
if (clickDrag[i] && i) {
context.moveTo(clickX[i - 1], clickY[i - 1]);
} else {
context.moveTo(clickX[i] - 1, clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
}
/** Save Canvas **/
$("#saveSig").click(function saveSig() {
var sigData = canvas.toDataURL("image/png");
$("#imgData").html('Thank you! Your signature was saved');
var ajax = XMLHttpRequest();
ajax.open("POST", 'http://www.your-domain.com/folder/post-html.php');
ajax.setRequestHeader('Content-Type', 'application/upload');
ajax.send(sigData);
});
/** Clear Canvas **/
function clearSig() {
clickX = new Array();
clickY = new Array();
clickDrag = new Array();
canvas.width = canvas.width;
canvas.height = canvas.height;
}
/**Draw when moving over Canvas **/
$('#signaturePad').mousemove(function (e) {
if (paint) {
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
});
/**Stop Drawing on Mouseup **/
$('#signaturePad').mouseup(function (e) {
paint = false;
});
/** Starting a Click **/
function addClick(x, y, dragging) {
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
$('#signaturePad').mousedown(function (e) {
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
redraw();
});
});
Last but not least, let's take a look at how we handle the MySQL portion:
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"]))
{
$session_id = $_SERVER['REMOTE_ADDR'];
// Get the data
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
// Remove the headers (data:,) part.
// A real application should use them according to needs such as to check image type
$filteredData=substr($imageData, strpos($imageData, ",")+1);
// Need to decode before saving since the data we received is already base64 encoded
$unencodedData=base64_decode($filteredData);
//echo "unencodedData".$unencodedData;
$imageName = "sign_" . rand(5,1000) . rand(1, 10) . rand(10000, 150000) . rand(1500, 100000000) . ".png";
//Set the absolute path to your folder (i.e. /usr/home/your-domain/your-folder/
$filepath = "htdocs/alpha/site6/signature/images/" . $imageName;
$fp = fopen("$filepath", 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
//Connect to a mySQL database and store the user's information so you can link to it later
$link = mysql_connect('localhost','root', 'pwd') OR DIE(mysql_error);
mysql_select_db("trial", $link);
mysql_query("INSERT INTO customer (`session`, `image_location`) VALUES ('$session_id', '$imageName')") OR DIE(mysql_error());
mysql_close($link);
}
?>