Anyone know how this can be done? Would you use a canvas object, svg, jQuery, etc?
-
See demo https://codepen.io/yguo/pen/OyYGxQ – lubosdz Jun 16 '23 at 12:36
7 Answers
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.
-
2Thanks in advance, best js signature lib I ever seen. Don't know why this answer just had 3 votes. https://github.com/szimek/signature_pad – VAdaihiep Aug 02 '13 at 10:17
-
4I like that this does not rely on other js libraries and how well it looks. One note about using it which helped me: add a border to the canvas so you can see how it is being adjusted. Also note that css changes to the canvas do some crazy things, so just specify a height and width in the canvas element if this get out of control. – Brian McGinity Aug 17 '13 at 04:25
-
Lack of documentation isn't helpful, but the demo page lays it all out pretty clearly. I am working on storing it in the database and retrieving. This is a REALLY slick library. Thanks szimek! – Jake Sep 04 '13 at 05:43
-
7Jake, what exactly is missing in your opinion in the documentation provided in README file? I'm open to suggestions how to improve it. – szimek Sep 04 '13 at 12:00
-
12I apologize. I think your documentation is actually adequate. It seemed limited until I realized just how easy this is to use. I got it fully implemented in a form, storing in the database and retrieving back to page in under an hour. I suppose, I was comparing it to libraries that were much more complex to use like the chosen answer above. I hadn't worked with data URIs before, but it is a truly brilliant way to handle the storage of the data. So, I just had to acclimate myself to those and then storing and retrieving in the database was so... easy... wow. Thanks again! – Jake Sep 04 '13 at 16:18
-
1No need to apologize :) I'm glad you like it. I'll probably add some info or at least a link to the wiki page about handling data URIs on the server side. Cheers! – szimek Sep 05 '13 at 07:31
-
szimek, your signature pad library works wonderfully, was exactly what I was looking for and is very easy to use. Thank you! – h-bomb Feb 07 '14 at 05:19
-
i was not able to somehow disable scroll for ios somehow but this plugin works like charm! Recomended – poorva Feb 20 '14 at 12:51
-
I'm having a few problems with the signature pad plugin, I think it's mainly due to the fact I've removed all the absolute positioning (the signature pad is part of a page, not a page on it's own like in the demo). Been hacking away but it's quite frustrating. – martincarlin87 Mar 28 '14 at 09:26
-
-
@szimek Just testing on desktop for now. Couldn't get it to work for some reason. – martincarlin87 Mar 28 '14 at 12:59
-
Sorry it took so long for me to accept this answer. I abandoned the project a few years ago. – Mark Richman Jun 02 '14 at 15:59
-
@szimek I need 2 signatures in a same page, how do I do it? – Ronaldinho Learn Coding Sep 15 '15 at 14:30
-
-
2@RonaldinhoLearnCoding check out the README file - there's a list of all possible options. The one you're looking for is called "penColor". – szimek Sep 18 '15 at 08:42
-
@szimek Thank you very much for a wonderful plugin and an intuitive support! – Ronaldinho Learn Coding Sep 18 '15 at 13:47
A canvas element with some JavaScript would work great.
In fact, Signature Pad (a jQuery plugin) already has this implemented.
-
2
-
I found this plugin really hard to use unforutnately. All the demos were very specific and tricky to apply. Definitely like the other signature pad approach better: http://stackoverflow.com/a/17200715/76672 With pretty much no documentation, I was able to get it working... – Jake Sep 04 '13 at 05:46
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.

- 2,188
- 15
- 19
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.

- 4,926
- 25
- 24
-
This is really nice... I like it's smoothing effects. Best I've seen. – Camden S. Jun 04 '13 at 19:04
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

- 665
- 7
- 11
@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 containersvg
- 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 thepath
element so it displays to the user - Add a helper function to output the signature path (
path.d
), which is just astring
you can plug back into thepath.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;
}
<svg id="sig_panel" xmlns="http://www.w3.org/2000/svg" width="300" height="100" viewBox="0 0 300 100">
<rect id="r" width="300" height="100" fill="#ffa"/>
<line x1="0" y1="80" x2="300" y2="80" stroke="#666" stroke-width="1" stroke-dasharray="3" shape-rendering="crispEdges" pointer-events="none"/>
<path id="p" stroke="navy" stroke-width="2" fill="none" pointer-events="none"/>
</svg>
<div class="flex">
<button id="show">Show signaure path data</button>
<button id="clear">Clear signature</button>
</div>
<div id="pathdata"></div>
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

- 2,041
- 25
- 19
Another OpenSource signature field is https://github.com/applicius/jquery.signfield/ , registered jQuery plugin using Sketch.js .

- 9,118
- 3
- 30
- 41