Path Effects
Generators that derive new paths from a base path. Each takes an array of control points and returns one or more new point arrays, ready to hand to a StrokeDef. They know nothing about renderers: the derived paths are ordinary paths, drawn by whatever renderer the caller picks.
public/lib/pathEffects.js
All randomness is seeded, so the same seed returns the same paths.
spiralPath
The tip circles with sin and cos while its center moves along the base path, returning one continuous coil. Takes turns, radius, and count (output points, since a spiral needs far more than its base).
entangledPaths
Copies of the path, each offset by its own seeded low-frequency waves. Endpoints pull back toward the base so the bundle reads as one gesture. Takes count, amplitude, waves, and seed.
scatteredPaths
Short strokes that copy small segments of the base and move sideways by a seeded offset. Takes count, length, offset, and seed.
mirroredPath
The path mirrored across the vertical line through x, the horizontal line through y, or both (a point reflection). With neither given it mirrors across the vertical line through the path’s own start. Pressures ride along, so a pen gesture mirrors with its dynamics.
rotatedPaths
count - 1 copies of the path rotated evenly around center, the path’s own start when omitted, so the path and its copies together divide the turn into count. Pressures ride along.
convexHull
The convex hull of a set of points, counterclockwise, by Andrew’s monotone chain. The hull is the smallest convex region containing every point.
offsetOutline
The outline of everything within radius of the polyline: an offset of the path itself, so it follows the gesture into its concavities instead of spanning them. The distance field to the polyline is stamped onto a grid and the radius contour is extracted with marching squares. Returns the longest closed contour, counterclockwise. Takes radius and cell.
blobOutline
The full blob pipeline: a gesture in, a smooth closed contour out. The path is resampled to knots, closed into a smooth loop, offset by radius, and the contour smoothed again. Closing first keeps the result a mass rather than a tube, and the offset field does not care when the closure crosses the stroke. Takes span and radius.
Shapes from endpoints
Contours placed and sized by a gesture’s start and end alone; the path between them is ignored. Every generator returns a closed counterclockwise contour with its corners kept exactly, or null when the endpoints are too close to span a shape.
circleFromEnds(a, b) is a circle from center a to edge b. ovalFromEnds(a, b) is the axis-aligned ellipse inscribed in the box with diagonal a-b, and rectFromEnds(a, b) is that box itself. diamondFromEnds(a, b) is a rhombus with long diagonal a-b; ratio sets the short diagonal against it. triangleFromEnds(a, b, { angles, seed }) stands a triangle on the edge a-b with the given interior angles; which corner takes which angle, and which side of the edge the apex lands on, derive from the seed.