Skip to content

PathGeometry

Read as Markdown

PathGeometry is mutable, inspectable geometry backed by private typed arrays. It supports the Canvas path-building vocabulary, segment editing, 2D affine transforms, and independent native/SVG conversion.

This is the operation map for editable PathGeometry. All functions below are public exports of @pibbl/core; methods belong to a geometry instance.

Goal API Result
Draw contours moveTo, lineTo, quadraticCurveTo, bezierCurveTo, closePath Mutates this geometry; returns void
Add curved and rectangular shapes arc, arcTo, ellipse, geometry.rect(), roundRect Mutates this geometry; returns void
Copy without sharing edits new PathGeometry(source), clone() Independent PathGeometry
Append another path addPath(other, matrix?) Mutates this geometry; optionally transforms the copy
Inspect segments segmentCount, getSegment(index), iteration Count or independent segment values
Replace, insert, or remove segments setSegment, spliceSegments Mutates this geometry
Empty and reuse storage clear() Mutates this geometry
Detect edits revision Mutation counter, not a reactive signal

See construction and editing and the editable geometry example.

Mapping constructors return a reusable PathTransform, not geometry. transformPath(geometry, mapping, { tolerance }) applies one and returns an independent PathGeometry. composeTransforms(...) combines mappings left to right before that final approximation. A mapping’s mapPoint(...) also maps individual points, useful for handles and annotations.

Goal API Working example
Translate, rotate, scale, skew, or reflect in place geometry.transform(matrix) Editable geometry
Apply an affine mapping without changing the original affineTransform with transformPath Transform examples
Fit into four corners, using bilinear or perspective mapping quadTransform Interactive quad warp
Stretch between two or more guide paths envelopeTransform Multi-guide envelope
Warp through a grid of curved boundaries meshTransform Mesh reference
Bend around a circular arc arcBendTransform Arc and path bending
Bend along a smooth guide path pathBendTransform Arc and path bending
Combine mappings and apply them once composeTransforms, transformPath Transform examples

See composable path transforms for source rectangles, guide correspondence, mesh boundaries, tolerance, and domain limits. See path bending for baseline, alignment, fitting, and overflow. Affine mappings preserve curves; nonlinear mappings produce line segments.

Goal API Result
Adaptively approximate curves with lines flattenPath Independent line-only geometry
Flatten with uniform parameter steps using Wang’s bound flattenPathWang Independent line-only geometry; predictable segment allocation
Reduce polyline vertices simplifyPath Independent simplified geometry; curves must be flattened first
Simplify with a radial-distance prepass simplifyPathRadial Independent simplified geometry; the two stages share the tolerance budget
Split segments into more editable pieces subdividePath Independent geometry; preserves curves, not equal physical spacing
Draw with native Canvas APIs toPath2D Fresh native Path2D snapshot
Export SVG path data toSvgPathData SVG path-data string

See geometry utilities and the utility comparison example.

Geometry edits do not schedule rendering: notify a consumed signal after editing. Changing Path or Group presentation transforms does not rewrite the source geometry. Pixel filters likewise do not edit its segments.

Native Path2D is opaque: Pibbl cannot turn it back into editable geometry. The create*Path factories return native paths, not PathGeometry. Start with the builder when later editing or warping is needed. Text outlines from @pibbl/text can also provide editable geometry; see text geometry. Boolean union/intersection/subtraction, equal-distance resampling, and curve fitting are not provided by this surface.

Explore the multi-guide text envelope example for a larger composition using the same mapping APIs.

import { PathGeometry, toPath2D, toSvgPathData } from "@pibbl/core";
const geometry = new PathGeometry();
geometry.moveTo(10, 10);
geometry.bezierCurveTo(10, 40, 40, 40, 40, 10);
geometry.closePath();
const native = toPath2D(geometry);
const svgData = toSvgPathData(geometry);

The mutable builder methods are moveTo, lineTo, quadraticCurveTo, bezierCurveTo, closePath, arc, arcTo, ellipse, geometry.rect(), and roundRect. They use the corresponding Canvas argument order and return void. Nonfinite builder inputs are ignored; invalid radii follow Canvas exception categories.

new PathGeometry(source?) and clone() copy independently. addPath(other, matrix?) copies another geometry, optionally transformed, including self-addition. Native Path2D and SVG-string import are not supported because native paths do not expose their segments for reading.

revision advances on mutation. Save it separately when checking whether an instance changed: reading two references to the same object cannot recover a previous revision. Mutation does not schedule a frame or invalidate a retained Layer; update a separate signal consumed by your component after editing.

