Signature Pad

A canvas you sign with a finger, stylus or mouse. Strokes are kept as points and redrawn, so undo, resize and export all work — and stylus pressure varies the line.

src/components/ui/signature-pad.tsx

About

From the component's own source, where it was written.

A canvas you sign with a finger, a stylus or a mouse.

**Strokes are stored as points, and the canvas is redrawn from them.** The naive version draws straight to the canvas and keeps no model — which means undo is impossible, a resize wipes the drawing, and exporting at a different resolution is not an option. Keeping the points makes all three fall out.

**Pointer events, not mouse or touch.** One set of handlers covers a mouse, a finger and a pen, and pressure from a stylus varies the stroke width the way a real pen does. touch-action: none is essential: without it the first downward stroke scrolls the page instead of drawing.

**It is drawn at device pixel ratio.** A canvas sized in CSS pixels is visibly soft on any modern screen, and a signature is a thing people zoom into. The backing store is scaled up and the context scaled down to match.

A signature captured this way is a picture of a squiggle. It is fine as a record that someone signed; it is **not** a digital signature and proves nothing cryptographically. If you need non-repudiation, sign a hash of the document with a key, and keep this as the human-facing part.

Install

npx astralyx-ui add signature-pad

Usage

import { SignaturePad } from '@/components/ui/signature-pad'

<SignaturePad onSign={(blob) => upload(blob)} />

Composer

Change the props and the source below follows.

Props
tsx
<SignaturePad
  penWidth={2}
  onSign={(blob) => upload(blob)}
/>

Examples

Sign, undo, clear

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

SignaturePad

Extends Omit<ComponentProps<'div'>, 'onChange'>.

PropTypeDefaultDescription
defaultValuestring | number | readonly string[]——
valueStroke[]—Points, not pixels. Drawing straight to the canvas with no model makes undo impossible and loses the drawing on resize.
onChange(strokes: Stroke[]) => void——
onSign(blob: Blob, strokes: Stroke[]) => void—Flattened image on demand, via toBlob.
heightnumber180—
penColorstring'currentColor'—
penWidthnumber2Base stroke width. Stylus pressure scales it.
backgroundstring'transparent'Transparent by default, so it composites onto a document.
outputTypestring'image/png'—
clearLabelstring'Clear'—
undoLabelstring'Undo'—
saveLabelstring'Save'—
actionsbooleantrue—
guidelinebooleantrueThe line people sign above.
placeholderstring'Sign here'—
labelstring'Signature'—
disabledboolean——

Types

Point

A canvas you sign with a finger, a stylus or a mouse.

FieldTypeDescription
xnumber—
ynumber—
pressurenumber—
TypeDefinitionDescription
Stroke
Point[]
—

Behaviour

TopicDetailDescription
pointer eventsone setMouse, finger and pen through one path, with pressure from a stylus varying the width. touch-action: none is essential or the first stroke scrolls the page.
device pixel ratiohandledThe backing store is scaled up and the context scaled down; a canvas sized in CSS pixels is visibly soft, and a signature is a thing people zoom into.
not a digital signaturea pictureFine as a record that someone signed; proves nothing cryptographically. For non-repudiation, sign a hash of the document with a key.