explaingit

steveruizok/perfect-freehand

5,559HTMLAudience · developerComplexity · 2/5LicenseSetup · easy

TLDR

A JavaScript library that turns mouse or stylus coordinates into smooth, natural-looking freehand strokes with variable width, like a real pen, not a rigid line.

Mindmap

mindmap
  root((perfect-freehand))
    What it does
      Converts points to stroke
      Variable width lines
      Natural pen feel
    How it works
      getStroke function
      Returns outline polygon
      You render the shape
    Pressure Sources
      Simulated from speed
      Real stylus pressure
    Options
      Size and thinning
      Smoothing streamline
      Taper easing
    Platforms
      SVG Canvas WebGL
      Dart Rust Python ports
Click or tap to explore — scroll the page freely

Code map

Detail Auto

An interactive map of this repo's files and how they connect — its source is parsed live in your browser. Click Visualize to build it.

filefunction / class

Things people build with this

USE CASE 1

Add natural freehand drawing to a web app by passing pointer coordinates through getStroke and rendering the result on an HTML Canvas.

USE CASE 2

Build a digital whiteboard or annotation tool where strokes look hand-drawn rather than mechanical.

USE CASE 3

Simulate pen pressure for mouse or touch input so drawings look natural even without a drawing tablet.

USE CASE 4

Use the Dart or Rust port to add freehand strokes to a Flutter or native app.

Tech stack

TypeScriptJavaScript

Getting it running

Difficulty · easy Time to first run · 5min

In plain English

Perfect Freehand is a JavaScript library that converts a series of pointer coordinates into a smooth, variable-width stroke shape. If you record the x and y positions as someone draws with a mouse or stylus, the library produces the outline of a natural-looking line that gets thicker or thinner based on the speed or pressure of the movement. The core of the library is a single function called getStroke. You pass it an array of points, one per recorded position, and it returns a new array of points that trace the outline of a polygon representing the stroke. You then take those outline points and draw them yourself, using SVG, HTML Canvas, or whatever rendering method fits your project. Pressure can come from two sources. By default, the library simulates it based on how fast the pointer is moving: slow movement produces a thicker stroke, fast movement produces a thinner one. If you have real pressure data, such as from a drawing tablet or a touch device that reports stylus pressure, you can include that as a third value for each input point and turn simulation off. Several options let you tune the appearance of the stroke. Size sets the maximum diameter. Thinning controls how much pressure affects thickness. Smoothing and streamline affect how closely the stroke follows the raw input points versus averaging them out. You can also add tapering at the start and end of a stroke, and apply custom easing curves to the pressure. The library is written in TypeScript and published to npm. Community-maintained ports exist for Dart, Python, Rust, and other languages.

Copy-paste prompts

Prompt 1
Show me how to use perfect-freehand in a React app with an SVG canvas, capture pointer events, pass them to getStroke, and render the stroke path.
Prompt 2
How do I tune the perfect-freehand options (thinning, smoothing, streamline, taper) to get a brush-like stroke vs a ballpoint pen look?
Prompt 3
Walk me through integrating real stylus pressure data from a tablet into perfect-freehand so the stroke thickness reflects actual pen pressure.
Prompt 4
How do I implement an undo system for a freehand drawing app built on perfect-freehand, what state do I need to track?
Open on GitHub → Explain another repo

← steveruizok on gitmyhub — every repo by this author, as a profile.

Verify against the repo before relying on details.