segmentCount counts canonical segments. getSegment(index) returns an independent PathSegment. setSegment(index, segment) replaces a segment; spliceSegments(start, deleteCount, segments?) inserts/removes/replaces segments. Indices are zero-based, and splice requires an in-range nonnegative deletion count. A nonempty path must start with Move. Failed edits leave it unchanged.

Segment types use these fields:

Type Fields
move, line x, y
quadratic cpx, cpy, x, y
cubic cp1x, cp1y, cp2x, cp2y, x, y
arc cx, cy, ux, uy, vx, vy, startAngle, sweep
close none

An arc is center + u*cos(t) + v*sin(t); its start and signed sweep are in radians within one revolution. This preserves ellipses through skew and reflection. Rectangle/rounded-rectangle and arcTo calls resolve to canonical segments, not a retained history of builder calls. Editing their points does not rerun those original calls. Iteration yields independent segment values; mutation during iteration throws. clear() removes geometry but retains buffer capacity for reuse. Segment lookup scans the packed buffer; sequential iteration is linear overall.

transform(matrix) mutates coordinates using a finite 2D DOMMatrix-compatible matrix. Matrix dictionaries accept platform aliases/defaults. 3D/perspective matrices and overflowing coordinates are rejected before modifying geometry.

toPath2D(geometry) always returns a fresh caller-owned snapshot. toSvgPathData(geometry) returns absolute SVG data without decimal rounding. Neither function caches publicly. Ellipses remain analytic; singular transforms export traversal-preserving lines. Turning-point stroke joins can differ from a browser’s degenerate native ellipse representation.

Path, Clip, explicit event-target and cursor/event-hook inputs accept geometry alongside native Path2D. Pibbl privately caches by identity and saved revision; paint, clipping and interaction use the same native snapshot. Already-rendered hit regions stay unchanged until their consumer renders again. Browser canvas methods still require toPath2D output. Particle path assets snapshot geometry when defining an effect, consistent with immutable effect ownership.

import { flattenPath, simplifyPath, subdividePath } from "@pibbl/core";
const lines = flattenPath(geometry, { tolerance: 0.25 });
const reduced = simplifyPath(lines, { tolerance: 0.5 });
const moreHandles = subdividePath(geometry, { divisions: 3 });

All three return independent geometry and preserve separate contours/closure. Their option types are FlattenPathOptions, SimplifyPathOptions, and SubdividePathOptions. Each accepts optional maxSegments (default 1,000,000, including Move/Close). Exceeding it throws without changing the input.

  • Flatten adaptively replaces curves with lines. Required positive tolerance measures geometric error in input coordinate units. Transform a clone first if you need output/tolerance in screen coordinates. Unachievable numerical precision or output limits cause an explicit error, not a partial result.
  • Simplify removes polyline vertices using required positive tolerance. Curved inputs require explicit flattening. Open endpoints and closure are preserved; nondegenerate closed rings retain at least three distinct vertices. Topology, hole preservation, and freedom from new intersections are not promised. Its error is relative to the polyline input, so earlier flattening error adds.
  • Subdivide splits each segment into a positive integer divisions, preserving curves up to floating-point precision. Equal parameter intervals do not mean equal physical lengths. Closing edges are subdivided and remain closed.

Equal-distance resampling and curve fitting are separate future operations. Try the editable path example.

Use composable path transforms to apply affine, quad, envelope, mesh, and bend mappings through transformPath. PathGeometry.transform remains the low-level in-place affine operation.

Flattens curves with Wang’s uniform-parameter bound.

This trades adaptive placement for a known output count and independent point evaluation. It is most useful when predictable allocation or parallel output generation matters more than minimizing the number of line segments.

flattenPathWang: (path: PathGeometry, options: Readonly<FlattenPathOptions>) => PathGeometry

Related API: flattenPathWang, PathGeometry, FlattenPathOptions.

  • path — Source geometry; it is not modified. See PathGeometry.

  • options — Maximum approximation error and flattening work limits. See FlattenPathOptions .

Independent geometry with curves replaced by line segments. See PathGeometry.

PathGeometry

FlattenPathOptions

View source — packages/core/src/lib/geometry/path-wang.ts:24

Simplifies line-only paths with a radial-distance prepass followed by the default Douglas–Peucker implementation. Each stage receives half of the requested error budget, so their errors compose within tolerance.

simplifyPathRadial: (path: PathGeometry, options: Readonly<SimplifyPathOptions>) => PathGeometry

Related API: simplifyPathRadial, PathGeometry, SimplifyPathOptions.

Independent geometry with redundant line vertices removed. See PathGeometry.

PathGeometry

SimplifyPathOptions

View source — packages/core/src/lib/geometry/path-radial.ts:18

