Skip to content

cool-ts/perfect-freehand

 
 

Repository files navigation

Perfect Freehand

Perfect freehand is a library for creating freehand paths by @steveruizok.

Screenshot

🔗 Demo

Installation

npm install perfect-freehand

or

yarn add perfect-freehand

Usage

The library export one default function, getPath, that accepts an array of points and an (optional) options object and returns SVG path data for a stroke.

The array of points may be either an array of number pairs representing the point's x, y, and (optionally) pressure...

import getPath from 'perfect-freehand'

const path = getPath([
  [0, 0],
  [10, 5],
  [20, 8],
])

const path = getPath([
  [0, 0, 0],
  [10, 5, 0.5],
  [20, 8, 0.3],
])

...or an array of objects with x, y, and (optionally) pressure properties.

getPath([
  { x: 0, y: 0 },
  { x: 10, y: 5 },
  { x: 20, y: 8 },
])

getPath([
  { x: 0, y: 0, pressure: 0, },
  { x: 10, y: 5, pressure: 0.5 },
  { x: 20, y: 8, pressure: 0.3 },
])

Options

The options object is optional, as are its properties.

Property Type Default Description
type string 'mouse' A pointerType.
minSize number 2.5 The thinnest size of the stroke.
maxSize number 8 The thickest size of the stroke.
simulatePressure boolean true Whether to interpret velocity as pressure for mouse and touch inputs.
streamline number .5 How much to streamline the stroke.
smooth number .5 How much to soften the stroke's edges.
getPath(myPoints, {
  type: 'pen',
  minSize: 2.5,
  maxSize: 8,
  simulatePressure: true,
  streamline: 0.5,
  smooth: 0.5,
})

Example

import * as React from 'react'
import getPath from 'perfect-freehand'

export default function Example() {
  const [currentType, setCurrentType] = React.useState('mouse')
  const [currentMark, setCurrentMark] = React.useState([])

  function handlePointerDown(e) {
    setCurrentType(e.pointerType)
    setCurrentMark([[e.pageX, e.pageY, e.pressure]])
  }

  function handlePointerMove(e) {
    if (e.buttons === 1 && e.pointerType === currentType) {
      setCurrentMark([...currentMark, [e.pageX, e.pageY, e.pressure]])
    }
  }

  return (
    <svg
      width={800}
      height={600}
      onPointerDown={handlePointerDown}
      onPointerMove={handlePointerMove}
    >
      <path d={getPath(currentMark, { type: currentType })} />
    </svg>
  )
}

Edit perfect-freehand-example

About

Draw perfect freehand lines.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 94.8%
  • CSS 4.6%
  • JavaScript 0.6%