Use Clipper's boolean and offsetting operations in Paper.js
Paper.js is a vector graphics scripting library.
js-angusj-clipper is a library with polygon offsetting and boolean operations. For optimal performance, it uses the original C++ version of Clipper via WebAssembly.
yarn add paper-clipper
or
npm install --save paper-clipper
Include methods from paper-clipper
import { clipperLib, clipperOffset, clipperUnite, paperClipperSimplify } from 'paper-clipper';
In an async
function, create an instance of the Clipper library (usually only do this once in your app):
const clipper = await clipperLib.loadNativeClipperLibInstanceAsync(
clipperLib.NativeClipperLibRequestedFormat.WasmWithAsmJsFallback,
);
As Clipper supports polygons only (ie. paths without bezier curves), paper-clipper's clipperOffset
method will Path#flatten
the Paper.js Path, offset it, then apply simplification to the resulting path.
Path simplification and smoothing is performed by the built-in paperClipperSimplify
function which uses Paper's Path#simplify
method, modified to better conserve edges of the input path.
const path = new paper.Path(..)
// Set strokeJoin on path for styling of expanded path edges
path.strokeJoin = 'round' // or 'miter' or 'bevel'
// Set strokeCap for styling of the ends of open paths
path.strokeCap = 'round' // or 'square' or 'butt'
// Offset a Paper.js Path
// By 10 pixels
const offsetPaths = await clipperOffset(clipper)(path, 10)
// With simplification disabled
// This returns an offset path with many segments, all without handles
const offsetPaths = await clipperOffset(clipper)(path, { offset: 10, simplify: false })
// With a custom simplify method applied to the offset path
// mySimplifyFn = (path) => output path
const offsetPaths = await clipperOffset(clipper)(path, { offset: 10, simplify: mySimplifyFn })
// With tolerance applied to the built-in paperClipperSimplify method. (default: 0.25)
const offsetPaths = await clipperOffset(clipper)(path, { offset: 10, tolerance: 2 })
The clipperUnite
method accepts a Paper.js Path but will discard handles, treating the path as a polygon. It offers better performance than Paper.js Path#unite
when this boolean operation is needed on Paths with no segment handles.
// Unite two Paper.js Paths
const paths = [new paper.Path(..), new paper.Path(..)]
const unitedPaths = await clipperUnite(clipper)(paperPaths)
Refer to js-angusj-clipper and its API reference for documentation.
- Clipper's other boolean operations (Intersection, Difference, Xor) could be included in the development of this library.