Skip to content

Pressure Signature Pad

A signature pad with real variable-width ink — pen pressure where it exists, velocity everywhere else, coalesced samples and midpoint quadratics.

Prominimaleditorial
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.

Preview
pressure · velocity fallback
sign here
0 strokes · —

Props

0.7
3.4
0.72
No runtime dependencies
"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
  // ---------------------------------------------------------------
}
Notes

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.

Related

Pairs well with

Matched on shared tags and category — the entries most likely to be used alongside this one.

A text input whose label floats from placeholder position into a caption on focus.

inputformlabel
Featured
NewPro

A numeric input whose label you drag to scrub, with pointer lock and precision modifiers.

inputnumberdrag
Featured
New

OTP Code Input

components

A one-time-code field whose cells survive SMS autofill, paste and Android backspace.

otpinputform