Mutable packed geometry. Mutations do not schedule Pibbl rendering.

class PathGeometry implements Iterable<PathSegment>

Related API: PathGeometry, PathSegment.

PathSegment

View source — packages/core/src/lib/geometry/path-geometry.ts:143

revision
readonly revision: number

Monotonic mutation revision; changing geometry does not itself request a Pibbl frame. See PathGeometry.

The mutation revision used to invalidate cached representations.

View source — packages/core/src/lib/geometry/path-geometry.ts:167

segmentCount
readonly segmentCount: number

Number of stored path segments, including move and close commands. See PathGeometry.

The number of stored path segments.

View source — packages/core/src/lib/geometry/path-geometry.ts:172

clone
clone: () => PathGeometry

Related API: PathGeometry.

Returns an independent copy with its own mutation revision. See PathGeometry.

An independent copy of this path’s segments. See PathGeometry.

View source — packages/core/src/lib/geometry/path-geometry.ts:178

clear
clear: () => void

Removes all segments and resets the current point. See PathGeometry.

View source — packages/core/src/lib/geometry/path-geometry.ts:181

moveTo
moveTo: (x: number, y: number) => void

Begins a subpath at the supplied coordinates. See PathGeometry.

  • x — Horizontal coordinate of the new subpath’s starting point.

  • y — Vertical coordinate of the new subpath’s starting point.

View source — packages/core/src/lib/geometry/path-geometry.ts:195

lineTo
lineTo: (x: number, y: number) => void

Appends a straight segment to the supplied coordinates. See PathGeometry.

  • x — Horizontal coordinate of the line endpoint.

  • y — Vertical coordinate of the line endpoint.

View source — packages/core/src/lib/geometry/path-geometry.ts:201

quadraticCurveTo
quadraticCurveTo: (cpx: number, cpy: number, x: number, y: number) => void

Appends a quadratic curve using one control point and an endpoint. See PathGeometry.

  • cpx — Horizontal coordinate of the quadratic control point.

  • cpy — Vertical coordinate of the quadratic control point.

  • x — Horizontal coordinate of the curve endpoint.

  • y — Vertical coordinate of the curve endpoint.

View source — packages/core/src/lib/geometry/path-geometry.ts:209

bezierCurveTo
bezierCurveTo: (cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number) => void

Appends a cubic curve using two control points and an endpoint. See PathGeometry.

  • cp1x — Horizontal coordinate of the first control point.

  • cp1y — Vertical coordinate of the first control point.

  • cp2x — Horizontal coordinate of the second control point.

  • cp2y — Vertical coordinate of the second control point.

  • x — Horizontal coordinate of the curve endpoint.

  • y — Vertical coordinate of the curve endpoint.

View source — packages/core/src/lib/geometry/path-geometry.ts:221

closePath
closePath: () => void

Closes the current subpath; an already closed or empty path is unchanged. See PathGeometry.

View source — packages/core/src/lib/geometry/path-geometry.ts:228

arc
arc: (x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean) => void

Appends a circular arc using Canvas-compatible angles in radians. See PathGeometry.

  • x — Horizontal coordinate of the circle center.

  • y — Vertical coordinate of the circle center.

  • radius — Circle radius in path units.

  • startAngle — Starting angle in radians.

  • endAngle — Ending angle in radians.

  • counterclockwise — Whether the arc runs counterclockwise; defaults to false.

View source — packages/core/src/lib/geometry/path-geometry.ts:243

ellipse
ellipse: (x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean) => void

Appends an elliptical arc; rotation and arc angles are in radians. See PathGeometry.

  • x — Horizontal coordinate of the ellipse center.

  • y — Vertical coordinate of the ellipse center.

  • radiusX — Horizontal radius in path units.

  • radiusY — Vertical radius in path units.

  • rotation — Ellipse rotation in radians.

  • startAngle — Starting angle in radians.

  • endAngle — Ending angle in radians.

  • counterclockwise — Whether the arc runs counterclockwise; defaults to false.

View source — packages/core/src/lib/geometry/path-geometry.ts:258

arcTo
arcTo: (x1: number, y1: number, x2: number, y2: number, radius: number) => void

Appends a circular arc tangent to two lines using Canvas-compatible geometry. See PathGeometry.

  • x1 — Horizontal coordinate of the first tangent intersection.

  • y1 — Vertical coordinate of the first tangent intersection.

  • x2 — Horizontal coordinate of the second tangent endpoint.

  • y2 — Vertical coordinate of the second tangent endpoint.

  • radius — Arc radius in path units.

View source — packages/core/src/lib/geometry/path-geometry.ts:291

