brinley / jSignature

jQuery plugin for adding web signature functionality
http://www.unbolt.net/jSignature
690 stars 529 forks source link

jSignature

jSignature is a jQuery plugin which simplifies creation of a signature capture field in the browser window, allowing a user to draw a signature using mouse, pen, or finger.

jSignature captures signature as vector outlines of the strokes. Although jSignature can export great bitmap (PNG) too, extraction of highly scalable stroke movement coordinates (aka vector image) of the signature allows much greater flexibility of signature rendering.

A extra effort (through smoothing and pressure simulation) is made to make the strokes look pretty on the screen while these are drawn by the signor.

All major desktop, tablet and phone browsers are supported. HTML5 Canvas element is used by default. We fall back on Flash-based Canvas element emulator (FlashCanvas) when actual Canvas is not supported by the browser (Internet Explorer v.8 and lower).

Real-time jSignature renders only the device-appropriate "prettiest" approximation of what we capture. Capture of data is always same - we capture as many movement coordinates as possible. Rendering of strokes differs per browser's capabilities, efficiency of the device, screen size.

This degrading and enhancing of screen representation of the captured signature is done on purpose to insure that rendering does not impead on the responsiveness of capture. For example, on slow rendering devices (Android Browser, FlashCanvas-based Canvas emulation) smoothing is kicked up a notch to compensate for large gaps in captured stroke coordinates - a result of inefficiency of capture device. In all cases, customer shold be pleased by responsiveness and beauty of the drawing.

jSignature makes it easy to pluck itself into an existing styled site. jSignature automatically detects the colors used on the wrapping element (text color = pen color, background = background) and auto-picks a pleasing middle-shade for 'decor' (signature line). jSignature adapts well to fixed and variable width web page designs, and various size screens (phones, tablets, computer screens) and automatically rescales the drawing area and signature when parent element changes size.

See demos here.

Adding jSignature to your page

Look into libs folder in the source tree. Pick 3 files from there:

  1. jSignature.min.js (The '' means you have choice. You can pick regular jQuery-centric build or a special jQuery.NoConflict build.)

  2. flashcanvas.js

  3. flashcanvas.swf

jSignature depends on (more or less recent) jQuery

If you do NOT intend to support IE 7 and 8 you don't need to download the FlashCanvas files.

Note that FlashCanvas is a cohesive group of two files, flashcanvas.swf and flashcanvas.js, both of which must be located together in the same folder. Do not host them from separate folders as flashcanvas.js looks for flashcanvas.swf in the same folder it was served from. Do not rename flashcanvas.js to anything else as it looks for itself in the DOM by that name to figure out where to load flashcanvas.swf from.

jSignature itself has three distinct pieces of code rolled into one minified deployable:

  1. Code that prepares a Canvas element. It includes detection of browser features, maximizing a canvas within the confines of a div, setting up emulated Canvas using Flashcanvas, when needed.
  2. Code that handles actual signature capture + data import / export API. It attaches and listens to movement event handlers, stores stroke data inside data structure, handles API calls.
  3. Plugins that help you get the signature data in convenient for you format, like raw data coordinates, image, compressed url-compatible string, SVG.

If you are certain that your audience will be limited to a specific browser engine (you deploy through an embedded browser widget, using something like PhoneGap) you can roll up your sleeves and yank out the part #1. If you know you will need only one export / import plugin, remove the plugins you don't need from the minified deployable.

More custom data export/import plugins can be loaded separately without reminifying the main deployable. But, minifying is fun and easy to do. Just take a look at wscript.py file and change a few lines to include / exclude some parts.

For the "generic" deployment scenario (which includes support of old IE) add this to your page:

<!-- this, preferably, goes inside head element: -->
<!--[if lt IE 9]>
<script type="text/javascript" src="https://github.com/brinley/jSignature/raw/master/path/to/flashcanvas.js"></script>
<![endif]-->

<div id="signature"></div>

<!-- you load jquery somewhere before jSignature ... -->
<script src="https://github.com/brinley/jSignature/raw/master/path/to/jSignature.min.js"></script>
<script>
    $(document).ready(function() {
        $("#signature").jSignature()
    })
</script>

Explained:

API

The following method becomes exposed on top of jQuery objects: .jSignature(String command, *args)

Arguments vary per command. When provided, command is expected to be a string with a command for jSignature. Commands supported at this time:

Usage examples:

var $sigdiv = $("#signature")
$sigdiv.jSignature() // inits the jSignature widget.
// after some doodling...
$sigdiv.jSignature("reset") // clears the canvas and rerenders the decor on it.

// Getting signature as SVG and rendering the SVG within the browser. 
// (!!! inline SVG rendering from IMG element does not work in all browsers !!!)
// this export plugin returns an array of [mimetype, base64-encoded string of SVG of the signature strokes]
var datapair = $sigdiv.jSignature("getData", "svgbase64") 
var i = new Image()
i.src = "data:" + datapair[0] + "," + datapair[1] 
$(i).appendTo($("#someelement")) // append the image (SVG) to DOM.

// Getting signature as "base30" data pair
// array of [mimetype, string of jSignature's custom Base30-compressed format]
datapair = $sigdiv.jSignature("getData","base30") 
// reimporting the data into jSignature.
// import plugins understand data-url-formatted strings like "data:mime;encoding,data"
$sigdiv.jSignature("setData", "data:" + datapair.join(",")) 

See tests and index.html for more examples.

Data Import / Export (and Plugins)

The following plugins (data formats) are part of mainline jSignature minified distributable:

Choosing the export / storage format.

I know you are tempted to want "images" from jSignature, but, please, control yourself, and stay away. Instead, contemplate capturing "base30" or "svg" data and enhance + render that in postproduction, server-side.

If you export "bitmap", the image will retain actual drawing colors, size, defects, and, to top it off, may not work on all browsers.

If you want to force yourself to use only Black on top of White signature capture web page style forever, DO use bitmap export. If you want to have your database admin scream at you because backup of database with all that bitmap data takes more than a day, DO use bitmap export. If you want your sales / business dept to scream at you because your signature capture format cannot be easily integrated into their new carefully-styled, wizbang product / service, DO use bitmap export. If you want to explain why siganture format export you chose does not work on all target platforms, DO use bitmap export. If you want to take the easy route now, and make the the IT person that will come in after you are fired do the difficult task of applying ImageMagic wisardry upon a mess of colored pixels you decided to collect, DO use bitmap export format.

If the use of the captured signature has anything to do with "business" or "printing" or "multiple presentation venues" use the Vector formats like "base30" or "svg" data and enhance + render that in postproduction. Decompression and sample, rudimentary rendering code (.Net, PHP as of Feb 2012) can be found in "extras" folder. You would use these as core that provides loop-able coordinate data arrays for your own rendering logic.

Events

The dom element upon which jSignature was initialized emits 'change' event immediately after a stroke is done being added to the storage. (In other words, when user is done drawing each stroke. If user draws 3 strokes, this event is emitted 3 times, after each stroke is done.)

Here is how you would bind to that event:

$("#signature").bind('change', function(e){ /* 'e.target' will refer to div with "#signature" */ })

Event is emitted asynchronously through a "thread" ( setTimeout(..., 3) ) so you don't need to wrap your event handler into "thread" of any kind, as jSignature widget will go on and will not be waiting for you to be done with your custom event handler logic.

License, Copyright

MIT License

See source header for full and most current Copyright attributions.