Mobile-friendly & Pressure-Sensitive JavaScript Signature library – czSignature.js

Category: Image , Javascript | September 2, 2025
Authorcyberzilla
Last UpdateSeptember 2, 2025
LicenseMIT
Views114 views
Mobile-friendly & Pressure-Sensitive JavaScript Signature library – czSignature.js

czSignature.js is a JavaScript signature library that creates beautiful, pressure-sensitive digital signatures on HTML5 canvas elements.

It captures stylus pressure for natural stroke variations and provides advanced export & data handling capabilities for web applications requiring signature functionality.

Features:

  • Pressure Sensitivity: Captures stylus pressure for natural stroke width variation with velocity-based fallback.
  • Modern API: Built with ES6 classes and modern Pointer Events API for consistent input handling.
  • Event-Driven: Emits events like drawStart, drawEnd, and clear to build a reactive UI..
  • Multiple Export Formats: Generate high-quality SVG vector files or high-DPI PNG/JPEG images.
  • Advanced Stroke Smoothing: Configurable smoothing algorithms with fade-in/fade-out effects.
  • Serialization Support: Save and restore signature data as JSON objects for backend storage.
  • Responsive Canvas: Automatically adjusts to canvas size changes and window resizing.
  • Trim Output: Export only the signature bounds with configurable padding.

Use cases:

  • E-signature Applications: Implement signature capture for contracts, forms, and legal documents requiring authentic digital signatures.
  • Creative Drawing Apps: Build sketching or annotation tools that benefit from pressure-sensitive brush dynamics.
  • Document Management Systems: Add signature functionality to PDF viewers, approval workflows, or document signing platforms.
  • Medical and Legal Software: Create HIPAA-compliant signature capture for patient forms, witness statements, or consent documents.

How to use it:

1. Create an HTML5 canvas element with the touch-action: none; declaration to prevent the page from scrolling on mobile devices while a user is signing.

<canvas id=”signature-pad”></canvas>

#signature-pad {
  width: 100%; 
  height: 100%; 
  touch-action: none;
  /* more styles here */
}

2. Download and load the ‘czSignature.js’ script in your document.

<script src="czSignature.js"></script>

3. Initialize the signature pad:

const instance = new czSignature(document.getElementById('signature-pad'), {
  // options here
});

4. Available configuration options. You can pass these during initialization or update them later with the updateOptions() method.

  • penColor (string): Stroke color, defaults to ‘#000000’
  • backgroundColor (string): Canvas background color, defaults to ‘#ffffff’
  • minWidth (number): Minimum brush width, defaults to 0.5
  • maxWidth (number): Maximum brush width, defaults to 2.5
  • pressureSupport (boolean): Enable pressure sensitivity, defaults to false
  • smoothingRatio (number): Stroke smoothing amount from 0-1, defaults to 0.5
  • smoothingMode (string): ‘post’ for responsive feel or ‘live’ for smoother visuals
  • smoothingFadePoints (number): Points to apply reduced smoothing at stroke ends
  • dpi (number): Output resolution for raster exports, defaults to 300
  • trimOutput (boolean): Crop exports to signature bounds, defaults to false
  • trimPadding (number): Padding around trimmed signatures, defaults to 16
  • outputPenColor (string): Override pen color for exports
  • outputBackgroundColor (string): Override background for exports, supports ‘transparent’
const instance = new czSignature(document.getElementById('signature-pad'), {
  penColor: '#000000',
  backgroundColor: '#ffffff',
  minWidth: 0.5,
  maxWidth: 2.5,
  velocityFilterWeight: 0.7,
  dotSize: 2.0,
  minDistance: 0.8,
  smoothingRatio: 0.5,
  smoothingFadePoints: 4,
  smoothingMode: 'post',
  pressureSupport: false,
  dpi: 300,
  trimOutput: false,
  trimPadding: 16,
  outputPenColor: null,
  outputBackgroundColor: null,
});

5. API methods.

  • instance.clear(): Clears the canvas and resets signature data
  • instance.undo(): Removes the last drawn stroke
  • instance.isEmpty(): Returns true if no signature data exists
  • instance.updateOptions(options): Updates configuration without losing signature data
  • instance.toData(): Returns signature as JSON-serializable array of stroke objects
  • instance.fromData(data): Loads signature from previously saved data
  • instance.toSVG(): Exports signature as SVG string with vector paths
  • instance.toDataURL(format): Returns Base64 data URL for PNG or JPEG export
  • instance.destroy(): Removes event listeners for cleanup

6. Event handlers.

signature.on('drawStart', () => {
  console.log('User started drawing');
  enableSaveButton();
});
signature.on('drawEnd', (data) => {
  console.log('Stroke completed:', data.stroke);
  validateSignature();
});
signature.on('clear', () => {
  console.log('Signature cleared');
  disableSaveButton();
});
signature.on('undo', (data) => {
  console.log('The number of strokes left:', strokesLeft);
});
signature.on('resize', () => {
  console.log('Signature resized');
});

7. For production applications, you often need different export settings than display settings:

// Save current options
const originalOptions = { ...signature.options };
// Configure for export
instance.updateOptions({
    trimOutput: true,
    outputBackgroundColor: 'transparent',
    outputPenColor: '#000000',
    dpi: 600
});
// Generate high-quality export
const dataURL = instance.toDataURL('image/png');
const svgString = instance.toSVG();
// Restore original settings
instance.updateOptions(originalOptions);

8. For a better user experience, you can save the raw vector data of a signature:

// Save the signature data to localStorage
function saveSignatureData() {
    const data = instance.toData();
    localStorage.setItem('pendingSignature', JSON.stringify(data));
}
// Load the signature data from localStorage
function loadSignatureData() {
    const dataJson = localStorage.getItem('pendingSignature');
    if (dataJson) {
        const data = JSON.parse(dataJson);
        instance.fromData(data);
    }
}
// Call loadSignatureData on page load
loadSignatureData();
// Call saveSignatureData on drawEnd or before unload
instance.on('drawEnd', saveSignatureData);

FAQs:

Q: How do I handle high-DPI (Retina) displays correctly?
A: The library handles this automatically. The #setupCanvas method checks window.devicePixelRatio and scales the canvas rendering surface accordingly.

Q: Can I make the background transparent on an exported PNG?
A: Yes. This is a common requirement. To do this, you use the updateOptions method to temporarily set outputBackgroundColor to 'transparent' before calling toDataURL('image/png').

Q: What’s the real difference between smoothingMode: 'post' and 'live'?
A: 'post' (the default) provides a better user experience during drawing. It renders the raw, slightly jagged line as you draw, so it feels instantaneous. The smoothing is only applied once you finish the stroke. 'live' applies the smoothing algorithm in real-time as you draw. This looks better visually during the drawing process but can sometimes introduce a tiny bit of lag on complex strokes or slower devices. We’d stick with 'post' for most use cases.

Q: Can I save signatures to a database?
A: Use the toData() method to serialize signatures as JSON objects suitable for database storage. The fromData() method reconstructs signatures from saved data.

Q: How do I implement signature validation?
A: Use event listeners to track drawing completion, check isEmpty() for content validation, and analyze the stroke data returned by toData() for complexity requirements.

Alternatives:

  • Signature Pad: The most popular signature library with simpler implementation but limited customization options and no pressure sensitivity support.
  • jSignature: jQuery-based solution with vector output focus but outdated architecture and limited modern browser optimization.

Related Resources:

You Might Be Interested In:


Leave a Reply