rect
rect: (x: number, y: number, width: number, height: number) => void

Appends a closed rectangle subpath. See PathGeometry.

  • x — Horizontal coordinate of the rectangle origin.

  • y — Vertical coordinate of the rectangle origin.

  • width — Signed horizontal extent in path units.

  • height — Signed vertical extent in path units.

View source — packages/core/src/lib/geometry/path-geometry.ts:322

roundRect
roundRect: (x: number, y: number, width: number, height: number, radii?: number | DOMPointInit | (number | DOMPointInit)[]) => void

Appends a closed rectangle with Canvas-compatible corner radii. See PathGeometry.

  • x — Horizontal coordinate of the rectangle origin.

  • y — Vertical coordinate of the rectangle origin.

  • width — Signed horizontal extent in path units.

  • height — Signed vertical extent in path units.

  • radii — Circular or elliptical corner radii, using Canvas roundRect ordering; defaults to zero.

View source — packages/core/src/lib/geometry/path-geometry.ts:345

addPath
addPath: (other: PathGeometry, matrix?: DOMMatrix2DInit) => void

Related API: PathGeometry.

Appends a copy of another path, optionally transformed by a 2D matrix. See PathGeometry.

  • other — Geometry whose segments are appended. See PathGeometry.

  • matrix — Optional affine transform applied to the appended segments; defaults to identity.

View source — packages/core/src/lib/geometry/path-geometry.ts:388

spliceSegments
spliceSegments: (start: number, deleteCount: number, segments?: readonly PathSegment[]) => void

Related API: PathSegment.

Replaces a segment range with validated independent segment values. See PathGeometry.

  • start — Index at which to begin replacing segments.

  • deleteCount — Number of segments to remove.

  • segments — Replacement segments; defaults to no inserted segments. See PathSegment .

View source — packages/core/src/lib/geometry/path-geometry.ts:419

getSegment
getSegment: (index: number) => PathSegment

Related API: PathSegment.

Returns an independent segment value at the specified index. See PathSegment.

  • index — Zero-based segment index.

The segment at the requested index. See PathSegment.

View source — packages/core/src/lib/geometry/path-geometry.ts:480

setSegment
setSegment: (index: number, segment: PathSegment) => void

Related API: PathSegment.

Replaces one stored segment with a validated independent value. See PathGeometry.

  • index — Zero-based index of the segment to replace.

  • segment — Replacement segment data. See PathSegment.

View source — packages/core/src/lib/geometry/path-geometry.ts:489

transform
transform: (matrix: DOMMatrix2DInit) => void

Applies a finite 2D affine matrix. Old native conversions remain unchanged.

  • matrix — Affine matrix applied to all segments in this path.

View source — packages/core/src/lib/geometry/path-geometry.ts:512

A canonical, independently editable path segment.

Full type declaration
type PathSegment = | {
/** Selects `"move"`, `"line"` for type. See {@link PathSegment}. */
type: 'move' | 'line';
/**
* Horizontal coordinate or displacement in the containing coordinate system. See
* {@link PathSegment}.
*/
x: number;
/**
* Vertical coordinate or displacement in the containing coordinate system. See
* {@link PathSegment}.
*/
y: number;
}
| {
/** The literal "quadratic" identifying this variant. See {@link PathSegment}. */
type: 'quadratic';
/** Horizontal coordinate of the quadratic control point. See {@link PathSegment}. */
cpx: number;
/** Vertical coordinate of the quadratic control point. See {@link PathSegment}. */
cpy: number;
/**
* Horizontal coordinate or displacement in the containing coordinate system. See
* {@link PathSegment}.
*/
x: number;
/**
* Vertical coordinate or displacement in the containing coordinate system. See
* {@link PathSegment}.
*/
y: number;
}
| {
/** The literal "cubic" identifying this variant. See {@link PathSegment}. */
type: 'cubic';
/** Horizontal coordinate of the first cubic control point. See {@link PathSegment}. */
cp1x: number;
/** Vertical coordinate of the first cubic control point. See {@link PathSegment}. */
cp1y: number;
/** Horizontal coordinate of the second cubic control point. See {@link PathSegment}. */
cp2x: number;
/** Vertical coordinate of the second cubic control point. See {@link PathSegment}. */
cp2y: number;
/**
* Horizontal coordinate or displacement in the containing coordinate system. See
* {@link PathSegment}.
*/
x: number;
/**
* Vertical coordinate or displacement in the containing coordinate system. See
* {@link PathSegment}.
*/
y: number;
}
| ArcSegment
| {
/** The literal "close" identifying this variant. See {@link PathSegment}. */
type: 'close';
}

Related API: PathSegment, displacement.

