Here's another canvas based version with variable width (based on drawing velocity) curves: demo at http://szimek.github.io/signature_pad and code at https://github.com/szimek/signature_pad.
https://i.stack.imgur.com/9vnaY.jpg
A canvas element with some JavaScript would work great.
In fact, Signature Pad (a jQuery plugin) already has this implemented.
Here is a quickly hacked up version of this using SVG I just did. Works well for me on my iPhone. Also works in a desktop browser using normal mouse events.
Perhaps the best two browser techs for this are Canvas, with Flash as a back up.
We tried VML on IE as backup for Canvas, but it was much slower than Flash. SVG was slower then all the rest.
With jSignature ( http://willowsystems.github.com/jSignature/ ) we used Canvas as primary, with fallback to Flash-based Canvas emulator (FlashCanvas) for IE8 and less. Id' say worked very well for us.
The options already listed are very good, however here a few more on this topic that I've researched and came across.
1) http://perfectionkills.com/exploring-canvas-drawing-techniques/
2) http://mcc.id.au/2010/signature.html
3) https://zipso.net/a-simple-touchscreen-sketchpad-using-javascript-and-html5/
And as always you may want to save the canvas to image:
http://www.html5canvastutorials.com/advanced/html5-canvas-save-drawing-as-an-image/
good luck and happy signing
@szimek (selected answer) has a well-documented solution for those who want a full-featured module with a MIT license that's good-to-go. @heycam has a simpler solution that requires no libraries or plugins, has no licenses, and can be easily customized; all of which makes it a better fit for my needs. This post tries to explain how exactly his solution works.
Basic workflow:
Create a functionally blank svg to contain the signature Reserve a path element inside the container svg Use touch events (touchstart, touchmove, touchend) for the user to draw the signature using touch inputs Use mouse events (mousedown, mousemove, mouseup, mouseout) for the user to draw the signature using mouse inputs On each event, detect the type of input (touch, mouse) to get the X,Y coordinates of the path the user is drawing Append each path to the d attribute (path coordinates) of the path element so it displays to the user Add a helper function to output the signature path (path.d), which is just a string you can plug back into the path.d later on to restore the signature Add a helper function to clear the path.d value
Here's @heycam's solution as a runnable snippet:
//init let r = document.getElementById('r'), p = document.getElementById('p'), signaturePath = '', isDown = false, svg = document.getElementById('sig_panel'), b_show = document.getElementById('show'), b_clear = document.getElementById('clear'), pathdata = document.getElementById('pathdata'); //drawing functions function isTouchEvent(e) { return e.type.match(/^touch/); } function getCoords(e) { if (isTouchEvent(e)) { return e.targetTouches[0].clientX + ',' + e.targetTouches[0].clientY; } return e.clientX + ',' + e.clientY; } function down(e) { signaturePath += 'M' + getCoords(e) + ' '; p.setAttribute('d', signaturePath); isDown = true; if (isTouchEvent(e)) e.preventDefault(); } function move(e) { if (isDown) { signaturePath += 'L' + getCoords(e) + ' '; p.setAttribute('d', signaturePath); } if (isTouchEvent(e)) e.preventDefault(); } function up(e) { isDown = false; if (isTouchEvent(e)) e.preventDefault(); } //input handlers r.addEventListener('touchstart', down, false); r.addEventListener('touchmove', move, false); r.addEventListener('touchend', up, false); r.addEventListener('mousedown', down, false); r.addEventListener('mousemove', move, false); r.addEventListener('mouseup', up, false); r.addEventListener('mouseout', up, false); //helper functions function clearSignature() { pathdata.textContent = ''; signaturePath = ''; p.setAttribute('d', ''); } function getSignature() { pathdata.textContent = signaturePath; return signaturePath; } //button handlers b_show.addEventListener('click', getSignature); b_clear.addEventListener('click', clearSignature); svg { margin: .5em; border: 1px solid gray; border-radius: .5em; } .flex { display: flex; } button { margin: .5em; } #pathdata { font-family: monospace; background: #ddd; padding: 1em; margin: 1em .5em; }
Saving the path.d
value on the server (and client cache) is all I need. Others may need to save the entire svg
itself with path.d
filled in, or convert it to other formats (JPEG, PNG, PDF) using appropriate converters (not covered here).
I plan to go a step beyond and add user controls to manage the following:
line thickness: path.stroke-width
line color: path.stroke
line quality: path.shape-rendering
and theme the signature field (as part of my custom form lib):
container dimensions: rect.width, rect.height
container background: rect.fill
eliminate the "sign here" line: line
Another OpenSource signature field is https://github.com/applicius/jquery.signfield/ , registered jQuery plugin using Sketch.js .
Success story sharing