@pixerate/editor 0.21.0 → 0.23.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.
- package/README.md +100 -13
- package/THIRD_PARTY_NOTICES.md +88 -0
- package/dist/agent/index.cjs +86 -111
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +69 -211
- package/dist/agent/index.d.ts +69 -211
- package/dist/agent/index.js +77 -102
- package/dist/agent/index.js.map +1 -1
- package/dist/arrangeShortcuts-B8O3f8-P.d.cts +184 -0
- package/dist/arrangeShortcuts-sLlD2rSX.d.ts +184 -0
- package/dist/canvas/index.cjs +2112 -60
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +712 -181
- package/dist/canvas/index.d.ts +712 -181
- package/dist/canvas/index.js +2105 -53
- package/dist/canvas/index.js.map +1 -1
- package/dist/chunk-26BVFKHU.cjs +453 -0
- package/dist/chunk-26BVFKHU.cjs.map +1 -0
- package/dist/chunk-2H7ZHPEJ.js +762 -0
- package/dist/chunk-2H7ZHPEJ.js.map +1 -0
- package/dist/chunk-7DWMJCAT.js +453 -0
- package/dist/chunk-7DWMJCAT.js.map +1 -0
- package/dist/{chunk-TVRC4KVT.cjs → chunk-AA4ZEVCC.cjs} +845 -90
- package/dist/chunk-AA4ZEVCC.cjs.map +1 -0
- package/dist/chunk-ARRTP33I.js +101 -0
- package/dist/chunk-ARRTP33I.js.map +1 -0
- package/dist/{chunk-LA7PEGU3.cjs → chunk-CL37JGFW.cjs} +4 -4
- package/dist/{chunk-LA7PEGU3.cjs.map → chunk-CL37JGFW.cjs.map} +1 -1
- package/dist/chunk-CPOKFNBG.cjs +101 -0
- package/dist/chunk-CPOKFNBG.cjs.map +1 -0
- package/dist/chunk-G2I4QJOT.cjs +762 -0
- package/dist/chunk-G2I4QJOT.cjs.map +1 -0
- package/dist/{chunk-4QPLEUL2.cjs → chunk-GVSMRPHB.cjs} +1046 -54
- package/dist/chunk-GVSMRPHB.cjs.map +1 -0
- package/dist/{chunk-KYRZDWM4.js → chunk-JJDLPEWL.js} +2 -2
- package/dist/{chunk-GVW4P7BG.js → chunk-K3R5NG2D.js} +448 -54
- package/dist/chunk-K3R5NG2D.js.map +1 -0
- package/dist/{chunk-3TYMNULT.js → chunk-MJZBNWG7.js} +807 -52
- package/dist/chunk-MJZBNWG7.js.map +1 -0
- package/dist/{chunk-A7DKIA72.js → chunk-QBJ22YZR.js} +1059 -93
- package/dist/chunk-QBJ22YZR.js.map +1 -0
- package/dist/{chunk-CYFJCKC4.js → chunk-QGHGJ56O.js} +997 -5
- package/dist/chunk-QGHGJ56O.js.map +1 -0
- package/dist/{chunk-JYRIOFEN.cjs → chunk-RIKBJLS2.cjs} +1064 -98
- package/dist/chunk-RIKBJLS2.cjs.map +1 -0
- package/dist/{chunk-U6NDQFOK.cjs → chunk-XDMXXC4Z.cjs} +569 -175
- package/dist/chunk-XDMXXC4Z.cjs.map +1 -0
- package/dist/commands/index.cjs +860 -0
- package/dist/commands/index.cjs.map +1 -0
- package/dist/commands/index.d.cts +592 -0
- package/dist/commands/index.d.ts +592 -0
- package/dist/commands/index.js +860 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/{controller-OUdxPY-X.d.ts → controller-pePCJLT1.d.cts} +216 -11
- package/dist/{controller-OUdxPY-X.d.cts → controller-pePCJLT1.d.ts} +216 -11
- package/dist/extensions/index.cjs +14 -4
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +3 -3
- package/dist/extensions/index.d.ts +3 -3
- package/dist/extensions/index.js +13 -3
- package/dist/history/index.cjs +12 -2
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +211 -7
- package/dist/history/index.d.ts +211 -7
- package/dist/history/index.js +13 -3
- package/dist/image-editor/index.cjs +418 -13
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +154 -3
- package/dist/image-editor/index.d.ts +154 -3
- package/dist/image-editor/index.js +417 -12
- package/dist/image-editor/index.js.map +1 -1
- package/dist/{index-k3mFbPx_.d.cts → index-CCr_z9kF.d.cts} +3 -3
- package/dist/{index-Ng1pG7JE.d.ts → index-Ck6ajwXh.d.ts} +3 -3
- package/dist/index.cjs +275 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +296 -47
- package/dist/index.d.ts +296 -47
- package/dist/index.js +266 -74
- package/dist/index.js.map +1 -1
- package/dist/registry-D5-R90p0.d.cts +209 -0
- package/dist/registry-D5-R90p0.d.ts +209 -0
- package/dist/{registry-iAHbqkYt.d.cts → registry-GJI4gToU.d.cts} +15 -4
- package/dist/{registry-iAHbqkYt.d.ts → registry-GJI4gToU.d.ts} +15 -4
- package/dist/serializers/index.cjs +3 -3
- package/dist/serializers/index.d.cts +1 -1
- package/dist/serializers/index.d.ts +1 -1
- package/dist/serializers/index.js +2 -2
- package/dist/spreadsheet/index.cjs +23 -3
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.d.cts +97 -10
- package/dist/spreadsheet/index.d.ts +97 -10
- package/dist/spreadsheet/index.js +22 -2
- package/dist/{track-changes-G8JcWB8b.d.cts → track-changes-BSF58RK0.d.cts} +92 -9
- package/dist/{track-changes-G8JcWB8b.d.ts → track-changes-BSF58RK0.d.ts} +92 -9
- package/dist/{types-DMe0vFB1.d.cts → types-DX4Mh4SL.d.cts} +1 -1
- package/dist/{types-DMe0vFB1.d.ts → types-DX4Mh4SL.d.ts} +1 -1
- package/dist/types-GT5a5YAX.d.cts +86 -0
- package/dist/types-GT5a5YAX.d.ts +86 -0
- package/package.json +8 -2
- package/dist/chunk-2TWGLC5K.cjs +0 -262
- package/dist/chunk-2TWGLC5K.cjs.map +0 -1
- package/dist/chunk-3TYMNULT.js.map +0 -1
- package/dist/chunk-4QPLEUL2.cjs.map +0 -1
- package/dist/chunk-A7DKIA72.js.map +0 -1
- package/dist/chunk-CYFJCKC4.js.map +0 -1
- package/dist/chunk-GVW4P7BG.js.map +0 -1
- package/dist/chunk-JYRIOFEN.cjs.map +0 -1
- package/dist/chunk-KAADNAPF.js +0 -262
- package/dist/chunk-KAADNAPF.js.map +0 -1
- package/dist/chunk-TVRC4KVT.cjs.map +0 -1
- package/dist/chunk-U6NDQFOK.cjs.map +0 -1
- package/dist/types-BZgcDsC5.d.cts +0 -42
- package/dist/types-BZgcDsC5.d.ts +0 -42
- /package/dist/{chunk-KYRZDWM4.js.map → chunk-JJDLPEWL.js.map} +0 -0
package/dist/canvas/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { R as Rect, C as CanvasNode, X as XYPosition,
|
|
2
|
-
export {
|
|
3
|
-
import { C as
|
|
1
|
+
import { R as Rect, C as CanvasNode, X as XYPosition, b as CanvasEdge, I as IncrementalLayoutOptions, S as Side, c as CanvasLayoutOptions, P as PlaceBesideOptions, T as TrajectoryFunction, F as FanOutTrajectoryOptions, N as NodeTransition, a as CanvasNodeStyle, d as ReflowDisplacementOptions, D as DirectionalDisplacementOptions, e as CanvasClipboardPayload, f as Position, g as Point } from '../types-DX4Mh4SL.js';
|
|
2
|
+
export { h as CanvasDockingCallbacks, i as CollapseNodeOptions, j as DisplacementDirection, k as DockStrategy, E as ExplodeNodeOptions, l as ExplosionSnapshot, G as GraphDifferences, m as TrajectoryPoint } from '../types-DX4Mh4SL.js';
|
|
3
|
+
import { b as CanvasNodeUpdate, N as NodeRectOptions, A as AlignEdge, c as AlignNodesOptions, D as DistributeAxis, a as DistributeMode, d as DistributeNodesOptions, S as SizeDimension, M as MatchSizeOptions, Z as ZOrderOperation, C as CanvasArrangeAction } from '../arrangeShortcuts-sLlD2rSX.js';
|
|
4
|
+
export { e as ArrangeShortcutBinding, f as DEFAULT_ARRANGE_SHORTCUTS, L as LOCKED_DATA_KEY, g as LOCKED_PREVIOUS_FLAGS_KEY, h as alignNodes, i as applyNodeUpdates, j as createNodeLookup, k as distributeNodes, l as getAbsolutePosition, m as getNodeRect, n as getNodeSize, o as invertNodeUpdates, p as isLocked, q as lockNodes, r as matchArrangeShortcut, s as matchSize, t as readStyleSize, u as reorderNodes, v as toggleLockNodes, w as unlockNodes, x as withStyleSize } from '../arrangeShortcuts-sLlD2rSX.js';
|
|
5
|
+
import { C as Command } from '../types-GT5a5YAX.js';
|
|
4
6
|
|
|
5
7
|
declare const DEFAULT_NODE_WIDTH = 200;
|
|
6
8
|
declare const DEFAULT_NODE_HEIGHT = 60;
|
|
@@ -328,172 +330,30 @@ declare function blendLayout<TNode extends CanvasNode = CanvasNode>(from: TNode[
|
|
|
328
330
|
*/
|
|
329
331
|
declare function connectedOnly<TNode extends CanvasNode = CanvasNode, TEdge extends CanvasEdge = CanvasEdge>(nodes: TNode[], edges: TEdge[]): TNode[];
|
|
330
332
|
|
|
331
|
-
/**
|
|
332
|
-
* Edge (or centre line) used by `alignNodes`.
|
|
333
|
-
* `center` aligns horizontal centres (a vertical line); `middle` aligns vertical centres.
|
|
334
|
-
*/
|
|
335
|
-
type AlignEdge = 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom';
|
|
336
|
-
/** Axis used by `distributeNodes`. `both` distributes horizontally and vertically. */
|
|
337
|
-
type DistributeAxis = 'horizontal' | 'vertical' | 'both';
|
|
338
|
-
/**
|
|
339
|
-
* `gaps` leaves equal space between neighbouring nodes, `centres` spaces their centres equally.
|
|
340
|
-
*/
|
|
341
|
-
type DistributeMode = 'gaps' | 'centres';
|
|
342
|
-
/** Dimension(s) copied by `matchSize`. */
|
|
343
|
-
type SizeDimension = 'width' | 'height' | 'both';
|
|
344
|
-
/**
|
|
345
|
-
* Partial node change produced by the arrange helpers. `position` is in the node's own
|
|
346
|
-
* coordinate space (relative to its `parentId` parent when it has one).
|
|
347
|
-
*/
|
|
348
|
-
interface CanvasNodeUpdate {
|
|
349
|
-
id: string;
|
|
350
|
-
position?: XYPosition;
|
|
351
|
-
width?: number;
|
|
352
|
-
height?: number;
|
|
353
|
-
zIndex?: number;
|
|
354
|
-
}
|
|
355
|
-
interface NodeRectOptions {
|
|
356
|
-
/** Width used when a node has no measured, explicit or style size and estimation is off. */
|
|
357
|
-
defaultWidth?: number;
|
|
358
|
-
/** Height used when a node has no measured, explicit or style size and estimation is off. */
|
|
359
|
-
defaultHeight?: number;
|
|
360
|
-
/** Estimate unmeasured node sizes from their label via `estimateNodeSize` (default `true`). */
|
|
361
|
-
estimate?: boolean;
|
|
362
|
-
}
|
|
363
|
-
/** Data key marking a node as locked. See `lockNodes`. */
|
|
364
|
-
declare const LOCKED_DATA_KEY = "locked";
|
|
365
|
-
/** Data key holding the interaction flags a node had before it was locked. */
|
|
366
|
-
declare const LOCKED_PREVIOUS_FLAGS_KEY = "lockedPrevious";
|
|
367
|
-
/**
|
|
368
|
-
* Reads a pixel `width` / `height` from a node style, which may be a CSS string (SvelteFlow)
|
|
369
|
-
* or a style object (React Flow). Non-pixel values (`%`, `auto`, ...) are ignored.
|
|
370
|
-
*/
|
|
371
|
-
declare function readStyleSize(style: CanvasNodeStyle | undefined | null): {
|
|
372
|
-
width?: number;
|
|
373
|
-
height?: number;
|
|
374
|
-
};
|
|
375
|
-
/**
|
|
376
|
-
* Returns `style` with its pixel `width` / `height` replaced, keeping its representation
|
|
377
|
-
* (string or object). Only dimensions already present in the style are rewritten, because
|
|
378
|
-
* xyflow applies the node's own `width` / `height` props otherwise.
|
|
379
|
-
*/
|
|
380
|
-
declare function withStyleSize(style: CanvasNodeStyle | undefined | null, size: {
|
|
381
|
-
width?: number;
|
|
382
|
-
height?: number;
|
|
383
|
-
}): CanvasNodeStyle | undefined;
|
|
384
|
-
/**
|
|
385
|
-
* Resolves a node's size: measured DOM size, then explicit `width` / `height`, then a pixel
|
|
386
|
-
* size in `style`, then a label-based estimate (or the defaults when `estimate` is `false`).
|
|
387
|
-
*/
|
|
388
|
-
declare function getNodeSize(node: CanvasNode, options?: NodeRectOptions): {
|
|
389
|
-
width: number;
|
|
390
|
-
height: number;
|
|
391
|
-
};
|
|
392
|
-
/**
|
|
393
|
-
* Absolute (flow-space) position of a node, following its `parentId` chain.
|
|
394
|
-
* Cycles and missing parents are tolerated.
|
|
395
|
-
*/
|
|
396
|
-
declare function getAbsolutePosition(node: CanvasNode, lookup: ReadonlyMap<string, CanvasNode>): XYPosition;
|
|
397
|
-
/** Builds an id lookup for a node array. */
|
|
398
|
-
declare function createNodeLookup<TNode extends CanvasNode>(nodes: TNode[]): Map<string, TNode>;
|
|
399
|
-
/** Absolute flow-space rectangle of a node. */
|
|
400
|
-
declare function getNodeRect(node: CanvasNode, lookup?: ReadonlyMap<string, CanvasNode>, options?: NodeRectOptions): Rect;
|
|
401
|
-
/**
|
|
402
|
-
* Whether a node has been locked with `lockNodes`.
|
|
403
|
-
*/
|
|
404
|
-
declare function isLocked(node: CanvasNode | undefined | null): boolean;
|
|
405
|
-
/**
|
|
406
|
-
* Locks nodes: marks `data.locked = true` and sets `draggable: false` and `deletable: false`
|
|
407
|
-
* so both SvelteFlow and React Flow stop dragging and deleting them. Nodes stay `selectable`
|
|
408
|
-
* so they can be unlocked again. The previous flags are kept in `data.lockedPrevious` and
|
|
409
|
-
* restored by `unlockNodes`. Returns a new array; untouched nodes keep their identity.
|
|
410
|
-
*/
|
|
411
|
-
declare function lockNodes<TNode extends CanvasNode>(nodes: TNode[], ids: Iterable<string>): TNode[];
|
|
412
|
-
/**
|
|
413
|
-
* Reverses `lockNodes`, restoring the `draggable` / `deletable` flags the node had before.
|
|
414
|
-
*/
|
|
415
|
-
declare function unlockNodes<TNode extends CanvasNode>(nodes: TNode[], ids: Iterable<string>): TNode[];
|
|
416
|
-
/** Locks the given nodes if any of them is unlocked, otherwise unlocks them all. */
|
|
417
|
-
declare function toggleLockNodes<TNode extends CanvasNode>(nodes: TNode[], ids: Iterable<string>): TNode[];
|
|
418
|
-
interface AlignNodesOptions extends NodeRectOptions {
|
|
419
|
-
/**
|
|
420
|
-
* What to align to: the selection bounding box (default) or a fixed rectangle.
|
|
421
|
-
* Locked nodes never move but still count towards the selection bounds, so they act as anchors.
|
|
422
|
-
*/
|
|
423
|
-
to?: 'selection' | Rect;
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Aligns nodes to a shared edge or centre line of their bounding box (Freeform's
|
|
427
|
-
* Align Left / Center / Right / Top / Middle / Bottom). Needs at least two nodes unless
|
|
428
|
-
* `options.to` is a rectangle. Locked nodes are not moved.
|
|
429
|
-
*/
|
|
430
|
-
declare function alignNodes(nodes: CanvasNode[], ids: Iterable<string>, edge: AlignEdge, options?: AlignNodesOptions): CanvasNodeUpdate[];
|
|
431
|
-
interface DistributeNodesOptions extends NodeRectOptions {
|
|
432
|
-
/** Explicit gap between neighbours for `gaps` mode. Default: spread evenly between the outer nodes. */
|
|
433
|
-
gap?: number;
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* Distributes nodes along an axis (Freeform's Distribute Horizontally / Vertically / Evenly).
|
|
437
|
-
* The outermost nodes stay put and the others are spaced with equal gaps (`gaps`, default)
|
|
438
|
-
* or equally spaced centres (`centres`). Needs at least three nodes (two with an explicit
|
|
439
|
-
* `gap`). Locked nodes keep their place in the order but are not moved.
|
|
440
|
-
*/
|
|
441
|
-
declare function distributeNodes(nodes: CanvasNode[], ids: Iterable<string>, axis: DistributeAxis, mode?: DistributeMode, options?: DistributeNodesOptions): CanvasNodeUpdate[];
|
|
442
|
-
interface MatchSizeOptions extends NodeRectOptions {
|
|
443
|
-
/**
|
|
444
|
-
* Size source: the `largest` (default) or `smallest` node, the `first` id given,
|
|
445
|
-
* or a specific node id.
|
|
446
|
-
*/
|
|
447
|
-
reference?: 'largest' | 'smallest' | 'first' | {
|
|
448
|
-
id: string;
|
|
449
|
-
};
|
|
450
|
-
/** Keep each node's centre in place instead of its top-left corner (default `false`). */
|
|
451
|
-
keepCentre?: boolean;
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
|
-
* Makes nodes the same width, height or both (Freeform's Make Same Size). Returns size
|
|
455
|
-
* updates (plus position updates with `keepCentre`). Locked nodes are not resized but can
|
|
456
|
-
* be the reference.
|
|
457
|
-
*/
|
|
458
|
-
declare function matchSize(nodes: CanvasNode[], ids: Iterable<string>, dimension: SizeDimension, options?: MatchSizeOptions): CanvasNodeUpdate[];
|
|
459
|
-
/** Z-order operation. */
|
|
460
|
-
type ZOrderOperation = 'bringForward' | 'sendBackward' | 'bringToFront' | 'sendToBack';
|
|
461
|
-
/**
|
|
462
|
-
* Restacks nodes (Bring Forward / Send Backward / Bring to Front / Send to Back).
|
|
463
|
-
*
|
|
464
|
-
* Both SvelteFlow and React Flow stack nodes by `zIndex` (missing = 0) and, for equal
|
|
465
|
-
* `zIndex`, by array order. This computes that effective order for the siblings that share
|
|
466
|
-
* the targets' parent, applies the operation, and returns `zIndex` updates assigning each
|
|
467
|
-
* sibling its new rank. The array order is left alone, because xyflow requires parents to
|
|
468
|
-
* precede their children. Locked nodes are not restacked. "Forward" moves past the next
|
|
469
|
-
* sibling the node overlaps, falling back to the next sibling when nothing overlaps.
|
|
470
|
-
*/
|
|
471
|
-
declare function reorderNodes(nodes: CanvasNode[], ids: Iterable<string>, operation: ZOrderOperation, options?: NodeRectOptions): CanvasNodeUpdate[];
|
|
472
|
-
/**
|
|
473
|
-
* Applies `CanvasNodeUpdate`s to a node array, returning a new array. Unchanged nodes keep
|
|
474
|
-
* their identity. Size updates set `width` / `height` and rewrite pixel sizes already present
|
|
475
|
-
* in `style` (string or object). An existing `measured` size is updated too, so geometry
|
|
476
|
-
* helpers see the new size before xyflow re-measures the node.
|
|
477
|
-
*/
|
|
478
|
-
declare function applyNodeUpdates<TNode extends CanvasNode>(nodes: TNode[], updates: CanvasNodeUpdate[]): TNode[];
|
|
479
|
-
/**
|
|
480
|
-
* Inverse of a set of updates against the current nodes, for undo. Restores the previous
|
|
481
|
-
* position / size / zIndex of every node an update touches.
|
|
482
|
-
*/
|
|
483
|
-
declare function invertNodeUpdates(nodes: CanvasNode[], updates: CanvasNodeUpdate[]): CanvasNodeUpdate[];
|
|
484
|
-
|
|
485
333
|
/**
|
|
486
334
|
* A guide line to render while dragging, in flow coordinates.
|
|
487
335
|
* `edge` and `centre` guides are alignment lines; `spacing` guides mark equal gaps.
|
|
336
|
+
* `measure` lines (with a distance `label`) and dashed `extension` lines come from the
|
|
337
|
+
* distance measuring helpers (`measureBetween`, `measureSelection`).
|
|
488
338
|
*/
|
|
489
339
|
interface GuideLine {
|
|
490
340
|
orientation: 'vertical' | 'horizontal';
|
|
491
|
-
kind: 'edge' | 'centre' | 'spacing';
|
|
341
|
+
kind: 'edge' | 'centre' | 'spacing' | 'measure' | 'extension';
|
|
492
342
|
x1: number;
|
|
493
343
|
y1: number;
|
|
494
344
|
x2: number;
|
|
495
345
|
y2: number;
|
|
346
|
+
/** Text drawn at the middle of the line (measuring distances). */
|
|
347
|
+
label?: string;
|
|
496
348
|
}
|
|
349
|
+
/**
|
|
350
|
+
* Snaps `value` to a grid with the given `spacing` and `origin`. A spacing of 0 or less
|
|
351
|
+
* (or a non-finite one) leaves the value unchanged.
|
|
352
|
+
*
|
|
353
|
+
* Ported from vectorcraft-main/crates/geom/src/snap.rs (MIT OR Apache-2.0, © ArtCraft Team
|
|
354
|
+
* and contributors). See THIRD_PARTY_NOTICES.md.
|
|
355
|
+
*/
|
|
356
|
+
declare function snapToGrid(value: number, spacing: number, origin?: number): number;
|
|
497
357
|
interface SnapGuidesOptions {
|
|
498
358
|
/** Current viewport zoom; the threshold is in screen pixels and divided by it (default 1). */
|
|
499
359
|
zoom?: number;
|
|
@@ -505,6 +365,13 @@ interface SnapGuidesOptions {
|
|
|
505
365
|
centres?: boolean;
|
|
506
366
|
/** Snap to equal spacing between neighbouring shapes in the same row / column (default `true`). */
|
|
507
367
|
spacing?: boolean;
|
|
368
|
+
/**
|
|
369
|
+
* Grid spacing in flow units (default 0, off). An axis that does not snap to a shape snaps
|
|
370
|
+
* its top-left (drag) or moving edge (resize) to the grid; grid snaps draw no guides.
|
|
371
|
+
*/
|
|
372
|
+
gridSize?: number;
|
|
373
|
+
/** Grid origin in flow units (default `{ x: 0, y: 0 }`). */
|
|
374
|
+
gridOrigin?: XYPosition;
|
|
508
375
|
}
|
|
509
376
|
interface SnapResult {
|
|
510
377
|
/** Snapped top-left of the moving rectangle. */
|
|
@@ -513,6 +380,7 @@ interface SnapResult {
|
|
|
513
380
|
offset: XYPosition;
|
|
514
381
|
/** Guide segments to draw for the snap that was applied. */
|
|
515
382
|
guides: GuideLine[];
|
|
383
|
+
/** Whether x snapped to a shape (grid snaps do not count). */
|
|
516
384
|
snappedX: boolean;
|
|
517
385
|
snappedY: boolean;
|
|
518
386
|
}
|
|
@@ -739,31 +607,498 @@ declare function fitViewportToNodes(nodes: CanvasNode[], size: {
|
|
|
739
607
|
}, ids?: Iterable<string>, options?: FitViewportOptions & NodeRectOptions): CanvasViewport | null;
|
|
740
608
|
|
|
741
609
|
/**
|
|
742
|
-
*
|
|
610
|
+
* Polygon boolean operations (union, intersection, difference, xor and divide) on
|
|
611
|
+
* multi-polygons with holes.
|
|
612
|
+
*
|
|
613
|
+
* Algorithm (overlay + winding classification):
|
|
614
|
+
* 1. Every input edge is collected into one segment set. Vertices are merged through a
|
|
615
|
+
* tolerance-aware point pool, so points closer than `epsilon` become one vertex.
|
|
616
|
+
* 2. Segments are split at every crossing, T-junction and collinear overlap until no two
|
|
617
|
+
* segments cross (a planar arrangement). Splitting is repeated because snapping a new
|
|
618
|
+
* vertex can move a segment by up to `epsilon`.
|
|
619
|
+
* 3. Coincident segments (shared edges) are merged, keeping for every operand the signed
|
|
620
|
+
* number of its edges that run along the segment.
|
|
621
|
+
* 4. For every segment the winding number of each operand on its right side is computed
|
|
622
|
+
* with a ray cast from the segment midpoint (the segment itself excluded), and the left
|
|
623
|
+
* side follows from the signed multiplicities. The fill rule turns windings into
|
|
624
|
+
* inside / outside flags and the operation decides whether each side is in the result.
|
|
625
|
+
* 5. Segments with the result on exactly one side are kept, oriented with the result on
|
|
626
|
+
* their left, and traced into rings (taking the sharpest left turn at shared vertices,
|
|
627
|
+
* so rings that touch at a vertex stay separate simple rings). Rings with a positive
|
|
628
|
+
* signed area are outer rings; negative ones are holes, assigned to the smallest outer
|
|
629
|
+
* ring that contains them.
|
|
630
|
+
*
|
|
631
|
+
* Handles shared edges, touching vertices, collinear overlaps, holes, nested and disjoint
|
|
632
|
+
* inputs and self-intersecting input rings (resolved by the operand's fill rule).
|
|
633
|
+
*
|
|
634
|
+
* Limits: the overlay is O(n²) in the number of edges (pruned by a sweep on x), which is
|
|
635
|
+
* comfortable for canvas shapes (thousands of edges) but not for GIS-scale data. Features
|
|
636
|
+
* narrower than `epsilon` collapse. Coordinates must be finite.
|
|
743
637
|
*/
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
638
|
+
|
|
639
|
+
/** A closed ring of points. The closing point may be repeated or omitted. */
|
|
640
|
+
type PolygonRing = Point[];
|
|
641
|
+
/** A polygon: the outer ring followed by its holes. */
|
|
642
|
+
type PolygonWithHoles = PolygonRing[];
|
|
643
|
+
/** A set of polygons. */
|
|
644
|
+
type MultiPolygon = PolygonWithHoles[];
|
|
645
|
+
/** SVG fill rule used to decide which areas of a ring set are inside. */
|
|
646
|
+
type PolygonFillRule = 'nonzero' | 'evenodd';
|
|
647
|
+
/** Boolean operations. `xor` is Freeform's Exclude. */
|
|
648
|
+
type PolygonBooleanOperation = 'union' | 'intersection' | 'difference' | 'xor';
|
|
649
|
+
/**
|
|
650
|
+
* A raw ring set with a fill rule (e.g. flattened SVG path data). Ring orientation is
|
|
651
|
+
* significant for `nonzero`.
|
|
652
|
+
*/
|
|
653
|
+
interface PolygonOperand {
|
|
654
|
+
rings: PolygonRing[];
|
|
655
|
+
fillRule?: PolygonFillRule;
|
|
754
656
|
}
|
|
657
|
+
type PolygonInput = MultiPolygon | PolygonOperand;
|
|
658
|
+
interface PolygonBooleanOptions {
|
|
659
|
+
/**
|
|
660
|
+
* Distance below which points are treated as equal. Defaults to `1e-9` times the
|
|
661
|
+
* largest coordinate magnitude of the inputs (at least `1e-9`).
|
|
662
|
+
*/
|
|
663
|
+
epsilon?: number;
|
|
664
|
+
}
|
|
665
|
+
/** One region of `dividePolygons`, with the indices of the operands that cover it. */
|
|
666
|
+
interface PolygonPiece {
|
|
667
|
+
polygon: PolygonWithHoles;
|
|
668
|
+
operands: number[];
|
|
669
|
+
}
|
|
670
|
+
/** Signed shoelace area of a ring (positive when counter-clockwise in a y-up frame). */
|
|
671
|
+
declare function ringSignedArea(ring: readonly Point[]): number;
|
|
672
|
+
/** Area of a polygon (outer ring minus holes). */
|
|
673
|
+
declare function polygonArea(polygon: PolygonWithHoles): number;
|
|
674
|
+
/** Total area of a multi-polygon (holes subtracted). */
|
|
675
|
+
declare function multiPolygonArea(multi: MultiPolygon): number;
|
|
676
|
+
/** Axis-aligned bounds of a multi-polygon (or ring list), or `null` when empty. */
|
|
677
|
+
declare function multiPolygonBounds(input: MultiPolygon | PolygonRing[]): {
|
|
678
|
+
minX: number;
|
|
679
|
+
minY: number;
|
|
680
|
+
maxX: number;
|
|
681
|
+
maxY: number;
|
|
682
|
+
} | null;
|
|
683
|
+
/**
|
|
684
|
+
* Whether a point is inside a ring set under a fill rule. Points exactly on an edge may
|
|
685
|
+
* report either side.
|
|
686
|
+
*/
|
|
687
|
+
declare function pointInRings(point: Point, rings: readonly (readonly Point[])[], fillRule?: PolygonFillRule): boolean;
|
|
688
|
+
/** Whether a point is inside a multi-polygon (holes excluded). */
|
|
689
|
+
declare function pointInMultiPolygon(point: Point, multi: MultiPolygon): boolean;
|
|
690
|
+
/**
|
|
691
|
+
* Applies a boolean operation to any number of operands.
|
|
692
|
+
* - `union`: covered by any operand.
|
|
693
|
+
* - `intersection`: covered by every operand.
|
|
694
|
+
* - `difference`: the first operand minus all others.
|
|
695
|
+
* - `xor`: covered by an odd number of operands (Exclude).
|
|
696
|
+
*
|
|
697
|
+
* Returns simple rings: outer rings have a positive signed area, holes a negative one.
|
|
698
|
+
* Rings may touch at vertices but never cross.
|
|
699
|
+
*/
|
|
700
|
+
declare function polygonBoolean(operation: PolygonBooleanOperation, operands: PolygonInput[], options?: PolygonBooleanOptions): MultiPolygon;
|
|
701
|
+
declare const unionPolygons: (a: PolygonInput, b: PolygonInput, options?: PolygonBooleanOptions) => MultiPolygon;
|
|
702
|
+
declare const intersectPolygons: (a: PolygonInput, b: PolygonInput, options?: PolygonBooleanOptions) => MultiPolygon;
|
|
703
|
+
declare const subtractPolygons: (a: PolygonInput, b: PolygonInput, options?: PolygonBooleanOptions) => MultiPolygon;
|
|
704
|
+
declare const xorPolygons: (a: PolygonInput, b: PolygonInput, options?: PolygonBooleanOptions) => MultiPolygon;
|
|
755
705
|
/**
|
|
756
|
-
*
|
|
757
|
-
* the
|
|
758
|
-
*
|
|
706
|
+
* Splits the overlay of the operands into its distinct regions (Freeform's Divide): every
|
|
707
|
+
* connected area covered by the same set of operands becomes one piece. Pieces are ordered
|
|
708
|
+
* by their operand set, then by size (largest first).
|
|
759
709
|
*/
|
|
760
|
-
declare
|
|
710
|
+
declare function dividePolygons(operands: PolygonInput[], options?: PolygonBooleanOptions): PolygonPiece[];
|
|
711
|
+
|
|
761
712
|
/**
|
|
762
|
-
*
|
|
763
|
-
*
|
|
764
|
-
* `Mod` is ⌘ or Ctrl.
|
|
713
|
+
* Shape geometry: shape descriptions (rect, rounded rect, ellipse, regular polygon, star and
|
|
714
|
+
* SVG path data) to polygons, SVG path parsing / flattening, and polygons back to path data.
|
|
765
715
|
*/
|
|
766
|
-
|
|
716
|
+
|
|
717
|
+
/** Paint shared by every shape kind. Colours are any CSS colour. */
|
|
718
|
+
interface ShapePaint {
|
|
719
|
+
fill?: string;
|
|
720
|
+
stroke?: string;
|
|
721
|
+
strokeWidth?: number;
|
|
722
|
+
opacity?: number;
|
|
723
|
+
}
|
|
724
|
+
interface ShapeBase extends ShapePaint {
|
|
725
|
+
/** Clockwise rotation in degrees (on a y-down canvas) about the centre of the node box. */
|
|
726
|
+
rotation?: number;
|
|
727
|
+
}
|
|
728
|
+
/** Rectangle filling the node box, optionally with rounded corners. */
|
|
729
|
+
interface RectShape extends ShapeBase {
|
|
730
|
+
kind: 'rect';
|
|
731
|
+
/** One radius, or `[topLeft, topRight, bottomRight, bottomLeft]`. Clamped to fit. */
|
|
732
|
+
cornerRadius?: number | readonly [number, number, number, number];
|
|
733
|
+
}
|
|
734
|
+
/** Ellipse (circle when the node is square) inscribed in the node box. */
|
|
735
|
+
interface EllipseShape extends ShapeBase {
|
|
736
|
+
kind: 'ellipse';
|
|
737
|
+
}
|
|
738
|
+
/** Regular polygon, stretched so its bounding box fills the node box. */
|
|
739
|
+
interface RegularPolygonShape extends ShapeBase {
|
|
740
|
+
kind: 'polygon';
|
|
741
|
+
/** Number of sides (at least 3, default 6). The first vertex points up. */
|
|
742
|
+
sides?: number;
|
|
743
|
+
}
|
|
744
|
+
/** Star, stretched so its bounding box fills the node box. */
|
|
745
|
+
interface StarShape extends ShapeBase {
|
|
746
|
+
kind: 'star';
|
|
747
|
+
/** Number of points (at least 3, default 5). The first point points up. */
|
|
748
|
+
points?: number;
|
|
749
|
+
/** Inner radius as a fraction of the outer radius (default 0.5). */
|
|
750
|
+
innerRadius?: number;
|
|
751
|
+
}
|
|
752
|
+
/** Arbitrary SVG path data. */
|
|
753
|
+
interface PathShape extends ShapeBase {
|
|
754
|
+
kind: 'path';
|
|
755
|
+
d: string;
|
|
756
|
+
/**
|
|
757
|
+
* `[minX, minY, width, height]` of the path's coordinate space, scaled to the node box.
|
|
758
|
+
* Without it the path coordinates are node-local pixels.
|
|
759
|
+
*/
|
|
760
|
+
viewBox?: readonly [number, number, number, number];
|
|
761
|
+
/** Fill rule (default `nonzero`, as in SVG). */
|
|
762
|
+
fillRule?: PolygonFillRule;
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* Shape description stored on a node as `data.shape`. Geometry is relative to the node
|
|
766
|
+
* box (`0,0` to `width,height`), so resizing the node resizes the shape.
|
|
767
|
+
*/
|
|
768
|
+
type ShapeDescription = RectShape | EllipseShape | RegularPolygonShape | StarShape | PathShape;
|
|
769
|
+
type ShapeKind = ShapeDescription['kind'];
|
|
770
|
+
declare const SHAPE_KINDS: readonly ShapeKind[];
|
|
771
|
+
/** Whether a value is a supported shape description. */
|
|
772
|
+
declare function isShapeDescription(value: unknown): value is ShapeDescription;
|
|
773
|
+
interface ShapeSize {
|
|
774
|
+
width: number;
|
|
775
|
+
height: number;
|
|
776
|
+
}
|
|
777
|
+
interface FlattenOptions {
|
|
778
|
+
/** Maximum distance between a curve and its polyline, in output units (default 0.25). */
|
|
779
|
+
tolerance?: number;
|
|
780
|
+
/** Upper bound on the segments one curve is split into (default 512). */
|
|
781
|
+
maxSegments?: number;
|
|
782
|
+
}
|
|
783
|
+
/** Normalised absolute path command produced by `parseSvgPath`. */
|
|
784
|
+
type PathCommand = {
|
|
785
|
+
type: 'M';
|
|
786
|
+
x: number;
|
|
787
|
+
y: number;
|
|
788
|
+
} | {
|
|
789
|
+
type: 'L';
|
|
790
|
+
x: number;
|
|
791
|
+
y: number;
|
|
792
|
+
} | {
|
|
793
|
+
type: 'C';
|
|
794
|
+
x1: number;
|
|
795
|
+
y1: number;
|
|
796
|
+
x2: number;
|
|
797
|
+
y2: number;
|
|
798
|
+
x: number;
|
|
799
|
+
y: number;
|
|
800
|
+
} | {
|
|
801
|
+
type: 'Q';
|
|
802
|
+
x1: number;
|
|
803
|
+
y1: number;
|
|
804
|
+
x: number;
|
|
805
|
+
y: number;
|
|
806
|
+
} | {
|
|
807
|
+
type: 'A';
|
|
808
|
+
rx: number;
|
|
809
|
+
ry: number;
|
|
810
|
+
rotation: number;
|
|
811
|
+
largeArc: boolean;
|
|
812
|
+
sweep: boolean;
|
|
813
|
+
x: number;
|
|
814
|
+
y: number;
|
|
815
|
+
} | {
|
|
816
|
+
type: 'Z';
|
|
817
|
+
};
|
|
818
|
+
/**
|
|
819
|
+
* Parses SVG path data into absolute `M`, `L`, `C`, `Q`, `A` and `Z` commands. Relative
|
|
820
|
+
* commands, `H` / `V`, smooth curves (`S` / `T`) and implicit repeated commands are
|
|
821
|
+
* normalised. Parsing stops at the first malformed command (as browsers do).
|
|
822
|
+
*/
|
|
823
|
+
declare function parseSvgPath(d: string): PathCommand[];
|
|
824
|
+
/**
|
|
825
|
+
* Flattens SVG path data into closed rings (one per subpath; open subpaths are closed the
|
|
826
|
+
* way SVG fills them). Curves are approximated within `tolerance`.
|
|
827
|
+
*/
|
|
828
|
+
declare function flattenSvgPath(d: string | PathCommand[], options?: FlattenOptions): PolygonRing[];
|
|
829
|
+
/**
|
|
830
|
+
* SVG path data for a shape in node-local pixels (exact curves: arcs for rounded corners
|
|
831
|
+
* and ellipses), plus the fill rule and a `transform` for rotation / path view boxes.
|
|
832
|
+
* Use it to render a shape; use `shapeToPolygon` for geometry.
|
|
833
|
+
*/
|
|
834
|
+
declare function getShapeSvg(shape: ShapeDescription, size: ShapeSize): {
|
|
835
|
+
d: string;
|
|
836
|
+
transform?: string;
|
|
837
|
+
fillRule: PolygonFillRule;
|
|
838
|
+
};
|
|
839
|
+
/** Everything a renderer needs to draw a shape as one SVG `<path>`. */
|
|
840
|
+
interface ShapeRenderData {
|
|
841
|
+
/** SVG `viewBox` (`0 0 width height`): node-local pixels. */
|
|
842
|
+
viewBox: string;
|
|
843
|
+
width: number;
|
|
844
|
+
height: number;
|
|
845
|
+
d: string;
|
|
846
|
+
transform?: string;
|
|
847
|
+
fillRule: PolygonFillRule;
|
|
848
|
+
fill: string;
|
|
849
|
+
stroke: string;
|
|
850
|
+
strokeWidth: number;
|
|
851
|
+
opacity?: number;
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Resolves the SVG drawing of a shape for a node size. Without a size, a path's view box
|
|
855
|
+
* size (or 100x100) is used. Paint defaults: `fill: currentColor`, `stroke: none`,
|
|
856
|
+
* `strokeWidth: 1`.
|
|
857
|
+
*/
|
|
858
|
+
declare function getShapeRenderData(shape: ShapeDescription, size?: Partial<ShapeSize>): ShapeRenderData;
|
|
859
|
+
/**
|
|
860
|
+
* Converts a shape to rings in node-local pixels (rotation applied), flattening curves at
|
|
861
|
+
* `tolerance`. Returns the rings with the fill rule they must be read with.
|
|
862
|
+
*/
|
|
863
|
+
declare function shapeToPolygon(shape: ShapeDescription, size: ShapeSize, options?: FlattenOptions): {
|
|
864
|
+
rings: PolygonRing[];
|
|
865
|
+
fillRule: PolygonFillRule;
|
|
866
|
+
};
|
|
867
|
+
/** Formats a number with at most `precision` decimals, without trailing zeros. */
|
|
868
|
+
declare function formatNumber(value: number, precision?: number): string;
|
|
869
|
+
/**
|
|
870
|
+
* Simplifies a closed ring with Ramer–Douglas–Peucker at `tolerance`. Returns an empty
|
|
871
|
+
* ring when fewer than three points survive.
|
|
872
|
+
*/
|
|
873
|
+
declare function simplifyRing(ring: readonly Point[], tolerance: number): Point[];
|
|
874
|
+
interface PolygonToPathOptions {
|
|
875
|
+
/** Decimal places in the output (default 3). */
|
|
876
|
+
precision?: number;
|
|
877
|
+
/** Ramer–Douglas–Peucker tolerance; `0` (default) keeps every vertex. */
|
|
878
|
+
simplify?: number;
|
|
879
|
+
/** Added to every point before formatting (e.g. to make coordinates node-local). */
|
|
880
|
+
offset?: {
|
|
881
|
+
x: number;
|
|
882
|
+
y: number;
|
|
883
|
+
};
|
|
884
|
+
/**
|
|
885
|
+
* `'lines'` (default) writes every ring as `M`/`L`/`Z`. `'fit'` fits cubic Béziers to each
|
|
886
|
+
* ring (`fitPathData`), so flattened curves come back as smooth `C` curves while sharp
|
|
887
|
+
* corners (turning more than `cornerAngleDeg`) and straight edges stay as they are.
|
|
888
|
+
*/
|
|
889
|
+
curves?: 'lines' | 'fit';
|
|
890
|
+
/** Curve-fitting tolerance in path units for `curves: 'fit'` (default 0.25). */
|
|
891
|
+
curveTolerance?: number;
|
|
892
|
+
/** Corner threshold in degrees for `curves: 'fit'` (default 30). */
|
|
893
|
+
cornerAngleDeg?: number;
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Converts a multi-polygon (or a list of rings) to SVG path data using `M`/`L`/`Z`. Holes
|
|
897
|
+
* keep their opposite orientation, so the path fills correctly with either fill rule.
|
|
898
|
+
*/
|
|
899
|
+
declare function polygonToSvgPath(input: MultiPolygon | PolygonRing[], options?: PolygonToPathOptions): string;
|
|
900
|
+
|
|
901
|
+
/**
|
|
902
|
+
* Shape nodes and Freeform-style shape boolean operations (Unite / Intersect / Subtract /
|
|
903
|
+
* Exclude / Divide) on canvas nodes.
|
|
904
|
+
*
|
|
905
|
+
* A shape node is any node whose `data.shape` is a `ShapeDescription`. Its geometry is
|
|
906
|
+
* relative to the node box, so moving or resizing the node moves / resizes the shape.
|
|
907
|
+
*/
|
|
908
|
+
|
|
909
|
+
/** Data key holding a node's shape description. */
|
|
910
|
+
declare const SHAPE_DATA_KEY = "shape";
|
|
911
|
+
/** Node type suggested for shape nodes (register `ShapeNode` under it). */
|
|
912
|
+
declare const SHAPE_NODE_TYPE = "shape";
|
|
913
|
+
/** Freeform's shape operations. `exclude` is xor; `divide` splits into every region. */
|
|
914
|
+
type ShapeOperation = 'unite' | 'intersect' | 'subtract' | 'exclude' | 'divide';
|
|
915
|
+
declare const SHAPE_OPERATIONS: readonly ShapeOperation[];
|
|
916
|
+
/** Whether a node carries a supported `data.shape`. */
|
|
917
|
+
declare function isShapeNode(node: CanvasNode | undefined | null): boolean;
|
|
918
|
+
/** The node's shape description, or `null`. */
|
|
919
|
+
declare function getNodeShape(node: CanvasNode | undefined | null): ShapeDescription | null;
|
|
920
|
+
interface ShapeNodePolygonOptions extends NodeRectOptions {
|
|
921
|
+
/** Curve flattening tolerance in flow units (default 0.25). */
|
|
922
|
+
tolerance?: number;
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* A shape node's outline in absolute flow coordinates (parent offsets, size and rotation
|
|
926
|
+
* applied), or `null` for non-shape nodes.
|
|
927
|
+
*/
|
|
928
|
+
declare function shapeNodeToPolygon(node: CanvasNode, lookup?: ReadonlyMap<string, CanvasNode>, options?: ShapeNodePolygonOptions): {
|
|
929
|
+
rings: PolygonRing[];
|
|
930
|
+
fillRule: PolygonFillRule;
|
|
931
|
+
} | null;
|
|
932
|
+
/** Why `combineShapeNodes` refused. */
|
|
933
|
+
type CombineShapeNodesRefusal =
|
|
934
|
+
/** A selected shape is locked; locked shapes are never consumed. */
|
|
935
|
+
'locked'
|
|
936
|
+
/** Fewer than two shape nodes were selected. */
|
|
937
|
+
| 'too-few'
|
|
938
|
+
/** The operation leaves nothing (e.g. intersecting shapes that do not overlap). */
|
|
939
|
+
| 'empty';
|
|
940
|
+
interface CombineShapeNodesOptions extends ShapeNodePolygonOptions {
|
|
941
|
+
/**
|
|
942
|
+
* Which shape's node style and data the result inherits: `bottom` (default, like
|
|
943
|
+
* Freeform: the back-most shape), `top`, `first` (first id passed), or a node id.
|
|
944
|
+
* Divide pieces always take the style of the top-most shape covering them.
|
|
945
|
+
*/
|
|
946
|
+
styleFrom?: 'bottom' | 'top' | 'first' | {
|
|
947
|
+
id: string;
|
|
948
|
+
};
|
|
949
|
+
/** Id factory for new nodes (default `crypto.randomUUID`, with a counter fallback). */
|
|
950
|
+
createId?: (index: number) => string;
|
|
951
|
+
/** Node `type` for the new nodes (default: the style source's type). */
|
|
952
|
+
nodeType?: string;
|
|
953
|
+
/** Decimal places in the path data (default 3). */
|
|
954
|
+
precision?: number;
|
|
955
|
+
/** Ramer–Douglas–Peucker simplification tolerance for the result (default 0, off). */
|
|
956
|
+
simplify?: number;
|
|
957
|
+
/**
|
|
958
|
+
* How the result's outline is written: `'fit'` (default) fits smooth cubic curves to the
|
|
959
|
+
* flattened result, so booleans of curved shapes stay curved (sharp corners and straight
|
|
960
|
+
* edges are kept); `'lines'` writes the polygon as straight segments.
|
|
961
|
+
*/
|
|
962
|
+
curves?: 'lines' | 'fit';
|
|
963
|
+
/** Curve-fitting tolerance in flow units for `curves: 'fit'` (default: `tolerance`, 0.25). */
|
|
964
|
+
curveTolerance?: number;
|
|
965
|
+
/** Corner threshold in degrees for `curves: 'fit'` (default 30). */
|
|
966
|
+
cornerAngleDeg?: number;
|
|
967
|
+
/** Point-merge tolerance passed to the boolean engine. */
|
|
968
|
+
epsilon?: number;
|
|
969
|
+
/** Select the new nodes (default `true`). */
|
|
970
|
+
select?: boolean;
|
|
971
|
+
}
|
|
972
|
+
type CombineShapeNodesResult<TNode extends CanvasNode = CanvasNode> = {
|
|
973
|
+
ok: true;
|
|
974
|
+
operation: ShapeOperation;
|
|
975
|
+
/** Ids of the shape nodes consumed by the operation. */
|
|
976
|
+
removeIds: string[];
|
|
977
|
+
/** New path shape node(s): one, or one per region for `divide`. */
|
|
978
|
+
nodes: TNode[];
|
|
979
|
+
} | {
|
|
980
|
+
ok: false;
|
|
981
|
+
operation: ShapeOperation;
|
|
982
|
+
reason: CombineShapeNodesRefusal;
|
|
983
|
+
};
|
|
984
|
+
/**
|
|
985
|
+
* Checks whether `combineShapeNodes` can run, without computing geometry (it cannot
|
|
986
|
+
* predict an `empty` result). Use it to enable menu items.
|
|
987
|
+
*/
|
|
988
|
+
declare function canCombineShapeNodes(nodes: CanvasNode[], ids: Iterable<string>): {
|
|
989
|
+
ok: true;
|
|
990
|
+
shapeIds: string[];
|
|
991
|
+
} | {
|
|
992
|
+
ok: false;
|
|
993
|
+
reason: Exclude<CombineShapeNodesRefusal, 'empty'>;
|
|
994
|
+
};
|
|
995
|
+
/**
|
|
996
|
+
* Freeform-style shape operations on canvas nodes.
|
|
997
|
+
*
|
|
998
|
+
* - Only shape nodes (`data.shape`) among `ids` take part; other selected nodes are ignored.
|
|
999
|
+
* - Refuses (`ok: false`) when a selected shape is locked, when fewer than two shapes are
|
|
1000
|
+
* selected, or when the result is empty. Nothing should be changed on refusal.
|
|
1001
|
+
* - `subtract` removes every other shape from the back-most one; the other operations are
|
|
1002
|
+
* symmetric. `divide` returns one node per distinct region of the overlay.
|
|
1003
|
+
* - Each new node is a `path` shape: its position / size is the result's bounding box and
|
|
1004
|
+
* its path data is node-local with `viewBox = [0, 0, width, height]`, so it scales with
|
|
1005
|
+
* the node. Rotation is baked into the path. Node fields and `data` (other than the
|
|
1006
|
+
* shape geometry, lock state and size) come from the style source.
|
|
1007
|
+
* - When all shapes share a parent, the new nodes keep it; otherwise they are top-level.
|
|
1008
|
+
*
|
|
1009
|
+
* Pure: returns the change; apply it with `applyShapeCombination` (or the arrange
|
|
1010
|
+
* controller's `combineShapes`, which also records one undo step).
|
|
1011
|
+
*/
|
|
1012
|
+
declare function combineShapeNodes<TNode extends CanvasNode>(nodes: TNode[], ids: Iterable<string>, operation: ShapeOperation, options?: CombineShapeNodesOptions): CombineShapeNodesResult<TNode>;
|
|
1013
|
+
/**
|
|
1014
|
+
* Applies a successful `combineShapeNodes` result: removes the consumed nodes and inserts
|
|
1015
|
+
* the new ones at the array index of the first consumed node.
|
|
1016
|
+
* With `deselect` (default `true`) other nodes are deselected when the result is selected.
|
|
1017
|
+
*/
|
|
1018
|
+
declare function applyShapeCombination<TNode extends CanvasNode>(nodes: TNode[], change: {
|
|
1019
|
+
removeIds: Iterable<string>;
|
|
1020
|
+
nodes: TNode[];
|
|
1021
|
+
}, options?: {
|
|
1022
|
+
deselect?: boolean;
|
|
1023
|
+
}): TNode[];
|
|
1024
|
+
/**
|
|
1025
|
+
* Reverses `applyShapeCombination`: removes the created nodes and puts the consumed nodes
|
|
1026
|
+
* back at their original array indices (`previous` is the node array before the change).
|
|
1027
|
+
*/
|
|
1028
|
+
declare function revertShapeCombination<TNode extends CanvasNode>(nodes: TNode[], change: {
|
|
1029
|
+
removeIds: Iterable<string>;
|
|
1030
|
+
nodes: TNode[];
|
|
1031
|
+
}, previous: TNode[]): TNode[];
|
|
1032
|
+
|
|
1033
|
+
/** A resize handle, named like xyflow's `ControlPosition`. */
|
|
1034
|
+
type ResizeHandle = 'top-left' | 'top' | 'top-right' | 'right' | 'bottom-right' | 'bottom' | 'bottom-left' | 'left';
|
|
1035
|
+
declare const RESIZE_HANDLES: readonly ResizeHandle[];
|
|
1036
|
+
/** Which edge of each axis a handle moves: -1 the start (left / top), 1 the end, 0 none. */
|
|
1037
|
+
declare function resizeHandleAxes(handle: ResizeHandle): {
|
|
1038
|
+
x: -1 | 0 | 1;
|
|
1039
|
+
y: -1 | 0 | 1;
|
|
1040
|
+
};
|
|
1041
|
+
/**
|
|
1042
|
+
* The handle a resize from `start` to `next` was made with, from the edges that moved, or
|
|
1043
|
+
* `null` when no edge moved.
|
|
1044
|
+
*/
|
|
1045
|
+
declare function inferResizeHandle(start: Rect, next: Rect, eps?: number): ResizeHandle | null;
|
|
1046
|
+
interface SnapResizeOptions extends Omit<SnapGuidesOptions, 'spacing'> {
|
|
1047
|
+
/**
|
|
1048
|
+
* Keep the input box's aspect ratio. A corner snaps whichever axis is closer to a target
|
|
1049
|
+
* and the other follows; a side scales the other axis about its centre.
|
|
1050
|
+
*/
|
|
1051
|
+
keepAspectRatio?: boolean;
|
|
1052
|
+
/** Smallest width a snap may leave (default: anything above 0). */
|
|
1053
|
+
minWidth?: number;
|
|
1054
|
+
/** Smallest height a snap may leave (default: anything above 0). */
|
|
1055
|
+
minHeight?: number;
|
|
1056
|
+
}
|
|
1057
|
+
interface SnapResizeResult {
|
|
1058
|
+
/** The snapped box. */
|
|
1059
|
+
rect: Rect;
|
|
1060
|
+
/** Guide segments for the shape snaps that were applied (grid snaps draw none). */
|
|
1061
|
+
guides: GuideLine[];
|
|
1062
|
+
/** Whether the moving x edge snapped to a shape. */
|
|
1063
|
+
snappedX: boolean;
|
|
1064
|
+
/** Whether the moving y edge snapped to a shape. */
|
|
1065
|
+
snappedY: boolean;
|
|
1066
|
+
/** Whether `rect` differs from the input. */
|
|
1067
|
+
changed: boolean;
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Snaps a resize of the axis-aligned box `rect` made with `handle` against `targets`. The
|
|
1071
|
+
* opposite edge (side handles) or corner (corner handles) stays fixed:
|
|
1072
|
+
*
|
|
1073
|
+
* - A **side** handle snaps its one moving edge to the nearest target edge or centre within
|
|
1074
|
+
* `threshold` screen pixels.
|
|
1075
|
+
* - A **corner** handle snaps x and y independently (unless `keepAspectRatio`).
|
|
1076
|
+
* - A snap that would collapse or flip the box (or go below `minWidth` / `minHeight`) is
|
|
1077
|
+
* rejected; the next nearest target is tried, else the edge stays where it was dragged.
|
|
1078
|
+
* - With `gridSize`, an axis without a shape snap snaps its moving edge to the grid.
|
|
1079
|
+
*
|
|
1080
|
+
* Returns the snapped box and the guides to draw (same shape as drag snapping).
|
|
1081
|
+
*/
|
|
1082
|
+
declare function snapResize(rect: Rect, handle: ResizeHandle, targets: Rect[] | GuideIndex, options?: SnapResizeOptions): SnapResizeResult;
|
|
1083
|
+
interface SnapNodeResizeOptions extends SnapResizeOptions, NodeRectOptions {
|
|
1084
|
+
/** Index from `createNodeGuideIndex(nodes, [id])`, reused across resize frames. */
|
|
1085
|
+
index?: GuideIndex;
|
|
1086
|
+
}
|
|
1087
|
+
interface SnapNodeResizeResult extends SnapResizeResult {
|
|
1088
|
+
/** Position / size update for the node (parent-relative position), or none. */
|
|
1089
|
+
updates: CanvasNodeUpdate[];
|
|
1090
|
+
}
|
|
1091
|
+
/**
|
|
1092
|
+
* Snaps a node that is being resized. `rect` is the node's proposed absolute box (e.g. from
|
|
1093
|
+
* a resize event) and `handle` the handle being dragged. Locked nodes are never snapped.
|
|
1094
|
+
* The node itself and its descendants are not snap targets.
|
|
1095
|
+
*/
|
|
1096
|
+
declare function snapNodeResize(nodes: CanvasNode[], id: string, rect: Rect, handle: ResizeHandle, options?: SnapNodeResizeOptions): SnapNodeResizeResult;
|
|
1097
|
+
/**
|
|
1098
|
+
* Absolute box of a node while it is being resized: flow libraries write the new size to
|
|
1099
|
+
* `width` / `height` before the DOM is re-measured, so those win over `measured` here.
|
|
1100
|
+
*/
|
|
1101
|
+
declare function getResizingNodeRect(node: CanvasNode, lookup: ReadonlyMap<string, CanvasNode>, options?: NodeRectOptions): Rect;
|
|
767
1102
|
|
|
768
1103
|
/** Minimal history surface (`HistoryManager` satisfies it). */
|
|
769
1104
|
interface ArrangeHistoryTarget {
|
|
@@ -782,15 +1117,27 @@ interface CanvasArrangeControllerOptions<TNode extends CanvasNode = CanvasNode>
|
|
|
782
1117
|
guides?: Omit<SnapGuidesOptions, 'zoom'>;
|
|
783
1118
|
/** Turns drag snapping off while keeping the arrange actions (default `true`). */
|
|
784
1119
|
snapping?: boolean;
|
|
1120
|
+
/** Turns resize snapping off (default: follows `snapping`). */
|
|
1121
|
+
resizeSnapping?: boolean;
|
|
1122
|
+
/** Resize options passed to `snapResize` (`keepAspectRatio`, `minWidth`, `minHeight`). */
|
|
1123
|
+
resize?: {
|
|
1124
|
+
keepAspectRatio?: boolean;
|
|
1125
|
+
minWidth?: number;
|
|
1126
|
+
minHeight?: number;
|
|
1127
|
+
};
|
|
785
1128
|
/** Size resolution for unmeasured nodes. */
|
|
786
1129
|
rectOptions?: NodeRectOptions;
|
|
787
1130
|
/** Called whenever the guide segments change (set while dragging, cleared on drop). */
|
|
788
1131
|
onGuidesChange?: (guides: GuideLine[]) => void;
|
|
789
1132
|
}
|
|
790
|
-
/**
|
|
1133
|
+
/**
|
|
1134
|
+
* A React Flow / SvelteFlow style node change; only `position` changes are inspected.
|
|
1135
|
+
* `id` is optional because a batch can contain changes without one (React Flow's
|
|
1136
|
+
* `add` change carries an `item` instead), so `NodeChange[]` must be accepted as is.
|
|
1137
|
+
*/
|
|
791
1138
|
interface PositionChangeLike {
|
|
792
1139
|
type: string;
|
|
793
|
-
id
|
|
1140
|
+
id?: string;
|
|
794
1141
|
position?: XYPosition;
|
|
795
1142
|
dragging?: boolean;
|
|
796
1143
|
[key: string]: any;
|
|
@@ -815,6 +1162,20 @@ declare function createCanvasArrangeController<TNode extends CanvasNode = Canvas
|
|
|
815
1162
|
unlock: (ids?: Iterable<string>) => string[];
|
|
816
1163
|
toggleLock(ids?: Iterable<string>): string[];
|
|
817
1164
|
isLocked: (id: string) => boolean;
|
|
1165
|
+
/**
|
|
1166
|
+
* Freeform shape operation (Unite / Intersect / Subtract / Exclude / Divide) on the
|
|
1167
|
+
* shape nodes among `ids` (default: the selection). Replaces them with the result as
|
|
1168
|
+
* one undoable step. Refuses without changing anything when a selected shape is
|
|
1169
|
+
* locked, fewer than two shapes are selected, or the result is empty.
|
|
1170
|
+
*/
|
|
1171
|
+
combineShapes(operation: ShapeOperation, ids?: Iterable<string>, combineOptions?: CombineShapeNodesOptions): CombineShapeNodesResult<TNode>;
|
|
1172
|
+
unite: (ids?: Iterable<string>, o?: CombineShapeNodesOptions) => CombineShapeNodesResult<TNode>;
|
|
1173
|
+
intersect: (ids?: Iterable<string>, o?: CombineShapeNodesOptions) => CombineShapeNodesResult<TNode>;
|
|
1174
|
+
subtract: (ids?: Iterable<string>, o?: CombineShapeNodesOptions) => CombineShapeNodesResult<TNode>;
|
|
1175
|
+
exclude: (ids?: Iterable<string>, o?: CombineShapeNodesOptions) => CombineShapeNodesResult<TNode>;
|
|
1176
|
+
divide: (ids?: Iterable<string>, o?: CombineShapeNodesOptions) => CombineShapeNodesResult<TNode>;
|
|
1177
|
+
/** Whether the shape operations can run on `ids` (default: the selection). */
|
|
1178
|
+
canCombineShapes: (ids?: Iterable<string>) => boolean;
|
|
818
1179
|
/**
|
|
819
1180
|
* Runs a shortcut action. Scene actions are not handled here (see the scenes store);
|
|
820
1181
|
* returns `false` for them and for unknown actions.
|
|
@@ -834,9 +1195,179 @@ declare function createCanvasArrangeController<TNode extends CanvasNode = Canvas
|
|
|
834
1195
|
* A batch without a dragging position change ends the drag and clears the guides.
|
|
835
1196
|
*/
|
|
836
1197
|
snapPositionChanges<TChange extends PositionChangeLike>(changes: TChange[]): TChange[];
|
|
837
|
-
/**
|
|
1198
|
+
/**
|
|
1199
|
+
* Starts resize snapping for node `id`: records its box (to tell which handle is
|
|
1200
|
+
* dragged) and caches the snap targets. Optional: `resize` starts lazily.
|
|
1201
|
+
*/
|
|
1202
|
+
beginResize(id: string): void;
|
|
1203
|
+
/**
|
|
1204
|
+
* Snaps node `id` as currently sized in `getNodes()` (call it after the flow wrote the
|
|
1205
|
+
* new size, e.g. SvelteFlow's `NodeResizer` `onResize`, deferred by a microtask) and
|
|
1206
|
+
* writes the snapped box back through `setNodes` (not recorded in history). `handle`
|
|
1207
|
+
* defaults to the one inferred from the edges that moved since `beginResize`. A locked
|
|
1208
|
+
* node is restored to its starting box.
|
|
1209
|
+
*/
|
|
1210
|
+
resize(id: string, handle?: ResizeHandle): SnapNodeResizeResult | null;
|
|
1211
|
+
/**
|
|
1212
|
+
* Ends resize snapping: clears guides and re-applies the last snapped box if the flow
|
|
1213
|
+
* wrote the raw pointer size afterwards.
|
|
1214
|
+
*/
|
|
1215
|
+
endResize(): void;
|
|
1216
|
+
/**
|
|
1217
|
+
* React Flow style: snaps the `dimensions` (and matching `position`) changes a
|
|
1218
|
+
* `NodeResizer` emits in an `onNodesChange` batch and updates `guides`. The resize-end
|
|
1219
|
+
* change (`resizing: false`) carries the raw pointer size, so the last snapped size is
|
|
1220
|
+
* kept. Resize changes of locked nodes are dropped. Returns the (possibly new) changes.
|
|
1221
|
+
*/
|
|
1222
|
+
snapResizeChanges<TChange extends PositionChangeLike>(changes: TChange[]): TChange[];
|
|
1223
|
+
/**
|
|
1224
|
+
* Clears guides and the cached snap targets. Call it from the flow's drag-stop
|
|
1225
|
+
* handler: flow libraries write the raw pointer position when a drag ends, so the
|
|
1226
|
+
* last snapped positions from `drag` are written back here.
|
|
1227
|
+
*/
|
|
838
1228
|
endDrag(): void;
|
|
839
1229
|
};
|
|
840
1230
|
type CanvasArrangeController<TNode extends CanvasNode = CanvasNode> = ReturnType<typeof createCanvasArrangeController<TNode>>;
|
|
841
1231
|
|
|
842
|
-
|
|
1232
|
+
/**
|
|
1233
|
+
* A measuring line in flow coordinates. `measure` lines carry a `label` (the distance);
|
|
1234
|
+
* `extension` lines are dashed, unlabelled lines that carry a gap over to the measured box
|
|
1235
|
+
* when the gap line passes beside it.
|
|
1236
|
+
*/
|
|
1237
|
+
interface MeasureGuide extends GuideLine {
|
|
1238
|
+
kind: 'measure' | 'extension';
|
|
1239
|
+
/** The distance as shown on the label (`measure` lines only). */
|
|
1240
|
+
label?: string;
|
|
1241
|
+
}
|
|
1242
|
+
/** A distance as shown on a label: absolute value, up to two decimals, no trailing zeros. */
|
|
1243
|
+
declare function measureLabel(distance: number): string;
|
|
1244
|
+
/**
|
|
1245
|
+
* Distance lines from box `a` (the selection) to box `b` (the hovered shape):
|
|
1246
|
+
*
|
|
1247
|
+
* - **One inside the other**: from the inner box to each edge of the outer one, along the
|
|
1248
|
+
* inner box's centre lines (the same lines either way round).
|
|
1249
|
+
* - **Overlapping**: between the matching edges (left to left, right to right, ...).
|
|
1250
|
+
* - **Apart**: the horizontal and/or vertical gap, across the shared rows / columns, or from
|
|
1251
|
+
* the middle of `a` with a dashed `extension` line to `b` when the gap line passes beside it.
|
|
1252
|
+
* Touching boxes have no gap to draw.
|
|
1253
|
+
*/
|
|
1254
|
+
declare function measureBetween(a: Rect, b: Rect): MeasureGuide[];
|
|
1255
|
+
/**
|
|
1256
|
+
* Distance lines from box `a` to an infinite guide line (`vertical` at x = `at`, otherwise
|
|
1257
|
+
* horizontal at y = `at`): to the nearer side, or to both sides when the line crosses the box.
|
|
1258
|
+
*/
|
|
1259
|
+
declare function measureToLine(a: Rect, orientation: 'vertical' | 'horizontal', at: number): MeasureGuide[];
|
|
1260
|
+
interface MeasureSelectionResult {
|
|
1261
|
+
/** Measuring lines in flow coordinates. */
|
|
1262
|
+
guides: MeasureGuide[];
|
|
1263
|
+
/** The box measured to (to outline), or `null` when nothing is measured. */
|
|
1264
|
+
target: Rect | null;
|
|
1265
|
+
/** The selection's bounding box, or `null` without a selection. */
|
|
1266
|
+
selection: Rect | null;
|
|
1267
|
+
}
|
|
1268
|
+
interface MeasureSelectionOptions extends NodeRectOptions {
|
|
1269
|
+
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Alt-hover measuring on canvas nodes: from the bounding box of `selectedIds` (absolute,
|
|
1272
|
+
* union of several nodes) to the hovered node. Hovering the selection itself, or nothing
|
|
1273
|
+
* (`hoveredId` null), measures to the selection's parent (`parentId`) when it has one;
|
|
1274
|
+
* a top-level selection then measures nothing. Hidden nodes are ignored.
|
|
1275
|
+
*/
|
|
1276
|
+
declare function measureSelection(nodes: CanvasNode[], selectedIds: Iterable<string>, hoveredId: string | null | undefined, options?: MeasureSelectionOptions): MeasureSelectionResult;
|
|
1277
|
+
/**
|
|
1278
|
+
* Whether the measuring modifier (Alt / Option) is held after a keyboard or pointer event.
|
|
1279
|
+
* `keyup` of Alt releases it; `keydown` of Alt or any event with `altKey` holds it.
|
|
1280
|
+
*/
|
|
1281
|
+
declare function isMeasureModifierHeld(event: {
|
|
1282
|
+
type?: string;
|
|
1283
|
+
key?: string;
|
|
1284
|
+
altKey?: boolean;
|
|
1285
|
+
} | null | undefined): boolean;
|
|
1286
|
+
|
|
1287
|
+
/**
|
|
1288
|
+
* Least-squares cubic Bézier fitting of point sequences (Schneider-style: fit one cubic with
|
|
1289
|
+
* fixed end tangents, reparameterise with Newton steps, split at the worst point), with
|
|
1290
|
+
* corner preservation by a turning-angle test.
|
|
1291
|
+
*
|
|
1292
|
+
* Portions ported from vectorcraft-main/crates/pathops/src/fit.rs and
|
|
1293
|
+
* vectorcraft-main/crates/pathops/src/edit.rs (MIT OR Apache-2.0, © ArtCraft Team and
|
|
1294
|
+
* contributors). See THIRD_PARTY_NOTICES.md.
|
|
1295
|
+
*/
|
|
1296
|
+
|
|
1297
|
+
/** One cubic Bézier segment. */
|
|
1298
|
+
interface CubicSegment {
|
|
1299
|
+
p0: Point;
|
|
1300
|
+
p1: Point;
|
|
1301
|
+
p2: Point;
|
|
1302
|
+
p3: Point;
|
|
1303
|
+
}
|
|
1304
|
+
interface FitCubicsOptions {
|
|
1305
|
+
/**
|
|
1306
|
+
* Vertices where the polyline turns by more than this many degrees stay sharp corners
|
|
1307
|
+
* (default 30). Use 180 to smooth through every vertex.
|
|
1308
|
+
*/
|
|
1309
|
+
cornerAngleDeg?: number;
|
|
1310
|
+
/** Treat the points as a closed ring (the last point connects back to the first). */
|
|
1311
|
+
closed?: boolean;
|
|
1312
|
+
}
|
|
1313
|
+
/** Evaluates a cubic segment at `t` ∈ [0, 1]. */
|
|
1314
|
+
declare function cubicPointAt(c: CubicSegment, t: number): Point;
|
|
1315
|
+
/**
|
|
1316
|
+
* Fits a G1-continuous chain of cubics through `points` (an open run) with the unit
|
|
1317
|
+
* tangents `t0` (leaving the first point) and `t1` (arriving at the last point, forward);
|
|
1318
|
+
* both are estimated from the end points when omitted. Every point lies within `tolerance`
|
|
1319
|
+
* of the curve at its fitted parameter.
|
|
1320
|
+
*/
|
|
1321
|
+
declare function fitCubicRun(points: readonly Point[], tolerance: number, t0?: Point, t1?: Point): CubicSegment[];
|
|
1322
|
+
/**
|
|
1323
|
+
* Fits cubic Bézier segments to a polyline (`closed` for a ring), keeping vertices that turn
|
|
1324
|
+
* by more than `cornerAngleDeg` (default 30°) as sharp corners. Each stretch between corners
|
|
1325
|
+
* is fitted Schneider-style so that every input point is within `tolerance` of the result.
|
|
1326
|
+
*
|
|
1327
|
+
* Returns the segments in order (consecutive segments share end points; a closed result ends
|
|
1328
|
+
* where it starts). Fewer than two distinct points give an empty array.
|
|
1329
|
+
*/
|
|
1330
|
+
declare function fitCubics(points: readonly Point[], tolerance: number, options?: FitCubicsOptions): CubicSegment[];
|
|
1331
|
+
/** Whether a cubic is (within `tol`) the straight line from `p0` to `p3`. */
|
|
1332
|
+
declare function isStraightCubic(c: CubicSegment, tol: number): boolean;
|
|
1333
|
+
interface FitPathDataOptions extends FitCubicsOptions {
|
|
1334
|
+
/** Fitting tolerance in path units (default 0.5). */
|
|
1335
|
+
tolerance?: number;
|
|
1336
|
+
/** Decimal places (default 3). */
|
|
1337
|
+
precision?: number;
|
|
1338
|
+
/** Added to every point before formatting. */
|
|
1339
|
+
offset?: {
|
|
1340
|
+
x: number;
|
|
1341
|
+
y: number;
|
|
1342
|
+
};
|
|
1343
|
+
/**
|
|
1344
|
+
* Keep the original polyline when fitting would need more segments than it has edges
|
|
1345
|
+
* (default `true`), so fitting never makes a path heavier.
|
|
1346
|
+
*/
|
|
1347
|
+
noWorse?: boolean;
|
|
1348
|
+
}
|
|
1349
|
+
/** SVG `d` for fitted segments (`L` for straight ones, `C` otherwise). */
|
|
1350
|
+
declare function cubicsToPathData(segments: readonly CubicSegment[], options?: {
|
|
1351
|
+
precision?: number;
|
|
1352
|
+
offset?: {
|
|
1353
|
+
x: number;
|
|
1354
|
+
y: number;
|
|
1355
|
+
};
|
|
1356
|
+
closed?: boolean;
|
|
1357
|
+
straightTolerance?: number;
|
|
1358
|
+
}): string;
|
|
1359
|
+
/**
|
|
1360
|
+
* Fits smooth curves to a polygon ring (closed by default) and returns SVG path data with
|
|
1361
|
+
* `C` curves for smooth stretches, `L` lines for straight ones and sharp corners kept.
|
|
1362
|
+
* Use it for boolean results of curved shapes or to smooth freehand strokes
|
|
1363
|
+
* (`{ closed: false }`, see `fitFreehandPath`).
|
|
1364
|
+
*/
|
|
1365
|
+
declare function fitPathData(ring: readonly Point[], options?: FitPathDataOptions): string;
|
|
1366
|
+
/**
|
|
1367
|
+
* Smooths a freehand stroke (pointer samples) into an open SVG path of cubic curves.
|
|
1368
|
+
* `tolerance` is the largest distance (in the points' units) a sample may be from the
|
|
1369
|
+
* curve (default 1); sharp turns above `cornerAngleDeg` (default 30) stay corners.
|
|
1370
|
+
*/
|
|
1371
|
+
declare function fitFreehandPath(points: readonly Point[], options?: Omit<FitPathDataOptions, 'closed'>): string;
|
|
1372
|
+
|
|
1373
|
+
export { AlignEdge, AlignNodesOptions, type ArrangeHistoryTarget, CONNECTION_LINE_TYPES, CanvasArrangeAction, type CanvasArrangeController, type CanvasArrangeControllerOptions, CanvasClipboardPayload, type CanvasConnectionLineType, CanvasEdge, type CanvasHeightOptions, CanvasLayoutOptions, CanvasNode, CanvasNodeStyle, CanvasNodeUpdate, type CanvasScene, type CanvasScenesOptions, type CanvasScenesState, CanvasScenesStore, type CanvasViewport, type Clock, type CombineShapeNodesOptions, type CombineShapeNodesRefusal, type CombineShapeNodesResult, type ConnectorSnap, type ConnectorSnapOptions, type ConnectorSnapTarget, type CubicSegment, DEFAULT_NODE_HEIGHT, DEFAULT_NODE_WIDTH, DEFAULT_PLACEMENT_GAP, DirectionalDisplacementOptions, DistributeAxis, DistributeMode, DistributeNodesOptions, type EllipseShape, FanOutTrajectoryOptions, type FitCubicsOptions, type FitPathDataOptions, type FitViewportOptions, type FlattenOptions, type GuideIndex, type GuideLine, IncrementalLayoutOptions, ManualClock, MatchSizeOptions, type MeasureGuide, type MeasureSelectionOptions, type MeasureSelectionResult, type MultiNodeTransitionOptions, type MultiPolygon, NodeRectOptions, NodeTransition, type PathCommand, type PathShape, PlaceBesideOptions, Point, type PolygonBooleanOperation, type PolygonBooleanOptions, type PolygonFillRule, type PolygonInput, type PolygonOperand, type PolygonPiece, type PolygonRing, type PolygonToPathOptions, type PolygonWithHoles, Position, type PositionChangeLike, RESIZE_HANDLES, Rect, type RectShape, ReflowDisplacementOptions, type RegularPolygonShape, type ResizeHandle, SHAPE_DATA_KEY, SHAPE_KINDS, SHAPE_NODE_TYPE, SHAPE_OPERATIONS, type SerializedCanvasScenes, type ShapeDescription, type ShapeKind, type ShapeNodePolygonOptions, type ShapeOperation, type ShapePaint, type ShapeRenderData, type ShapeSize, Side, SizeDimension, type SnapGuidesOptions, type SnapNodeDragOptions, type SnapNodeDragResult, type SnapNodeResizeOptions, type SnapNodeResizeResult, type SnapResizeOptions, type SnapResizeResult, type SnapResult, type StarShape, StreamingLayoutManager, type StreamingLayoutManagerOptions, TrajectoryFunction, XYPosition, ZOrderOperation, applyShapeCombination, blendLayout, boundsOf, calculateDagreReflowDisplacement, calculateDirectionalDisplacement, canCombineShapeNodes, canvasHeight, centerNodes, centre, collectDescendantIds, combineShapeNodes, computeNodesBoundingBox, computeSnapGuides, connectedOnly, createBezierTrajectory, createCanvasArrangeController, createCanvasScenesStore, createFanOutTrajectory, createGuideIndex, createNodeGuideIndex, cubicPointAt, cubicsToPathData, defaultEasing, dividePolygons, ensureLayout, estimateCanvasHeight, estimateNodeSize, findConnectorSnap, fitCubicRun, fitCubics, fitFreehandPath, fitPathData, fitViewportToNodes, fitViewportToRect, flattenSvgPath, flowSide, formatNumber, getCenteredNodePosition, getLayoutedNodes, getNodeShape, getResizingNodeRect, getShapeRenderData, getShapeSvg, handlePoint, inferResizeHandle, intersectPolygons, isEventFromTextInput, isMeasureModifierHeld, isShapeDescription, isShapeNode, isStraightCubic, isValidCanvasEdge, isValidCanvasNode, isValidCanvasScene, isValidUrl, layoutBounds, linearPositionTrajectory, linearTrajectory, measureBetween, measureLabel, measureSelection, measureToLine, multiPolygonArea, multiPolygonBounds, nearestHandlePositions, oppositePosition, overlaps, pageHidden, parseCanvasClipboardData, parseCanvasScenes, parseSvgPath, placeBeside, pointInMultiPolygon, pointInRings, polygonArea, polygonBoolean, polygonToSvgPath, positionToSide, realClock, remapPastedNodes, repositionNodesTo, resizeHandleAxes, revertShapeCombination, ringSignedArea, runMultiNodeTransition, serializeCanvasNodes, shapeNodeToPolygon, shapeToPolygon, sideToPosition, simplifyRing, snapNodeDrag, snapNodeResize, snapResize, snapToGrid, subtractPolygons, unionPolygons, withStyleOpacity, xorPolygons };
|