Pressure Signature Pad
A signature pad with real variable-width ink — pen pressure where it exists, velocity everywhere else, coalesced samples and midpoint quadratics.
- Category
- Components
- Added
- 2026-09-21
- Deps
- none
- Updated
- 2026-09-21
This is a viberdy Pro component
The live preview, the props panel and the write-up are open to everyone. The full source, the AI prompt and CLI install are part of Pro.
Props
"use client";
import { useCallback, useEffect, useRef, useState } from "react";
type Pt = { x: number; y: number; w: number };
export function PressureSignaturePad({
minWidth = 0.7,
maxWidth = 3.4,
ink = "#f4f6f8",
velocityWeight = 0.72,
label = "Signature",
onChange,
}: {
minWidth?: number;
maxWidth?: number;
ink?: string;
/** How much of the fallback width comes from speed rather than a flat mid value. */
// ---------------------------------------------------------------
// Full source available with a viberdy Pro subscription.
// https://viberdy.dev/pricing
// ---------------------------------------------------------------
}About this component
Nearly every signature pad on the web draws a constant-width line, and the reason is a single API detail: PointerEvent.pressure reports exactly one half while a mouse button is held and zero otherwise. Binding the line width to it therefore produces a completely flat stroke on the device almost everyone builds and tests on, and only comes alive on a pen, which is the hardware nobody checks. The fix is to treat pressure as available rather than assumed — use it when the pointer really reports it, and otherwise derive width from velocity, because a fast stroke of a real nib runs thin and a slow one pools. That single substitution is what makes a mouse signature look handwritten. Three supporting details finish it. The pointer must be read through getCoalescedEvents, since a pen samples far faster than the display refreshes and the browser buffers everything but one sample per frame — miss them and a quick stroke is visibly polygonal. The smoothing is midpoint quadratics, curving between the midpoints of consecutive samples with the sample as the control point, which is continuous in the first derivative without any tangent bookkeeping. And the samples, not the bitmap, are the document: assigning to canvas.width clears it even when the value is unchanged, so a pad that stores only pixels loses the signature on any resize — on a phone, the moment the keyboard opens.
Curator’s note
A mouse reports pressure 0.5 exactly, always. Bind lineWidth to it and the stroke is flat on every machine you test on and alive only on hardware you do not have.
Pairs well with
Matched on shared tags and category — the entries most likely to be used alongside this one.
Floating Label Input
componentsA text input whose label floats from placeholder position into a caption on focus.
Scrub Number Field
componentsA numeric input whose label you drag to scrub, with pointer lock and precision modifiers.
OTP Code Input
componentsA one-time-code field whose cells survive SMS autofill, paste and Android backspace.