@pixerate/editor 0.34.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -109,8 +109,12 @@ interface VectorAnchorRef {
109
109
  interface VectorHandleRef extends VectorAnchorRef {
110
110
  handle: 'in' | 'out';
111
111
  }
112
- /** Canvas tools. `direct` edits anchors and handles; the shape tools drag out a new shape. */
113
- type VectorTool = 'select' | 'direct' | 'pen' | 'pencil' | 'rect' | 'ellipse' | 'polygon' | 'star' | 'line';
112
+ /**
113
+ * Canvas tools. `direct` edits anchors, handles and segments; the shape tools drag out a new
114
+ * shape; `scissors` cuts a path at a point, `knife` cuts filled shapes along a freehand stroke
115
+ * and `eraser` rubs out the area under one.
116
+ */
117
+ type VectorTool = 'select' | 'direct' | 'pen' | 'pencil' | 'rect' | 'ellipse' | 'polygon' | 'star' | 'line' | 'scissors' | 'knife' | 'eraser';
114
118
  declare const VECTOR_TOOLS: readonly VectorTool[];
115
119
  /** Keyboard modifiers held during a pointer event. */
116
120
  interface VectorModifiers {
@@ -144,6 +148,14 @@ type VectorAlign = 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom';
144
148
  type VectorDistribute = 'horizontal' | 'vertical';
145
149
  type VectorBooleanOperation = 'union' | 'subtract' | 'intersect' | 'exclude';
146
150
  type VectorArrange = 'front' | 'forward' | 'backward' | 'back';
151
+ /** Average: line anchors up on a horizontal line (same y), a vertical one (same x), or both. */
152
+ type VectorAverageAxis = 'horizontal' | 'vertical' | 'both';
153
+ /** Identifies one segment of a path node: from anchor `segment` to the next. */
154
+ interface VectorSegmentRef {
155
+ nodeId: string;
156
+ subpath: number;
157
+ segment: number;
158
+ }
147
159
 
148
160
  /**
149
161
  * Vector path geometry: anchors and handles to Bézier paths and back, bounds, hit-testing,
@@ -555,6 +567,29 @@ interface VectorSnapOptions {
555
567
  }
556
568
  /** Snap options new editors start with. Hold Cmd / Ctrl (`mod`) during a drag to bypass snapping. */
557
569
  declare const DEFAULT_VECTOR_SNAP: Readonly<VectorSnapOptions>;
570
+ /** How path-editing gestures and the pencil, knife and eraser behave. */
571
+ interface VectorPathEditOptions {
572
+ /**
573
+ * Deleting anchors refits the neighbouring handles so the shape stays (default true). Off,
574
+ * the neighbours are joined with their handles as they are.
575
+ */
576
+ keepShapeOnDelete: boolean;
577
+ /**
578
+ * Dragging one anchor with the direct tool bends its two segments like the Curvature tool,
579
+ * keeping the segments beyond still (default false). Alt held during the drag flips it.
580
+ */
581
+ curvatureMoves: boolean;
582
+ /** Pencil lazy-mouse smoothing, 0–1: the pulled string is up to 100 screen pixels long (default 0, off). */
583
+ pencilSmoothing: number;
584
+ /** Pencil strokes that look like a line, rectangle, ellipse or polygon become that shape (default false). */
585
+ recognizeShapes: boolean;
586
+ /** Eraser diameter in document units (default 10). */
587
+ eraserSize: number;
588
+ }
589
+ /** Path-editing options new editors start with. */
590
+ declare const DEFAULT_VECTOR_PATH_EDIT: Readonly<VectorPathEditOptions>;
591
+ /** Longest pencil lazy-mouse string (at smoothing 1), in screen pixels. */
592
+ declare const VECTOR_PENCIL_STRING_PX = 100;
558
593
  interface VectorEditorOptions {
559
594
  document?: VectorDocument;
560
595
  /** History to record into, e.g. one shared with the rest of the app (default: a new one). */
@@ -565,6 +600,7 @@ interface VectorEditorOptions {
565
600
  defaults?: VectorDefaults;
566
601
  viewport?: Partial<VectorViewport>;
567
602
  snap?: Partial<VectorSnapOptions>;
603
+ editing?: Partial<VectorPathEditOptions>;
568
604
  /** Pick distance for anchors, handles and outlines in screen pixels (default 6). */
569
605
  hitRadius?: number;
570
606
  /** Id factory for new nodes. */
@@ -587,6 +623,7 @@ interface VectorHover {
587
623
  nodeId: string | null;
588
624
  anchor?: VectorAnchorRef;
589
625
  handle?: VectorHandleRef;
626
+ /** A segment under the pointer (direct tool and scissors); `point` is in document space. */
590
627
  segment?: {
591
628
  nodeId: string;
592
629
  subpath: number;
@@ -619,11 +656,20 @@ type VectorInteraction = {
619
656
  } | {
620
657
  type: 'handle';
621
658
  ref: VectorHandleRef;
659
+ } | {
660
+ type: 'bend';
661
+ ref: VectorSegmentRef;
622
662
  } | {
623
663
  type: 'draw';
624
664
  tool: VectorTool;
625
665
  nodeId: string;
626
666
  bounds: VectorBounds;
667
+ string?: [Vec2, Vec2];
668
+ } | {
669
+ type: 'stroke';
670
+ tool: 'knife' | 'eraser';
671
+ points: Vec2[];
672
+ width: number;
627
673
  } | {
628
674
  type: 'pen';
629
675
  nodeId: string;
@@ -647,6 +693,7 @@ interface VectorEditorState {
647
693
  viewport: VectorViewport;
648
694
  defaults: Readonly<Required<Pick<VectorDefaults, 'polygonSides' | 'starPoints' | 'starInnerRatio' | 'cornerRadius'>> & VectorStyle>;
649
695
  snap: VectorSnapOptions;
696
+ editing: VectorPathEditOptions;
650
697
  /** Smart guides of the snap in progress, in document units (null when there are none). */
651
698
  guides: VectorSnapGuides | null;
652
699
  hitRadius: number;
@@ -784,6 +831,7 @@ declare class VectorEditorController {
784
831
  private defaults;
785
832
  private viewport;
786
833
  private snap;
834
+ private editing;
787
835
  private hitRadius;
788
836
  private hover;
789
837
  private pointer;
@@ -855,6 +903,8 @@ declare class VectorEditorController {
855
903
  setTool(tool: VectorTool): void;
856
904
  setDefaults(defaults: Partial<VectorDefaults>): void;
857
905
  setSnap(snap: Partial<VectorSnapOptions>): void;
906
+ /** Changes how deleting, dragging anchors, the pencil and the eraser behave. */
907
+ setEditing(editing: Partial<VectorPathEditOptions>): void;
858
908
  /** Turns object snapping on or off (the toolbar's snapping toggle). */
859
909
  toggleSnapping(on?: boolean): void;
860
910
  private gridValue;
@@ -1013,8 +1063,22 @@ declare class VectorEditorController {
1013
1063
  private updateAnchors;
1014
1064
  /** Moves anchors by a document-space offset (converted into each node's own space). */
1015
1065
  private movedAnchors;
1016
- /** Moves one anchor to a document position (handles follow). */
1017
- moveAnchor(ref: VectorAnchorRef, to: Vec2): VectorActionResult;
1066
+ /**
1067
+ * Moves one anchor to a document position. Its handles follow; with `curvature` (default:
1068
+ * the `curvatureMoves` setting) its two segments bend instead, as the Curvature tool does.
1069
+ */
1070
+ moveAnchor(ref: VectorAnchorRef, to: Vec2, options?: {
1071
+ curvature?: boolean;
1072
+ }): VectorActionResult;
1073
+ /** `doc` with anchor `ref` moved to document point `to` by a Curvature-tool move. */
1074
+ private curvatureMoved;
1075
+ /** `doc` with segment `ref` bent through document point `p` at parameter `t`. */
1076
+ private bent;
1077
+ /**
1078
+ * Bends a segment so the curve passes through document point `to` at parameter `t`
1079
+ * (default 0.5, clamped to 0.05–0.95); see `bendSegment` in `pathEdit`.
1080
+ */
1081
+ bendSegment(ref: VectorSegmentRef, to: Vec2, t?: number): VectorActionResult;
1018
1082
  /** Moves one handle to a document position (see `moveAnchorHandle` for how the opposite handle follows). */
1019
1083
  moveHandle(ref: VectorHandleRef, to: Vec2, options?: {
1020
1084
  breakHandles?: boolean;
@@ -1023,12 +1087,95 @@ declare class VectorEditorController {
1023
1087
  convertAnchors(type: VectorAnchorType, refs?: readonly VectorAnchorRef[]): VectorActionResult;
1024
1088
  /** Adds an anchor on the nearest segment of `nodeId` to document point `point` (shape unchanged). */
1025
1089
  insertAnchorAt(nodeId: string, point: Vec2): VectorAnchorRef | null;
1026
- /** Deletes the selected anchors; empty subpaths and paths go too. */
1027
- deleteAnchors(refs?: readonly VectorAnchorRef[]): VectorActionResult;
1090
+ /**
1091
+ * Deletes the selected (or given) anchors; subpaths left with one anchor and empty paths go
1092
+ * too. With `keepShape` (default: the `keepShapeOnDelete` setting, on) the neighbours'
1093
+ * handles are refitted so the path keeps its shape; off, the neighbours are joined as they are.
1094
+ */
1095
+ deleteAnchors(refs?: readonly VectorAnchorRef[], options?: {
1096
+ keepShape?: boolean;
1097
+ }): VectorActionResult;
1028
1098
  /** Opens or closes the subpaths that contain selected anchors (or all subpaths of `nodeId`). */
1029
1099
  setClosed(closed: boolean, nodeId?: string): VectorActionResult;
1030
1100
  /** Reverses the direction of every subpath of the selected paths. */
1031
1101
  reversePaths(ids?: readonly string[]): VectorActionResult;
1102
+ /** Unlocked path nodes in the given roots (default: the paths being edited, else the selection). */
1103
+ private pathTargets;
1104
+ /** Subpaths of node `from` mapped into node `to`'s own space. */
1105
+ private subpathsIn;
1106
+ /**
1107
+ * Replaces a path with pieces: each entry becomes one path (the first keeps the node's id and
1108
+ * place, the others go just above it with the same style). No pieces removes the path.
1109
+ * Returns the ids of the paths now standing in for it.
1110
+ */
1111
+ private replaceWithPieces;
1112
+ /** Clears anchor selections, editing and pen state that no longer point at anything. */
1113
+ private dropStaleRefs;
1114
+ /**
1115
+ * Join: the open subpaths of the selected (or given) paths become one open path, joined
1116
+ * nearest endpoints first (ends within `tolerance` document units merge into one anchor,
1117
+ * others get a straight segment); a single open subpath is closed. The result replaces the
1118
+ * lowest path, in its space and style. Default tolerance: the pick distance.
1119
+ */
1120
+ joinPaths(options?: {
1121
+ ids?: readonly string[];
1122
+ tolerance?: number;
1123
+ }): VectorActionResult;
1124
+ /** Average: moves the selected (or given) anchors onto their average position along `axis`, in document space. */
1125
+ averageAnchors(axis?: VectorAverageAxis, refs?: readonly VectorAnchorRef[]): VectorActionResult;
1126
+ /** Applies `fn` to every subpath of the target paths as one undo step. */
1127
+ private editSubpaths;
1128
+ /**
1129
+ * Remove Redundant Points: drops anchors of the selected (or given) paths that can go
1130
+ * without moving the outline more than `tolerance` document units (default 0.5).
1131
+ */
1132
+ removeRedundantPoints(options?: {
1133
+ ids?: readonly string[];
1134
+ tolerance?: number;
1135
+ }): VectorActionResult;
1136
+ /**
1137
+ * Smooth: pulls handles towards smooth tangents by `amount` (0–1, default 1). With the direct
1138
+ * tool and points selected, only those points change.
1139
+ */
1140
+ smoothPaths(options?: {
1141
+ ids?: readonly string[];
1142
+ amount?: number;
1143
+ refs?: readonly VectorAnchorRef[];
1144
+ }): VectorActionResult;
1145
+ /** Splits a cut subpath into pieces: separate paths for a one-subpath node, subpaths in place for a compound one. */
1146
+ private applyCuts;
1147
+ /**
1148
+ * Scissors: cuts path `nodeId` at the outline point nearest document point `point` (at an
1149
+ * anchor when within the pick distance of one). A closed subpath opens there; an open one
1150
+ * splits in two (a one-subpath path becomes two paths). Returns the ids of the paths.
1151
+ */
1152
+ cutPathAt(nodeId: string, point: Vec2): string[] | null;
1153
+ /** Scissors on the selected (or given) anchors: each cuts its subpath there (see `cutPathAt`). */
1154
+ cutAtAnchors(refs?: readonly VectorAnchorRef[]): VectorActionResult;
1155
+ /** Visible, unlocked paths a stroke over `points` can reach: in `ids`, the selection, or (with neither) any whose bounds it crosses. */
1156
+ private strokeTargets;
1157
+ /** A stroke's points in node `id`'s own space. */
1158
+ private localPoints;
1159
+ /**
1160
+ * Knife: cuts closed paths along the polyline `points` (document space) wherever it crosses
1161
+ * them from edge to edge, with no gap between the pieces. It cuts the given paths, the
1162
+ * selection, or (with neither) every path it crosses. Returns the ids of the pieces (empty
1163
+ * when nothing was cut).
1164
+ */
1165
+ knife(points: readonly Vec2[], options?: {
1166
+ ids?: readonly string[];
1167
+ }): string[];
1168
+ /**
1169
+ * Eraser: rubs out a round stroke of diameter `size` (default: the `eraserSize` setting)
1170
+ * along `points` (document space). Filled closed paths lose that area (pieces that come
1171
+ * apart become separate paths); outlines are cut where they pass under it. It erases from
1172
+ * the given paths, the selection, or (with neither) every path it reaches. Returns the ids
1173
+ * of the paths it changed or created.
1174
+ */
1175
+ erase(points: readonly Vec2[], options?: {
1176
+ ids?: readonly string[];
1177
+ size?: number;
1178
+ }): string[];
1032
1179
  /** Ends the pen path being drawn (a lone anchor is removed). */
1033
1180
  finishPath(): void;
1034
1181
  /** Copies the selection. Returns JSON text for the system clipboard (or null). */
@@ -1056,6 +1203,8 @@ declare class VectorEditorController {
1056
1203
  /** Endpoints of open subpaths of unlocked visible paths (pen tool resumes from them). */
1057
1204
  private openEndpoints;
1058
1205
  private computeHover;
1206
+ /** The nearest outline point of any visible, unlocked path within the pick distance of document point `p`. */
1207
+ private nearestOutline;
1059
1208
  private sameHover;
1060
1209
  /** Primary button down on the canvas at `screen` (pixels relative to the canvas). */
1061
1210
  pointerDown(screen: Vec2, input?: VectorPointerInput): void;
@@ -1196,6 +1345,24 @@ interface VectorOverlayRenderData {
1196
1345
  lines: VectorRenderGuideLine[];
1197
1346
  labels: VectorRenderGuideLabel[];
1198
1347
  };
1348
+ /**
1349
+ * The knife or eraser stroke being drawn, screen space: `d` is an open polyline; draw the
1350
+ * eraser's with a round-capped stroke `width` pixels wide (0 for the knife: a thin line).
1351
+ */
1352
+ toolStroke: {
1353
+ tool: 'knife' | 'eraser';
1354
+ d: string;
1355
+ width: number;
1356
+ } | null;
1357
+ /** The pencil's lazy-mouse string from the pen to the pointer, screen space. */
1358
+ pencilString: {
1359
+ x1: number;
1360
+ y1: number;
1361
+ x2: number;
1362
+ y2: number;
1363
+ } | null;
1364
+ /** Where the scissors would cut (screen space). */
1365
+ cutPoint: Vec2 | null;
1199
1366
  /** A short status, e.g. "W 120 × H 80" or "45°". */
1200
1367
  status: string | null;
1201
1368
  }
@@ -1215,6 +1382,8 @@ declare const VECTOR_OVERLAY_THEME: {
1215
1382
  readonly guide: "#ff3dfc";
1216
1383
  readonly handleFill: "#ffffff";
1217
1384
  readonly marqueeFill: "rgba(14, 165, 233, 0.08)";
1385
+ /** The eraser's swath while it is dragged. */
1386
+ readonly eraserFill: "rgba(239, 68, 68, 0.25)";
1218
1387
  readonly transformHandleSize: 8;
1219
1388
  readonly anchorSize: 7;
1220
1389
  readonly handleRadius: 3.5;
@@ -1269,6 +1438,25 @@ interface VectorSelectionStyle {
1269
1438
  declare function getVectorSelectionStyle(state: Pick<VectorEditorState, 'document' | 'selection'>): VectorSelectionStyle | null;
1270
1439
  /** A paint as `#rrggbb` for `<input type="color">`, or null for none, gradients and other CSS colours. */
1271
1440
  declare function vectorPaintToHex(paint: VectorPaint | undefined): string | null;
1441
+ /** A path-editing button of the bundled toolbars. */
1442
+ interface VectorPathAction {
1443
+ id: 'join' | 'average' | 'cut' | 'clean' | 'smooth';
1444
+ label: string;
1445
+ title: string;
1446
+ /** Shortcut after Cmd / Ctrl, if any. */
1447
+ shortcut?: string;
1448
+ /** Whether it can run with `selected` nodes and `points` selected anchors (direct tool). */
1449
+ enabled: (selected: number, points: number) => boolean;
1450
+ run: (controller: VectorEditorController) => unknown;
1451
+ }
1452
+ /** Join, Average, Cut at Points, Remove Redundant Points and Smooth, as the toolbars show them. */
1453
+ declare const VECTOR_PATH_ACTIONS: readonly VectorPathAction[];
1454
+ /** The on / off path-editing settings the toolbars toggle. */
1455
+ declare const VECTOR_EDIT_TOGGLES: readonly {
1456
+ key: 'keepShapeOnDelete' | 'curvatureMoves' | 'recognizeShapes';
1457
+ label: string;
1458
+ title: string;
1459
+ }[];
1272
1460
 
1273
1461
  interface VectorCommandOptions {
1274
1462
  /** Id prefix (default `vector.`); use one per editor when several are registered. */
@@ -1311,4 +1499,182 @@ interface VectorNodeListing {
1311
1499
  */
1312
1500
  declare function createVectorCommands(controller: VectorEditorController, options?: VectorCommandOptions): CommandSpec[];
1313
1501
 
1314
- export { type AddVectorNodeOptions, AffineMatrix, DEFAULT_VECTOR_SNAP, IDENTITY_MATRIX, KAPPA, type NearestSegment, SvgGradientDef, VECTOR_CLIPBOARD_TYPE, VECTOR_CONSTRUCTION_ANGLES, VECTOR_OVERLAY_THEME, VECTOR_ROTATE_HANDLE_OFFSET, VECTOR_TOOLS, VECTOR_TOOL_GLYPHS, VECTOR_TOOL_SHORTCUTS, VECTOR_TRANSFORM_HANDLES, type Vec2, type VectorActionResult, type VectorAlign, type VectorAnchor, type VectorAnchorRef, type VectorAnchorType, type VectorArrange, type VectorBooleanOperation, type VectorBounds, type VectorCommandOptions, type VectorDefaults, type VectorDistribute, type VectorDocument, VectorEditorController, type VectorEditorOptions, type VectorEditorState, type VectorFillRule, type VectorGroupNode, type VectorGuideKind, type VectorGuideLabel, type VectorGuideLine, type VectorHandleRef, type VectorHover, type VectorInteraction, type VectorKeyInput, type VectorLineCap, type VectorLineJoin, type VectorMatrix, type VectorModifiers, type VectorNode, type VectorNodeListing, type VectorOverlayRenderData, type VectorPaint, type VectorPathNode, type VectorPointSnap, type VectorPointerInput, type VectorRectSnap, type VectorRenderAnchor, type VectorRenderGroup, type VectorRenderGuideLabel, type VectorRenderGuideLine, type VectorRenderHandle, type VectorRenderNode, type VectorRenderPath, type VectorScaleSnap, type VectorSceneRenderData, type VectorSelectionBoxGeometry, type VectorSelectionFrame, type VectorSelectionStyle, type VectorShapeInput, type VectorSnapGuides, type VectorSnapKind, type VectorSnapLeave, type VectorSnapOptions, VectorSnapTargets, type VectorStyle, type VectorSubpath, type VectorSvgExportOptions, type VectorSvgImportOptions, type VectorTool, type VectorTransformHandle, type VectorViewport, applyMatrix, applyMatrixLinear, bezierToSubpaths, boundsFromPoints, boundsIntersect, cloneAnchor, cloneSubpath, cloneVectorDocument, cloneVectorNode, collectPathNodes, constrainToLeave, convertAnchor, createVectorCommands, decomposeRigid, ellipseSubpath, findVectorNode, getAnchor, getAnchorWorld, getEditablePathIds, getTransformHandlePositions, getVectorOverlayRenderData, getVectorSceneRenderData, getVectorSelectionBoxGeometry, getVectorSelectionFrame, getVectorSelectionStyle, getVisibleAnchors, getVisibleHandles, hasPaint, hitTestVectorNode, hitTestVectorNodes, inferAnchorType, insertAnchor, invertMatrix, isIdentityMatrix, isVectorTextTarget, lineSubpath, locateVectorNode, matrixRotation, moveAnchorHandle, multiplyMatrices, nearestSegment, nodeMatrix, parseSvgTransform, parseVectorSvg, polygonSubpath, rectSubpath, removeAnchors, reverseSubpath, rotateMatrix, roundSubpaths, scaleFor, scaleMatrix, starSubpath, subpathSegment, subpathSegmentCount, subpathsToBezier, toVectorKeyInput, toVectorModifiers, toVectorPointerInput, transformVectorNode, translateAnchor, translateMatrix, unionBounds, vectorDocumentToSvg, vectorNodeBounds, vectorNodeRotation, vectorNodeToBezier, vectorPaintToHex, vectorPaintToSvg, vectorParentMatrix, vectorPathData, vectorPathWorldBezier, vectorResizeCursor, vectorToolLabel, vectorWorldMatrix, walkVectorNodes };
1502
+ /**
1503
+ * Removes anchor `index` without opening the path: its neighbours keep their handle directions
1504
+ * and their facing handles are refitted so one cubic follows the two segments that met there
1505
+ * as closely as possible (least maximum error over where the new curve passes the removed
1506
+ * point). Two straight segments become one; removing an end of an open subpath drops its
1507
+ * segment. Returns the subpath unchanged (a copy) when `index` is out of range.
1508
+ */
1509
+ declare function removeAnchorKeepingShape(sp: VectorSubpath, index: number): VectorSubpath;
1510
+ /** Removes several anchors of a subpath, keeping the shape (see `removeAnchorKeepingShape`). */
1511
+ declare function removeAnchorsKeepingShape(sp: VectorSubpath, indices: readonly number[]): VectorSubpath;
1512
+ /**
1513
+ * Bends segment `segment` so the curve passes through `p` at parameter `t` (clamped to
1514
+ * 0.05–0.95): its handles go to the thirds of the chord plus one shared offset, so
1515
+ * `B(t) = L(t) + 3t(1 − t)·offset` exactly. The end anchors keep their types (a smooth or
1516
+ * symmetric end turns its other handle to stay in line).
1517
+ */
1518
+ declare function bendSegment(sp: VectorSubpath, segment: number, t: number, p: Vec2): VectorSubpath;
1519
+ /** The point at parameter `t` of segment `segment` (for tests and previews). */
1520
+ declare function subpathPointAt(sp: VectorSubpath, segment: number, t: number): Vec2;
1521
+ /**
1522
+ * Moves anchor `index` to `q` the way the Curvature tool drags a point: only the two segments
1523
+ * at it change. A smooth or symmetric anchor turns its handles along the line through its
1524
+ * neighbours; the neighbours' handles on those segments, and a corner's own handles, keep
1525
+ * their directions while their lengths scale with their segment's chord, so the segments
1526
+ * beyond don't move and a corner without handles keeps none.
1527
+ */
1528
+ declare function curvatureMoveAnchor(sp: VectorSubpath, index: number, q: Vec2): VectorSubpath;
1529
+ /**
1530
+ * Cuts a subpath at the anchors `at`: each becomes the end of one open piece and the start of
1531
+ * the next, its handle off each piece dropped (the shape doesn't change). A closed subpath
1532
+ * opens at its first cut, so one cut leaves one piece whose ends coincide. The ends of an open
1533
+ * subpath and indices out of range don't cut; with no cut left the subpath comes back as it is.
1534
+ */
1535
+ declare function cutSubpathAt(sp: VectorSubpath, at: readonly number[]): VectorSubpath[];
1536
+ /**
1537
+ * Cuts a subpath at parameter `t` of segment `segment` (Scissors on a segment): an anchor is
1538
+ * inserted there without changing the shape, then cut. Within `endTolerance` of the segment's
1539
+ * ends (in parameter) the existing anchor is cut instead.
1540
+ */
1541
+ declare function splitSubpathAt(sp: VectorSubpath, segment: number, t: number, endTolerance?: number): VectorSubpath[];
1542
+ /**
1543
+ * Join: open subpaths are joined nearest-endpoints-first into one open subpath (endpoints
1544
+ * within `tolerance` merge into one anchor, otherwise a straight segment connects them). A
1545
+ * single open subpath is closed instead (its ends merged when they meet). Closed subpaths and
1546
+ * lone anchors pass through unchanged, before the joined one.
1547
+ */
1548
+ declare function joinSubpaths(subpaths: readonly VectorSubpath[], tolerance: number): VectorSubpath[];
1549
+ /**
1550
+ * Smooth: pulls handles towards Catmull-Rom-like tangents (a third of the way to each
1551
+ * neighbour along the line through both). `amount` 0–1 (0 = unchanged, 1 = fully smooth).
1552
+ * Only the anchors in `only` change when it is given; endpoints of open subpaths keep their
1553
+ * handles. Subpaths of fewer than three anchors are unchanged.
1554
+ */
1555
+ declare function smoothSubpath(sp: VectorSubpath, amount?: number, only?: ReadonlySet<number>): VectorSubpath;
1556
+ /**
1557
+ * Remove Redundant Points: drops anchors that can go without changing the shape by more than
1558
+ * `tolerance` (collinear corners, duplicate points, and smooth joints that one cubic can
1559
+ * replace).
1560
+ */
1561
+ declare function removeRedundantPoints(sp: VectorSubpath, tolerance: number): VectorSubpath;
1562
+
1563
+ /**
1564
+ * Knife and eraser on Bézier paths, built on the curve booleans and `outlineStroke`.
1565
+ *
1566
+ * The knife cuts filled regions along a polyline with no gap: each stretch of the polyline
1567
+ * that crosses a region from boundary to boundary (a chord) splits the boundary loop it starts
1568
+ * and ends on into two loops sharing that chord, or, when it joins two loops (an outline and a
1569
+ * hole), merges them into one. Crossings are exact (line–cubic roots), and the pieces share
1570
+ * the cut edge exactly.
1571
+ *
1572
+ * The eraser removes the area of a round-capped stroke along a polyline: filled shapes lose it
1573
+ * by a boolean difference; outlines are cut where they cross the stroke's outline (exact
1574
+ * curve–curve intersections) and keep the parts outside it.
1575
+ *
1576
+ * Modelled on vectorcraft-main/crates/engine/src/cmd/draw2.rs (`knife`, `erase_region`,
1577
+ * `erase_outline`, `cut_subpath`; MIT OR Apache-2.0, © ArtCraft Team and contributors; see
1578
+ * THIRD_PARTY_NOTICES.md), without its fixed knife slit and its sampled crossing search.
1579
+ */
1580
+
1581
+ type FillRule = 'nonzero' | 'evenodd';
1582
+ /** One path per face (an outline with its holes) of a filled path, largest first. */
1583
+ declare function splitIntoFaces(path: BezierPathInput, fillRule?: FillRule): BezierPath[];
1584
+ /**
1585
+ * Cuts the filled path along the open polyline `knife`. Returns one path per resulting face
1586
+ * (an outline with its holes), or null when the knife crossed nothing from edge to edge. A
1587
+ * stretch of the knife that starts or ends inside the shape does not cut.
1588
+ */
1589
+ declare function knifePath(path: BezierPathInput, fillRule: FillRule, knife: readonly Point[]): BezierPath[] | null;
1590
+ /** The area a round eraser of diameter `width` covers along `points` (a disc for one point). */
1591
+ declare function eraserRegion(points: readonly Point[], width: number): BezierPath;
1592
+ /**
1593
+ * A filled path with `region` removed: one path per remaining face, or null when the region
1594
+ * does not overlap the fill.
1595
+ */
1596
+ declare function eraseFromFill(path: BezierPathInput, fillRule: FillRule, region: BezierPathInput): BezierPath[] | null;
1597
+ /**
1598
+ * The parts of a subpath's outline outside `region`, as open subpaths that keep the original
1599
+ * curves exactly; null when the outline does not enter the region. A closed subpath's last
1600
+ * and first parts join at its first anchor.
1601
+ */
1602
+ declare function eraseFromOutline(sp: VectorSubpath, region: BezierPathInput): VectorSubpath[] | null;
1603
+ /** Bounds of a point list (for picking the paths a knife or eraser stroke can reach). */
1604
+ declare function polylineBounds(points: readonly Point[], pad?: number): {
1605
+ x: number;
1606
+ y: number;
1607
+ width: number;
1608
+ height: number;
1609
+ } | null;
1610
+ /** Ramer–Douglas–Peucker reduction of a polyline (keeps both ends). */
1611
+ declare function simplifyPolyline(points: readonly Point[], tolerance: number): Point[];
1612
+
1613
+ /**
1614
+ * Pencil helpers: lazy-mouse smoothing (a pulled string between the pointer and the pen) and
1615
+ * ink-to-shape recognition (a hand-drawn stroke that is a line, rectangle, ellipse or polygon).
1616
+ *
1617
+ * Portions ported from (MIT OR Apache-2.0, © ArtCraft Team and contributors; see
1618
+ * THIRD_PARTY_NOTICES.md):
1619
+ * - photocraft-main/crates/paint/src/dynamics.rs (`Smoother`: pulled-string mode, `string`,
1620
+ * `finish` with catch-up on stroke end)
1621
+ * - wordcraft-main/crates/engine/src/cmd/ink_shape.rs (`recognise`, `ellipse_rms`,
1622
+ * `snap_square`, `corners`, `turning`, `rdp`, `upright`)
1623
+ */
1624
+
1625
+ /**
1626
+ * Pulled-string smoothing: the pen stays put until the pointer is more than `length` away,
1627
+ * then follows it at that distance, so small wobbles never reach the stroke. Feed pointer
1628
+ * positions to `push`; it returns the pen positions to draw through (possibly none).
1629
+ */
1630
+ declare class LazyMouse {
1631
+ readonly length: number;
1632
+ private pos;
1633
+ private last;
1634
+ /** `length` is the string length in the units of the points (0 turns smoothing off). */
1635
+ constructor(length: number);
1636
+ push(p: Point): Point[];
1637
+ /** The string from the pen to the pointer while they are apart, else null. */
1638
+ string(): [Point, Point] | null;
1639
+ /** End of stroke: the pen catches up with the pointer (the point to add, if it lagged). */
1640
+ finish(): Point[];
1641
+ }
1642
+ /** A shape recognised in a stroke, in the stroke's coordinates. */
1643
+ type VectorInkShape = {
1644
+ kind: 'line';
1645
+ a: Point;
1646
+ b: Point;
1647
+ } | {
1648
+ kind: 'rect';
1649
+ x: number;
1650
+ y: number;
1651
+ width: number;
1652
+ height: number;
1653
+ } | {
1654
+ kind: 'ellipse';
1655
+ x: number;
1656
+ y: number;
1657
+ width: number;
1658
+ height: number;
1659
+ } | {
1660
+ kind: 'polygon';
1661
+ points: Point[];
1662
+ };
1663
+ interface RecognizeInkOptions {
1664
+ /** Strokes whose longer side is smaller than this stay ink (default 6). */
1665
+ minSize?: number;
1666
+ }
1667
+ /** Most corners a recognised polygon may have. */
1668
+ declare const VECTOR_INK_MAX_CORNERS = 8;
1669
+ /** "line", "square", "rectangle", "circle", "ellipse", "triangle" or "polygon". */
1670
+ declare function vectorInkShapeName(shape: VectorInkShape): string;
1671
+ /**
1672
+ * The shape a hand-drawn stroke draws, if it is one: an open stroke is a line when it stays
1673
+ * close to the chord between its ends; a closed one is an ellipse when its points sit on the
1674
+ * ellipse inscribed in their bounds, else a polygon of 3–8 corners when that polygon stays
1675
+ * close to every point (an upright four-cornered one is a rectangle). Nearly square boxes
1676
+ * become squares and circles. Anything else (scribbles, curves, letters) is null.
1677
+ */
1678
+ declare function recognizeInkShape(points: readonly Point[], options?: RecognizeInkOptions): VectorInkShape | null;
1679
+
1680
+ export { type AddVectorNodeOptions, AffineMatrix, DEFAULT_VECTOR_PATH_EDIT, DEFAULT_VECTOR_SNAP, IDENTITY_MATRIX, KAPPA, LazyMouse, type NearestSegment, type RecognizeInkOptions, SvgGradientDef, VECTOR_CLIPBOARD_TYPE, VECTOR_CONSTRUCTION_ANGLES, VECTOR_EDIT_TOGGLES, VECTOR_INK_MAX_CORNERS, VECTOR_OVERLAY_THEME, VECTOR_PATH_ACTIONS, VECTOR_PENCIL_STRING_PX, VECTOR_ROTATE_HANDLE_OFFSET, VECTOR_TOOLS, VECTOR_TOOL_GLYPHS, VECTOR_TOOL_SHORTCUTS, VECTOR_TRANSFORM_HANDLES, type Vec2, type VectorActionResult, type VectorAlign, type VectorAnchor, type VectorAnchorRef, type VectorAnchorType, type VectorArrange, type VectorAverageAxis, type VectorBooleanOperation, type VectorBounds, type VectorCommandOptions, type VectorDefaults, type VectorDistribute, type VectorDocument, VectorEditorController, type VectorEditorOptions, type VectorEditorState, type VectorFillRule, type VectorGroupNode, type VectorGuideKind, type VectorGuideLabel, type VectorGuideLine, type VectorHandleRef, type VectorHover, type VectorInkShape, type VectorInteraction, type VectorKeyInput, type VectorLineCap, type VectorLineJoin, type VectorMatrix, type VectorModifiers, type VectorNode, type VectorNodeListing, type VectorOverlayRenderData, type VectorPaint, type VectorPathAction, type VectorPathEditOptions, type VectorPathNode, type VectorPointSnap, type VectorPointerInput, type VectorRectSnap, type VectorRenderAnchor, type VectorRenderGroup, type VectorRenderGuideLabel, type VectorRenderGuideLine, type VectorRenderHandle, type VectorRenderNode, type VectorRenderPath, type VectorScaleSnap, type VectorSceneRenderData, type VectorSegmentRef, type VectorSelectionBoxGeometry, type VectorSelectionFrame, type VectorSelectionStyle, type VectorShapeInput, type VectorSnapGuides, type VectorSnapKind, type VectorSnapLeave, type VectorSnapOptions, VectorSnapTargets, type VectorStyle, type VectorSubpath, type VectorSvgExportOptions, type VectorSvgImportOptions, type VectorTool, type VectorTransformHandle, type VectorViewport, applyMatrix, applyMatrixLinear, bendSegment, bezierToSubpaths, boundsFromPoints, boundsIntersect, cloneAnchor, cloneSubpath, cloneVectorDocument, cloneVectorNode, collectPathNodes, constrainToLeave, convertAnchor, createVectorCommands, curvatureMoveAnchor, cutSubpathAt, decomposeRigid, ellipseSubpath, eraseFromFill, eraseFromOutline, eraserRegion, findVectorNode, getAnchor, getAnchorWorld, getEditablePathIds, getTransformHandlePositions, getVectorOverlayRenderData, getVectorSceneRenderData, getVectorSelectionBoxGeometry, getVectorSelectionFrame, getVectorSelectionStyle, getVisibleAnchors, getVisibleHandles, hasPaint, hitTestVectorNode, hitTestVectorNodes, inferAnchorType, insertAnchor, invertMatrix, isIdentityMatrix, isVectorTextTarget, joinSubpaths, knifePath, lineSubpath, locateVectorNode, matrixRotation, moveAnchorHandle, multiplyMatrices, nearestSegment, nodeMatrix, parseSvgTransform, parseVectorSvg, polygonSubpath, polylineBounds, recognizeInkShape, rectSubpath, removeAnchorKeepingShape, removeAnchors, removeAnchorsKeepingShape, removeRedundantPoints, reverseSubpath, rotateMatrix, roundSubpaths, scaleFor, scaleMatrix, simplifyPolyline, smoothSubpath, splitIntoFaces, splitSubpathAt, starSubpath, subpathPointAt, subpathSegment, subpathSegmentCount, subpathsToBezier, toVectorKeyInput, toVectorModifiers, toVectorPointerInput, transformVectorNode, translateAnchor, translateMatrix, unionBounds, vectorDocumentToSvg, vectorInkShapeName, vectorNodeBounds, vectorNodeRotation, vectorNodeToBezier, vectorPaintToHex, vectorPaintToSvg, vectorParentMatrix, vectorPathData, vectorPathWorldBezier, vectorResizeCursor, vectorToolLabel, vectorWorldMatrix, walkVectorNodes };