svelte-signature-pad Svelte Themes

Svelte Signature Pad

Capture smoothed signatures as SVG paths in Svelte

svelte-signature-pad

Svelte Action to capture smoothed signatures as SVG paths using the excellent perfect-freehand library.

Instructions

Install using you package manager of choice:

pnpm i svelte-signature-pad

Import action into page and pass and object with ondraw and oncomplete method properties.

Each will receive a path which can be rendered as SVG in your component. ondraw fires while the user is drawing and would be the current stroke. oncomplete fires when they have finished the line (which could transition to a different color).

Example

<script lang="ts">
  import { signature } from 'svelte-signature-pad'

  let layers: { path: string; width: number; height: number }[] = []

  let width: number
  let height: number
  let preview: string

  const ondraw = (path: string) => (preview = path)
  const oncomplete = (path: string) => {
    preview = ''
    layers = [...layers, { width, height, path }]
  }

  const clear = () => {
    layers = []
  }
</script>

<div class="relative w-full h-[360px] bg-gray-100 border border-dashed border-gray-300">
  <div class="absolute left-4 right-4 bottom-24 border-t border-dotted border-gray-300" />
  <div
    class="w-full h-full"
    use:signature={{ ondraw, oncomplete }}
    bind:clientWidth={width}
    bind:clientHeight={height}
    on:touchmove|preventDefault={() => false}
  >
    {#each layers as layer}
      <svg class="absolute w-full h-full fill-black pointer-events-none" viewBox="0 0 {layer.width} {layer.height}">
        <path d={layer.path} />
      </svg>
    {/each}

    {#if preview}
      <svg class="absolute w-full h-full fill-gray-900 pointer-events-none" viewBox="0 0 {width} {height}">
        <path d={preview} />
      </svg>
    {/if}
  </div>
  <button class="absolute top-2 right-2 px-4 py-2 text-sm text-gray-500 bg-white border border-gray-200" on:click={clear}>Clear</button>
</div>

<p class="mt-2 text-sm">Please sign on the dotted line to indicate that you agree to all the legal terms we all know you didn't read. Thank you!</p>

<div class="relative mt-4">
  {#each layers as layer}
    <svg class="absolute fill-black" viewBox="0 0 {layer.width * 2} {layer.height * 2}">
      <path d={layer.path} />
    </svg>
  {/each}
</div>

Top categories

Loading Svelte Themes