npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

v-signature

v1.2.3

Published

take on-screen virtual signature

Readme

v-signature

NPM Version NPM Downloads License

🌐 Live Demo / Interactive Playground Studio

v-signature is an ultra-lightweight, responsive HTML5 canvas signature pad library written in pure vanilla JavaScript. Capture smooth, high-fidelity digital signatures using dynamic calligraphy brush dynamics, custom text watermarks, baseline signing guidelines, and export them instantly to vector SVG, JPEG, PNG, or whitespace-trimmed signature images.

Designed for seamless integration into Laravel, React, Vue, Angular, Node, and vanilla web applications.


Key Features

  • 🚀 Zero Dependencies: Lightweight vanilla JavaScript capture engine.
  • 🖋️ Premium Brush Presets: built-in Fountain, Feather Quill, Gel, Calligraphy Brush, and Highlighter pen presets.
  • 📈 Dynamic Physics: Velocity-sensitive line width calculations for expressive drawing.
  • 📐 Baseline Guideline Layer: Dotted signature helper line with titles (can be omitted on export).
  • 🏢 Watermark Support: Draw transparent text watermarks rotated behind drawings.
  • 🖱️ Custom Pointer Cursors: Self-contained SVG pointers (fountain pen, quill, pencil) that work anywhere.
  • ✂️ Whitespace Autocropping: Trim margins automatically to export only the signature bounding box.
  • 💾 Multiple Formats: Export drawings as SVG (vector XML code), JPEG, standard PNG, or trimmed PNG.
  • 🎨 Photoshop Studio UI: Responsive, fullscreen, double-sidebar playground demo page.

Installation

Install v-signature via npm:

npm install v-signature

Importing

ES Modules

import vSignature from 'v-signature';

// make it globally accessible if needed
window.vSignature = vSignature;

CommonJS

const vSignature = require('v-signature');

window.vSignature = vSignature;

Quick Start

Create a hidden input element to hold the signature base64 data stream:

<input type="hidden" id="signature-data" class="signature">

Initialize vSignature in your script:

document.addEventListener('DOMContentLoaded', () => {
    // initialize using input selector
    const signature = new vSignature('signature-data');
});

Configuration Options

You can pass configuration parameters during initialization to style the canvas, change brush physics, add watermarks, and customize pointer icons:

const signature = new vSignature('signature-data', {
    // structural elements
    canvas: 'custom-canvas-id', // optional custom canvas element selector
    clear: 'clear-btn-id',       // optional clear trigger selector
    save: 'save-btn-id',         // optional save trigger selector
    undo: 'undo-btn-id',         // optional undo trigger selector
    redo: 'redo-btn-id',         // optional redo trigger selector

    options: {
        // canvas dimensions
        width: '100%',
        height: '350px',
        backgroundColor: '#ffffff',
        border: '1px dashed #cccccc',
        borderRadius: '8px',
        disabled: false,

        // brush style preset
        // options: 'fountain' | 'pen' | 'quill' | 'feather' | 'calligraphy' | 'gel' | 'brush' | 'highlighter' | 'custom'
        style: 'fountain',
        color: '#000000',
        lineWidth: 2,
        lineJoin: 'round', // options: 'round' | 'bevel' | 'miter'
        opacity: 1.0,

        // custom physics (active when style is 'custom' or 'fountain')
        minWidth: 0.5,
        maxWidth: 3.0,
        velocitySensitivity: 0.7,

        // shadow blur / ink bleed
        shadowBlur: 0,
        shadowColor: null,

        // cursor pointer styling
        // options: 'default' | 'pen' | 'feather' | 'pencil' | 'custom' | custom image path/URL string
        pen: 'default',

        // custom watermark layer
        watermark: null, // watermark text string
        watermarkColor: 'rgba(0, 0, 0, 0.05)',
        watermarkFont: '32px sans-serif',
        watermarkAngle: -30,

        // guideline baseline layer
        guideLine: null, // text description (e.g. "sign here") or true for line only
        guideLineColor: 'rgba(0, 0, 0, 0.15)',
        guideLineExport: false // set true to burn guideline into export files
    }
});

Public Methods

  • on(event, callback): Register an event callback for canvas updates.

    // listen to changes
    signature.on('change', (data) => {
        console.log('signature changed: ', data);
    });
  • isEmpty(): Returns true if the signature canvas is empty.

    if (signature.isEmpty()) {
        console.log('canvas is empty');
    }
  • disable(): Locks the signature pad to prevent drawing.

    signature.disable();
  • enable(): Unlocks the signature pad to allow drawing.

    signature.enable();
  • clear(): Wipes all strokes and resets the canvas state.

    signature.clear();
  • undo(): Undo the last drawn vector stroke.

    signature.undo();
  • redo(): Redo the last undone vector stroke.

    signature.redo();
  • setPen(type): Change the active cursor pointer style dynamically.

    signature.setPen('quill');
  • toPNG(): Returns base64 PNG data URL string containing the transparent signature.

    const pngDataUrl = signature.toPNG();
  • downloadPNG(): Triggers browser file download of the transparent signature as a PNG file.

    signature.downloadPNG();
  • toJPEG(): Returns base64 JPEG data URL string containing the signature on a solid white background.

    const jpegDataUrl = signature.toJPEG();
  • downloadJPEG(): Triggers browser file download of the signature as a solid white-background JPEG file.

    signature.downloadJPEG();
  • toSVG(): Generates and returns raw vector inline SVG XML markup string.

    const svgMarkup = signature.toSVG();
  • downloadSVG(): Triggers browser file download of the signature as a vector .svg file.

    signature.downloadSVG();
  • toTrimmedPNG(): Automatically crops margins and returns base64 PNG data URL cropped directly to drawing bounds.

    const trimmedPngUrl = signature.toTrimmedPNG();
  • downloadTrimmedPNG(): Triggers browser file download of the cropped transparent signature as a PNG file.

    signature.downloadTrimmedPNG();
  • toTrimmedJPEG(): Automatically crops margins and returns base64 JPEG data URL cropped directly to drawing bounds on a white background.

    const trimmedJpegUrl = signature.toTrimmedJPEG();
  • downloadTrimmedJPEG(): Triggers browser file download of the cropped signature as a white-background JPEG file.

    signature.downloadTrimmedJPEG();
  • toTrimmedSVG(): Generates and returns cropped vector XML SVG markup string dynamically using viewBox coordinates.

    const trimmedSvg = signature.toTrimmedSVG();
  • downloadTrimmedSVG(): Triggers browser file download of the cropped signature as a vector .svg file.

    signature.downloadTrimmedSVG();
  • toData(): Exports raw array of stroke coordinates and speed dynamics.

    const strokes = signature.toData();
  • fromData(data): Imports and renders raw coordinates onto the signature canvas.

    signature.fromData(strokes);

License

MIT License. See the LICENSE file.