I was recently asked to create a signature pad for desktop and mobile browsers to save customer signatures. The solution included using the <canvas>
element and adding event listeners for both mouse and touch events to draw the signature lines on the canvas.
First thing is we have to create a canvas element.
<canvas id="canvas" width="500" height="100" style="border: 1px solid #ccc;"></canvas>
Next we declare our variables and add the event listeners.
var canvasWidth = 400; //canvas width
var canvasHeight = 60; //canvas height
var canvas = document.getElementById('canvas'); //canvas element
var context = canvas.getContext("2d"); //context element
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
canvas.addEventListener("mousedown", mouseDown, false);
canvas.addEventListener("mousemove", mouseXY, false);
document.body.addEventListener("mouseup", mouseUp, false);
//For mobile
canvas.addEventListener("touchstart", mouseDown, false);
canvas.addEventListener("touchmove", mouseXY, true);
canvas.addEventListener("touchend", mouseUp, false);
document.body.addEventListener("touchcancel", mouseUp, false);
To draw on a canvas you first have to create a path. Then move from one point (x,y), draw a line to another point and then fill the line so it becomes visible on the canvas.
function draw() {
context.clearRect(0, 0, canvas.width, canvas.height); // Clears the canvas
context.strokeStyle = "#000000"; //set the "ink" color
context.lineJoin = "miter"; //line join
context.lineWidth = 2; //"ink" width
for (var i = 0; i < clickX.length; i++) {
context.beginPath(); //create a path
if (clickDrag[i] && i) {
context.moveTo(clickX[i - 1], clickY[i - 1]); //move to
} else {
context.moveTo(clickX[i] - 1, clickY[i]); //move to
}
context.lineTo(clickX[i], clickY[i]); //draw a line
context.stroke(); //filled with "ink"
context.closePath(); //close path
}
}
The MouseDown/TouchStart event is used to save that the mouse was pressed, store the current X and Y coordinates of the mouse and begin drawing.
function mouseDown(e)
{
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
draw();
}
In the MouseUp/TouchEnd event, we save that the mouse was released.
function mouseUp() {
paint = false;
}
Last we finish up with the MouseMove/TouchMove event. This handler has to do the following: check if the mouse is pressed, if it is pressed then draw a line from previous coordinates to current coordinates.
function mouseXY(e) {
if (paint) {
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
draw();
}
}
Demo: http://demos.ijasoneverett.com/html5-sigpad.php
Source Code: https://gist.github.com/ijason/5898019
7 Comments
Thanks, works very well !! π I have written a similar script with smooth curves, please have a look http://www.supersignature.com
Cheers!, Andy.
Looks great so far on my page! Having an issue with the mouse offset. the line is drawn about 120×90 px away from my cursor…any thoughts?
I have the same issue. Did you find a resolution?
It is working well on my website, thanks! π
Hi, the link provided to source code is not working please help.
Hi, the link provided to source code is not working please help.
https://gist.github.com/ijason/5898019
Anyone know how to get this to work with the changes in iOS 11.3:
https://bugs.webkit.org/show_bug.cgi?id=182521
Something like this is the fix?
https://stackoverflow.com/questions/49500339/cant-prevent-touchmove-from-scrolling-window-on-ios