PathGeometry

View source — packages/core/src/lib/geometry/path-geometry.ts:7

type
type: "arc" | "close" | "cubic" | "line" | "move" | "quadratic"

Selects "move", "line" for type. See PathSegment. The literal “quadratic” identifying this variant. See PathSegment. The literal “cubic” identifying this variant. See PathSegment. The literal “close” identifying this variant. See PathSegment.

View source — packages/core/src/lib/geometry/path-arc.ts:3

Creates a fresh caller-owned native snapshot; never returns a shared cache.

toPath2D: (geometry: PathGeometry) => Path2D

Related API: toPath2D, PathGeometry.

A native Canvas path representing the geometry.

PathGeometry

View source — packages/core/src/lib/geometry/path-conversion.ts:12

Serializes independent absolute SVG path data without implicit rounding.

toSvgPathData: (geometry: PathGeometry) => string

Related API: toSvgPathData, PathGeometry.

  • geometry — Pibbl geometry to serialize. See PathGeometry.

SVG path data representing the geometry.

PathGeometry

View source — packages/core/src/lib/geometry/path-conversion.ts:47

Returns independent geometry with curves approximated by line segments within the requested tolerance.

flattenPath: (path: PathGeometry, options: Readonly<FlattenPathOptions>) => PathGeometry

Related API: flattenPath, PathGeometry, FlattenPathOptions.

  • path — Source geometry; it is not modified. See PathGeometry.

  • options — Maximum approximation error and flattening work limits. See FlattenPathOptions .

Independent geometry with curves replaced by line segments. See PathGeometry.

PathGeometry

FlattenPathOptions

View source — packages/core/src/lib/geometry/path-utilities.ts:62

Returns independent polyline geometry with redundant points removed within the requested tolerance.

simplifyPath: (path: PathGeometry, options: Readonly<SimplifyPathOptions>) => PathGeometry

Related API: simplifyPath, PathGeometry, SimplifyPathOptions.

Independent geometry with redundant line vertices removed. See PathGeometry.

PathGeometry

SimplifyPathOptions

View source — packages/core/src/lib/geometry/path-utilities.ts:164

Returns independent geometry with each drawable segment split into the requested number of pieces.

subdividePath: (path: PathGeometry, options: Readonly<SubdividePathOptions>) => PathGeometry

Related API: subdividePath, PathGeometry, SubdividePathOptions.

Independent geometry with segments split according to the requested limits. See PathGeometry .

PathGeometry

SubdividePathOptions

View source — packages/core/src/lib/geometry/path-utilities.ts:108

Positive approximation tolerance and output-segment budget for curve flattening.

interface FlattenPathOptions

Related API: FlattenPathOptions.

flattenPath

flattenPathWang

View source — packages/core/src/lib/geometry/path-utilities.ts:14

tolerance
readonly tolerance: number

Positive maximum geometric approximation error. See FlattenPathOptions.

View source — packages/core/src/lib/geometry/path-utilities.ts:16

maxSegments (optional)
readonly maxSegments?: number | undefined

Upper bound on the number of output path segments. See FlattenPathOptions.

View source — packages/core/src/lib/geometry/path-utilities.ts:18

Positive tolerance and output-segment budget for polyline simplification.

interface SimplifyPathOptions

Related API: SimplifyPathOptions.

simplifyPath

simplifyPathRadial

View source — packages/core/src/lib/geometry/path-utilities.ts:27

tolerance
readonly tolerance: number

Positive maximum geometric approximation error. See SimplifyPathOptions.

View source — packages/core/src/lib/geometry/path-utilities.ts:29

maxSegments (optional)
readonly maxSegments?: number | undefined

Upper bound on the number of output path segments. See SimplifyPathOptions.

View source — packages/core/src/lib/geometry/path-utilities.ts:31

Subdivision count and output-segment budget for splitting path segments.

interface SubdividePathOptions

Related API: SubdividePathOptions.

subdividePath

View source — packages/core/src/lib/geometry/path-utilities.ts:39

divisions
readonly divisions: number

Number of pieces produced from each drawable path segment. See SubdividePathOptions.

View source — packages/core/src/lib/geometry/path-utilities.ts:43

maxSegments (optional)
readonly maxSegments?: number | undefined

Upper bound on the number of output path segments. See SubdividePathOptions.

View source — packages/core/src/lib/geometry/path-utilities.ts:45

Read the Drawing, layout, and effects companion for ownership, adaptation, failure modes, and verification. Agent start provides the version-selection workflow.

Documentation built with @pibbl/core 0.0.2, revision 380919b. ALPHA — NOT FOR PRODUCTION USE.