Signature Pad
more-shadcn-noair/signature-padFreeComponent
A pressure and velocity aware drawing canvas that exports to PNG or SVG.
Live preview
live · rendered by the registry
Rendered by more-shadcn-noair on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://more-shadcn.noair.fun/r/signature-pad.jsonSource
1<script lang="ts" module>2 export type SignaturePoint = { x: number; y: number; w: number };3 export type SignatureStroke = { color: string; points: SignaturePoint[] };45 export type SignatureSegment = {6 x0: number;7 y0: number;8 cx: number;9 cy: number;10 x1: number;11 y1: number;12 w: number;13 };1415 const mid = (a: SignaturePoint, b: SignaturePoint) => ({16 x: (a.x + b.x) / 2,17 y: (a.y + b.y) / 218 });1920 /**21 * Turns a stroke into quadratic segments (control point = the sampled point,22 * endpoints = the midpoints of its neighbours). Shared by the canvas renderer23 * and the SVG exporter so both produce the exact same curve.24 */25 export function strokeToSegments(stroke: SignatureStroke): SignatureSegment[] {26 const p = stroke.points;27 if (p.length < 2) return [];2829 const segments: SignatureSegment[] = [];30 let start = { x: p[0].x, y: p[0].y };3132 for (let i = 1; i < p.length; i++) {33 const end = i === p.length - 1 ? { x: p[i].x, y: p[i].y } : mid(p[i], p[i + 1]);34 segments.push({35 x0: start.x,36 y0: start.y,37 cx: p[i].x,38 cy: p[i].y,39 x1: end.x,40 y1: end.y,41 w: p[i].w42 });43 start = end;44 }4546 return segments;47 }48</script>4950<script lang="ts">51 import { cn } from '$UTILS$';52 import { onMount } from 'svelte';5354 let {55 strokes = $bindable([]),56 penColor = 'currentColor',57 backgroundColor = 'transparent',58 minWidth = 0.7,59 maxWidth = 2.6,60 velocityWeight = 0.7,61 disabled = false,62 class: className,63 onbegin,64 onend,65 onchange,66 ...rest67 }: {68 strokes?: SignatureStroke[];69 penColor?: string;70 backgroundColor?: string;71 minWidth?: number;72 maxWidth?: number;73 velocityWeight?: number;74 disabled?: boolean;75 class?: string;76 onbegin?: () => void;77 onend?: (stroke: SignatureStroke) => void;78 onchange?: (strokes: SignatureStroke[]) => void;79 [key: string]: unknown;80 } = $props();8182 let canvas = $state<HTMLCanvasElement | null>(null);83 let ctx: CanvasRenderingContext2D | null = null;84 let size = $state({ width: 0, height: 0 });8586 let drawing = false;87 let current: SignatureStroke | null = null;88 let lastWidth = maxWidth;89 let lastTime = 0;9091 export const isEmpty = () => strokes.length === 0;9293 const colorCache = new Map<string, string>();9495 /**96 * Normalises any CSS color to `#rrggbb` / `rgba()`. Themes resolve to modern97 * color spaces such as `oklch()`, which older SVG viewers do not understand.98 */99// … truncated
More from more-shadcn-noair
All 43 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Audioaudio | more-shadcn-noair | Components | Free | no deps | |
| Audio Waveaudio-wave | more-shadcn-noair | Components | Free | no deps | |
| Autocompleteautocomplete | more-shadcn-noair | Components | Free | no deps | |
| Bannerbanner | more-shadcn-noair | Components | Free | no deps | |
| Big Calendarbig-calendar | more-shadcn-noair | Components | Free | no deps | |
| Bottom Navigationbottom-nav | more-shadcn-noair | Components | Free | no deps | |
| Canvascanvas | more-shadcn-noair | Components | Free | no deps | |
| Chipchip | more-shadcn-noair | Components | Free | no deps |
