@weasel-js/path-tools 0.0.0-stage → 1.11.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/LICENSE +21 -0
- package/README.md +70 -2
- package/dist/icons.table.d.ts +6 -0
- package/dist/icons.table.js +129 -0
- package/dist/icons.table.js.map +1 -0
- package/dist/icons.table.json +121 -0
- package/dist/index.d.ts +1550 -0
- package/dist/index.js +3900 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -4
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1550 @@
|
|
|
1
|
+
import { PathEditExtension, SnapSource, FeaturePreset, EditableShape, BlendEffect, BendAlongEffect, RepeatAlongEffect, PathNode, Tool, SurfaceContribution, NodeId, PathPaint, BooleanOpResult, BooleansAdapter, BooleanOpOptions, BooleanStrokes, RenderLayer, SceneNode, PathRepresentation, AnchorMarkerShape, EditAnchorsDep, RectPose, AddNodeSpec } from '@weasel-js/core';
|
|
2
|
+
import { DrawCommand } from '@weasel-js/renderer';
|
|
3
|
+
import { AnchorSet, Point, PolygonPath, View, CornerFrame, SoftFalloff, PathConstraintKind, PathConstraint, LengthenMode, Affine, SpiroKind, SegmentType, CornerShape, TrimResult, SpiroPoint, SpiroContour, CornerKeyword } from '@weasel-js/geom';
|
|
4
|
+
import * as _weasel_js_routing from '@weasel-js/routing';
|
|
5
|
+
import { Action, ActionDeps, ToolKeybinding } from '@weasel-js/routing';
|
|
6
|
+
export { ActionParamSchema } from '@weasel-js/routing';
|
|
7
|
+
import { CursorSpec } from '@weasel-js/cursor';
|
|
8
|
+
import { PathWarp, DistortMode, EnvelopeMapping } from '@weasel-js/geom/warp';
|
|
9
|
+
import { VertexWidth, Stroke, HalfWidths } from '@weasel-js/paint';
|
|
10
|
+
import { StrokeEdgeHit, StrokeSide } from '@weasel-js/stroke';
|
|
11
|
+
import { PrefGroup } from '@weasel-js/prefs';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The balance lines path edit can draw over the open path: one per curved
|
|
15
|
+
* segment, from its first handle's tip to its second's, with the grip
|
|
16
|
+
* `balanceHandles` drags at the middle, pressed as `balance:N`.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** Chrome-caps id the balance lines and their grips are drawn and hit-tested
|
|
20
|
+
* under. Off by default. */
|
|
21
|
+
declare const PATH_BALANCE_CHROME_ID = "path-edit.balance";
|
|
22
|
+
/** How the balance lines are drawn. */
|
|
23
|
+
interface PathEditBalanceStyle {
|
|
24
|
+
/** Color of the line between a segment's handle tips and of its grip's rim. */
|
|
25
|
+
color?: string;
|
|
26
|
+
/** Fill of the grip. */
|
|
27
|
+
gripFill?: string;
|
|
28
|
+
/** Radius of the grip, in screen px. Default 4. */
|
|
29
|
+
gripRadiusPx?: number;
|
|
30
|
+
}
|
|
31
|
+
/** Draw commands for `set`'s balance lines and their grips, in screen space. */
|
|
32
|
+
declare function balanceCommands(set: AnchorSet, toScreen: (p: Point) => Point, style?: PathEditBalanceStyle): DrawCommand[];
|
|
33
|
+
/** The balance lines as a path-edit extension: drawn, and their grips
|
|
34
|
+
* pressed, while chrome-caps shows {@link PATH_BALANCE_CHROME_ID}. */
|
|
35
|
+
declare function createBalanceExtension(style?: PathEditBalanceStyle): PathEditExtension;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The curvature comb path edit can draw over the open path.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/** Chrome-caps id the curvature comb is drawn under. Off by default. */
|
|
42
|
+
declare const PATH_COMB_CHROME_ID = "path-edit.comb";
|
|
43
|
+
/** How the curvature comb is drawn. */
|
|
44
|
+
interface PathEditCombOptions {
|
|
45
|
+
/** Tooth length per unit of curvature, in world units: a tooth over a
|
|
46
|
+
* stretch of radius r is `scale / r` long. Default 2000. */
|
|
47
|
+
scale?: number;
|
|
48
|
+
/** Teeth per segment, ends included. Default 24. */
|
|
49
|
+
samplesPerSegment?: number;
|
|
50
|
+
/** Color of the teeth and of the line through their tips. */
|
|
51
|
+
color?: string;
|
|
52
|
+
}
|
|
53
|
+
/** Draw commands for `set`'s curvature comb, in screen space. */
|
|
54
|
+
declare function combCommands(set: AnchorSet, toScreen: (p: Point) => Point, opts?: PathEditCombOptions): DrawCommand[];
|
|
55
|
+
/** The comb as a path-edit extension, drawn while chrome-caps shows
|
|
56
|
+
* {@link PATH_COMB_CHROME_ID}. `options` is read every frame. */
|
|
57
|
+
declare function createCombExtension(options?: () => PathEditCombOptions | undefined): PathEditExtension;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The corner widgets path edit shows on the open path: one inside each corner
|
|
61
|
+
* anchor, at the middle of its cut, pushed a fixed distance further in on
|
|
62
|
+
* screen so that it clears the anchor square at a zero radius. The overlay
|
|
63
|
+
* paints it and the hit-test presses it, as `corner:N`, from this one
|
|
64
|
+
* placement.
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
/** Chrome-caps id the corner widgets are drawn and hit-tested under. On by
|
|
68
|
+
* default. */
|
|
69
|
+
declare const PATH_CORNERS_CHROME_ID = "path-edit.corners";
|
|
70
|
+
/** Screen distance from the middle of a corner's cut to its widget. */
|
|
71
|
+
declare const CORNER_WIDGET_STANDOFF_PX = 14;
|
|
72
|
+
/** The corner anchors of `path` that show a widget. */
|
|
73
|
+
declare function cornerWidgetFrames(path: PolygonPath): CornerFrame[];
|
|
74
|
+
/** How the widgets are drawn. */
|
|
75
|
+
interface CornerWidgetStyle {
|
|
76
|
+
/** Default: path edit's anchor fill. */
|
|
77
|
+
fill?: string;
|
|
78
|
+
/** Default: path edit's anchor stroke. */
|
|
79
|
+
stroke?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The widget of every corner anchor of `path`, in screen space: a small
|
|
83
|
+
* square whose corner toward the anchor is cut in the corner's shape. A
|
|
84
|
+
* corner with no spec draws as round, the shape a drag gives it.
|
|
85
|
+
*/
|
|
86
|
+
declare function cornerWidgetCommands(path: PolygonPath, view: View, style?: CornerWidgetStyle): DrawCommand[];
|
|
87
|
+
/** The corner widgets as a path-edit extension: drawn, and pressed as
|
|
88
|
+
* `corner:N`, while chrome-caps shows {@link PATH_CORNERS_CHROME_ID}. */
|
|
89
|
+
declare function createCornerWidgetsExtension(style?: CornerWidgetStyle): PathEditExtension;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The small marks the path-edit overlay draws for a path's constraints, in
|
|
93
|
+
* screen pixels, and where a click finds them: a letter beside a horizontal
|
|
94
|
+
* or vertical segment, paired strokes beside parallel ones, a foot beside
|
|
95
|
+
* perpendicular ones, ticks across equal ones, a dimension bar beside a fixed
|
|
96
|
+
* length, a pin by a fixed anchor, a ring by coincident ones, a line
|
|
97
|
+
* touching a circle by a tangent one, and a dot on a line by one held on a
|
|
98
|
+
* segment. Marks sit
|
|
99
|
+
* on the inside of the shape, toward the centroid of its anchors, so a click
|
|
100
|
+
* on one lands on the shape rather than on empty canvas.
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
/** Colors for the constraint marks. */
|
|
104
|
+
interface ConstraintGlyphStyle {
|
|
105
|
+
/** A constraint that holds. */
|
|
106
|
+
stroke: string;
|
|
107
|
+
/** One that does not: it conflicts with the others. */
|
|
108
|
+
conflictStroke: string;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Angle snapping for a control-handle drag. */
|
|
112
|
+
interface HandleSnapOptions {
|
|
113
|
+
/** Snap to every multiple of this many degrees. Default 45; 0 turns the
|
|
114
|
+
* steps off and leaves only the opposite handle. */
|
|
115
|
+
stepDeg?: number;
|
|
116
|
+
/** How near, in degrees, the handle must come to an angle to snap. Read
|
|
117
|
+
* by the drag as it starts. Default 6. */
|
|
118
|
+
reachDeg?: number;
|
|
119
|
+
/** Also snap onto the line through the anchor's other handle. Default true. */
|
|
120
|
+
opposite?: boolean;
|
|
121
|
+
}
|
|
122
|
+
/** Options, or a thunk read on every move: null or undefined from it leaves
|
|
123
|
+
* the handle unsnapped. */
|
|
124
|
+
type HandleSnapOptionsInput = HandleSnapOptions | (() => HandleSnapOptions | null | undefined);
|
|
125
|
+
/**
|
|
126
|
+
* A handle drag's angle targets: the multiples of `stepDeg` either side of
|
|
127
|
+
* the handle, and the angle that puts it in line with the anchor's other
|
|
128
|
+
* handle, which the drag brings as `also.anchors`, ahead of a step it ties
|
|
129
|
+
* with. Each draws its line.
|
|
130
|
+
*/
|
|
131
|
+
declare function handleSnapSource(options?: HandleSnapOptionsInput): SnapSource;
|
|
132
|
+
/**
|
|
133
|
+
* Handle snapping as a path-edit extension: each control-handle drag runs a
|
|
134
|
+
* `'handle'` session on the canvas's `snap` dep, in polar coordinates about
|
|
135
|
+
* its anchor, and the handle keeps the length the pointer and the locks give
|
|
136
|
+
* it. A held angle lock holds the angle; a held length lock keeps the length
|
|
137
|
+
* while the angle snaps. The angles come from {@link handleSnapSource}, which
|
|
138
|
+
* `createHandleSnapPreset` registers beside it.
|
|
139
|
+
*/
|
|
140
|
+
declare function createHandleSnapExtension(options?: HandleSnapOptionsInput): PathEditExtension;
|
|
141
|
+
|
|
142
|
+
/** How far soft selection reaches, and how it fades. */
|
|
143
|
+
interface SoftSelectionOptions {
|
|
144
|
+
/** How far along the path the influence reaches, in screen pixels. */
|
|
145
|
+
radiusPx: number;
|
|
146
|
+
/** How the influence fades over the radius. Default `'smooth'`. */
|
|
147
|
+
falloff?: SoftFalloff;
|
|
148
|
+
/** Told each radius the wheel scrubs to, so a host can keep it for the next drag. */
|
|
149
|
+
onRadius?: (radiusPx: number) => void;
|
|
150
|
+
}
|
|
151
|
+
/** Soft selection as a path-edit extension. `options` is read as each anchor
|
|
152
|
+
* drag starts; null or undefined leaves that drag hard. */
|
|
153
|
+
declare function createSoftSelectionExtension(options: () => SoftSelectionOptions | null | undefined): PathEditExtension;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Which way the open path runs, drawn over it: an arrow at the middle of
|
|
157
|
+
* every segment and a ring round each subpath's start anchor.
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
/** Chrome-caps id the direction arrows and start rings are drawn under. Off by default. */
|
|
161
|
+
declare const PATH_DIRECTION_CHROME_ID = "path-edit.direction";
|
|
162
|
+
/** How the direction marks are drawn. */
|
|
163
|
+
interface PathDirectionStyle {
|
|
164
|
+
/** Color of the arrows and the start rings. */
|
|
165
|
+
color?: string;
|
|
166
|
+
/** Length of an arrow, tip to base, in screen pixels. */
|
|
167
|
+
arrowPx?: number;
|
|
168
|
+
/** Radius of a start ring, in screen pixels. */
|
|
169
|
+
ringPx?: number;
|
|
170
|
+
}
|
|
171
|
+
/** Draw commands for `set`'s direction arrows and start rings, in screen space. */
|
|
172
|
+
declare function directionCommands(set: AnchorSet, toScreen: (p: Point) => Point, style?: PathDirectionStyle): DrawCommand[];
|
|
173
|
+
/** The direction marks as a path-edit extension, drawn in `style` while
|
|
174
|
+
* chrome-caps shows {@link PATH_DIRECTION_CHROME_ID}. */
|
|
175
|
+
declare function createDirectionExtension(style?: PathDirectionStyle): PathEditExtension;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* The package's behavior as `<SceneCanvas features>` presets: one per tool
|
|
179
|
+
* family, and `pathTools` for all of them. Each assumes core's `paths`
|
|
180
|
+
* preset, which opens a path for editing.
|
|
181
|
+
*/
|
|
182
|
+
|
|
183
|
+
/** The Simplify brush, a path-edit tool that refits the curve it passes over. */
|
|
184
|
+
declare const simplifyBrushPreset: FeaturePreset;
|
|
185
|
+
/** The `handleLock.angle` and `handleLock.length` toggles. */
|
|
186
|
+
declare const handleLocksPreset: FeaturePreset;
|
|
187
|
+
/**
|
|
188
|
+
* Soft selection: dragging anchors in path edit also moves the anchors near
|
|
189
|
+
* them along the path, by a falloff over `options`' radius, read as each drag
|
|
190
|
+
* starts. The wheel scrubs the radius mid-drag. Null or undefined from
|
|
191
|
+
* `options` leaves a drag hard.
|
|
192
|
+
*/
|
|
193
|
+
declare function createSoftSelectionPreset(options: () => SoftSelectionOptions | null | undefined): FeaturePreset;
|
|
194
|
+
/**
|
|
195
|
+
* Handle snapping: a dragged control handle's angle snaps to steps and to the
|
|
196
|
+
* line through its anchor's other handle, as `options` says. A thunk is read
|
|
197
|
+
* every move, and null or undefined from it leaves the handle unsnapped.
|
|
198
|
+
*/
|
|
199
|
+
declare function createHandleSnapPreset(options?: HandleSnapOptionsInput): FeaturePreset;
|
|
200
|
+
/** Handle snapping every 45°, within 6°, and to the opposite handle. */
|
|
201
|
+
declare const handleSnapPreset: FeaturePreset;
|
|
202
|
+
/** Bridge, on whole paths and on two selected anchors. */
|
|
203
|
+
declare const bridgePreset: FeaturePreset;
|
|
204
|
+
/** `trimPath`, which `useTrimTool` binds. */
|
|
205
|
+
declare const trimPreset: FeaturePreset;
|
|
206
|
+
/** `extendToMeet`, which `useExtendTool` binds. */
|
|
207
|
+
declare const extendPreset: FeaturePreset;
|
|
208
|
+
/** Lengthen, a path-edit tool whose drag on an open end grows or trims the
|
|
209
|
+
* path from that end, and its toggle. */
|
|
210
|
+
declare const lengthenPreset: FeaturePreset;
|
|
211
|
+
/** `smudgeBrush`, which `useSmudgeBrushTool` binds. */
|
|
212
|
+
declare const smudgePreset: FeaturePreset;
|
|
213
|
+
/** Harmonize curvature. */
|
|
214
|
+
declare const harmonizePreset: FeaturePreset;
|
|
215
|
+
/** Anchor selection along the path: grow, shrink, every Nth, corners, smooth
|
|
216
|
+
* anchors, and the complement. */
|
|
217
|
+
declare const anchorSelectionPreset: FeaturePreset;
|
|
218
|
+
/** Resample, which spreads anchors evenly by arc length. */
|
|
219
|
+
declare const resamplePreset: FeaturePreset;
|
|
220
|
+
/** Add extremes, an anchor at each curve's leftmost, rightmost, top, and bottom. */
|
|
221
|
+
declare const addExtremesPreset: FeaturePreset;
|
|
222
|
+
/** The curvature comb over the open path, drawn as `options` says, read every
|
|
223
|
+
* frame. Off until chrome-caps shows `path-edit.comb`. */
|
|
224
|
+
declare function createCurvatureCombPreset(options?: () => PathEditCombOptions | undefined): FeaturePreset;
|
|
225
|
+
/** The curvature comb with its default look. */
|
|
226
|
+
declare const curvatureCombPreset: FeaturePreset;
|
|
227
|
+
/**
|
|
228
|
+
* Balance handles: a line between each curved segment's handle tips with a
|
|
229
|
+
* grip to drag (`balanceHandles`) or double-click (`equalizeHandles`), drawn
|
|
230
|
+
* in `style`. Off until chrome-caps shows `path-edit.balance`. It refines
|
|
231
|
+
* `paths`, so a grip's double-click goes ahead of entering path edit.
|
|
232
|
+
*/
|
|
233
|
+
declare function createBalancePreset(style?: PathEditBalanceStyle): FeaturePreset;
|
|
234
|
+
/** Balance handles with their default look. */
|
|
235
|
+
declare const balancePreset: FeaturePreset;
|
|
236
|
+
/** Path constraints: their actions, their marks in `style`'s colors, and
|
|
237
|
+
* every edit of a constrained path finished so they hold. */
|
|
238
|
+
declare function createConstraintsPreset(style?: Partial<ConstraintGlyphStyle>): FeaturePreset;
|
|
239
|
+
/** Path constraints with their default colors. */
|
|
240
|
+
declare const constraintsPreset: FeaturePreset;
|
|
241
|
+
/**
|
|
242
|
+
* Corner shape: a widget inside each corner anchor of the open path, drawn in
|
|
243
|
+
* `style`, whose drag sets the corner's radius (`editCorner`), and the
|
|
244
|
+
* commands on the selected corners (`setCorners`, `cycleCornerShape`). The
|
|
245
|
+
* widgets show while chrome-caps shows `path-edit.corners`, which is on by
|
|
246
|
+
* default. It refines `paths`, so a widget's drag goes ahead of the marquee.
|
|
247
|
+
*/
|
|
248
|
+
declare function createCornerShapePreset(style?: CornerWidgetStyle): FeaturePreset;
|
|
249
|
+
/** Corner shape with path edit's anchor colors. */
|
|
250
|
+
declare const cornerShapePreset: FeaturePreset;
|
|
251
|
+
/**
|
|
252
|
+
* Where a path starts and which way it runs: `setPathStart` and
|
|
253
|
+
* `reversePath`, and arrows and start rings over the open path, drawn in
|
|
254
|
+
* `style`. The marks are off until chrome-caps shows `path-edit.direction`.
|
|
255
|
+
*/
|
|
256
|
+
declare function createPathStructurePreset(style?: PathDirectionStyle): FeaturePreset;
|
|
257
|
+
/** Path start and direction with the marks' default look. */
|
|
258
|
+
declare const pathStructurePreset: FeaturePreset;
|
|
259
|
+
/** `convertSegments` and `convertSegmentAt`, turning segments straight or
|
|
260
|
+
* curved. It refines `paths`, so a segment's Shift+double-click goes ahead
|
|
261
|
+
* of entering path edit. */
|
|
262
|
+
declare const segmentTypePreset: FeaturePreset;
|
|
263
|
+
/** Blend, Bend along, and Repeat along, live, and the actions that edit and
|
|
264
|
+
* expand them. The scene must hold `withPathEffectsRegistry`'s derivations. */
|
|
265
|
+
declare const pathEffectsPreset: FeaturePreset;
|
|
266
|
+
/** `expandWarp` and `configureWarp`; the warp tools bring their own drags. */
|
|
267
|
+
declare const warpPreset: FeaturePreset;
|
|
268
|
+
/** Every preset above, spiro curves, the comb, balance, constraints, path
|
|
269
|
+
* direction, and corner shape with their defaults — except soft selection and
|
|
270
|
+
* handle snapping, which change what every anchor or handle drag does. */
|
|
271
|
+
declare const pathTools: FeaturePreset;
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Add and remove geometric constraints on the anchors selected in path edit.
|
|
275
|
+
* Neither has a default binding: a consumer binds each kind it offers, with
|
|
276
|
+
* the kind as a param (see `<SceneCanvas tune>`).
|
|
277
|
+
*/
|
|
278
|
+
|
|
279
|
+
/** Params for `constrainAnchors`. */
|
|
280
|
+
interface ConstrainAnchorsParams {
|
|
281
|
+
kind: PathConstraintKind;
|
|
282
|
+
/** For `length`: the length to hold. Default: each pair's length now. */
|
|
283
|
+
length?: number;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* The constraints of `kind` that `anchors`, in the order they were selected,
|
|
287
|
+
* ask for: each anchor for `fixed`; each anchor with both handles for
|
|
288
|
+
* `tangent`; for `onPath`, three anchors, the first held on the segment the
|
|
289
|
+
* other two end; each consecutive pair for `horizontal`,
|
|
290
|
+
* `vertical`, `length`, and `coincident`; and for the kinds relating two
|
|
291
|
+
* segments, three anchors as two segments sharing the middle one or four as
|
|
292
|
+
* two pairs. Empty when the anchors cannot make that kind.
|
|
293
|
+
*/
|
|
294
|
+
declare function constraintsForAnchors(kind: PathConstraintKind, anchors: readonly number[], path: PolygonPath, length?: number): PathConstraint[];
|
|
295
|
+
/**
|
|
296
|
+
* Delete the constraint selected in path edit, as a command. Delete and
|
|
297
|
+
* Backspace reach it through `deleteAnchors`, which deletes whichever of the
|
|
298
|
+
* two is selected, so the keys have one binding.
|
|
299
|
+
*/
|
|
300
|
+
declare const deleteConstraintAction: Action & {
|
|
301
|
+
requires: string[];
|
|
302
|
+
};
|
|
303
|
+
/**
|
|
304
|
+
* Constrain the selected anchors: params `{ kind, length? }`, read as
|
|
305
|
+
* {@link constraintsForAnchors} reads them. The path moves the least that
|
|
306
|
+
* makes every constraint hold; a constraint that conflicts with the rest is
|
|
307
|
+
* kept all the same, left unsolved, and shown as a conflict.
|
|
308
|
+
*/
|
|
309
|
+
declare const constrainAnchorsAction: Action & {
|
|
310
|
+
requires: string[];
|
|
311
|
+
};
|
|
312
|
+
/**
|
|
313
|
+
* Remove the constraints whose anchors are all selected — only those of
|
|
314
|
+
* `kind` when the params name one.
|
|
315
|
+
*/
|
|
316
|
+
declare const unconstrainAnchorsAction: Action & {
|
|
317
|
+
requires: string[];
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
/** The path-edit tool under which a drag on an open end lengthens the path. */
|
|
321
|
+
declare const LENGTHEN_TOOL = "lengthen";
|
|
322
|
+
/** Params `lengthenPath` reads on every move. */
|
|
323
|
+
interface LengthenPathParams {
|
|
324
|
+
/** How an unmodified drag grows the end; Shift picks the other. Default `'tangent'`. */
|
|
325
|
+
mode?: LengthenMode;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Lengthen, the path-edit tool's drag. While path edit's `lengthen` tool is
|
|
329
|
+
* on, dragging an open path's end anchor lengthens the path from that end
|
|
330
|
+
* (`lengthenPathEnd`): straight along its end tangent, or along an arc with
|
|
331
|
+
* the curvature the end has. Dragging back into the path shortens it along
|
|
332
|
+
* itself. The `mode` param (`'tangent'`, the default, or `'curvature'`) picks
|
|
333
|
+
* which, and Shift picks the other; both are read on every move. One undo
|
|
334
|
+
* step per drag. With the tool off, a drag on the anchor is `editAnchors`'
|
|
335
|
+
* and moves it.
|
|
336
|
+
*/
|
|
337
|
+
declare const lengthenPathAction: Action & {
|
|
338
|
+
requires: string[];
|
|
339
|
+
};
|
|
340
|
+
/** The bar toggle for Lengthen: `pathEditTool.lengthen`. */
|
|
341
|
+
declare const lengthenToolAction: Action & {
|
|
342
|
+
requires: string[];
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
/** What the `resamplePath` action reads from its params. */
|
|
346
|
+
type ResamplePathParams = {
|
|
347
|
+
/** Anchors in the result. 0 or absent keeps the count the path has. */
|
|
348
|
+
count?: number;
|
|
349
|
+
/** Distance between anchors along the path; overrides `count` when above 0. */
|
|
350
|
+
spacing?: number;
|
|
351
|
+
/** Hold corner anchors where they are. Default `true`. */
|
|
352
|
+
keepCorners?: boolean;
|
|
353
|
+
/** How far the result may stray from the original. Default 0.5. */
|
|
354
|
+
tolerance?: number;
|
|
355
|
+
};
|
|
356
|
+
/**
|
|
357
|
+
* Redistribute each selected path's anchors evenly by arc length
|
|
358
|
+
* (`resamplePath`), to `params.count` anchors or at `params.spacing`, with
|
|
359
|
+
* corners held unless `params.keepCorners` is false, and curves refitted
|
|
360
|
+
* within `params.tolerance` of the original ({@link ResamplePathParams}).
|
|
361
|
+
* Ongoing: `begin` previews it, each update with new params recomputes it,
|
|
362
|
+
* and committing writes one undo entry.
|
|
363
|
+
*/
|
|
364
|
+
declare const resamplePathAction: _weasel_js_routing.Action & {
|
|
365
|
+
requires: string[];
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
/** The path-edit tool under which a plain drag brushes. */
|
|
369
|
+
declare const SIMPLIFY_BRUSH_TOOL = "simplifyBrush";
|
|
370
|
+
/** The brush's radius on screen when no param names one. */
|
|
371
|
+
declare const SIMPLIFY_BRUSH_RADIUS_PX = 12;
|
|
372
|
+
/** Params the brush reads on every move, so a thunk can change them mid-stroke. */
|
|
373
|
+
interface SimplifyBrushParams {
|
|
374
|
+
/** Brush radius in screen pixels. */
|
|
375
|
+
radiusPx?: number;
|
|
376
|
+
/** How far the refit may stray from the original, in world units, as for
|
|
377
|
+
* the Simplify command. */
|
|
378
|
+
tolerance?: number;
|
|
379
|
+
}
|
|
380
|
+
/** The kit's brush-ring cursor drawn `radiusPx` in radius on screen. */
|
|
381
|
+
declare function brushRingCursor(radiusPx: number): CursorSpec;
|
|
382
|
+
/**
|
|
383
|
+
* The Simplify command, brushed on. While path edit's
|
|
384
|
+
* `simplifyBrush` tool is on, a plain drag gathers every anchor a round brush
|
|
385
|
+
* passes over, and each unbroken stretch of them along a subpath is refitted
|
|
386
|
+
* as one span by Simplify's own fitter (`simplifyAnchorsAt`) at `tolerance`.
|
|
387
|
+
* Only anchors the shape does not need go, so brushing again goes further.
|
|
388
|
+
* The path previews the result while the brush is down and commits as one
|
|
389
|
+
* undo step on release.
|
|
390
|
+
*/
|
|
391
|
+
declare const simplifyBrushAction: Action & {
|
|
392
|
+
requires: string[];
|
|
393
|
+
};
|
|
394
|
+
/** The bar toggle for the brush: `pathEditTool.simplifyBrush`. */
|
|
395
|
+
declare const simplifyBrushToolAction: Action & {
|
|
396
|
+
requires: string[];
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* The Smudge brush's drag: the selected paths' outlines under a round brush
|
|
401
|
+
* follow the pointer, as one undo entry per stroke.
|
|
402
|
+
*/
|
|
403
|
+
|
|
404
|
+
/** The brush's radius in screen px when no param gives one. */
|
|
405
|
+
declare const DEFAULT_SMUDGE_RADIUS_PX = 40;
|
|
406
|
+
/** How much of the pointer's motion the outline under the brush's center follows,
|
|
407
|
+
* when no param gives it. */
|
|
408
|
+
declare const DEFAULT_SMUDGE_STRENGTH = 0.6;
|
|
409
|
+
/** The params `smudgeBrush` reads, each on every pointer move. */
|
|
410
|
+
interface SmudgeBrushParams {
|
|
411
|
+
/** The brush's radius, in screen px. */
|
|
412
|
+
radiusPx?: number;
|
|
413
|
+
/** `1` moves the outline under the brush's center as far as the pointer; less, less. */
|
|
414
|
+
strength?: number;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* A drag that pushes the outline of every selected path along with
|
|
418
|
+
* the pointer (`smudgePath` in `@weasel-js/geom`). Each pointer move is one dab from
|
|
419
|
+
* where the last one ended: points under the brush move with it, most at its center
|
|
420
|
+
* and not at all at its rim, and a long segment the brush meets gets anchors added
|
|
421
|
+
* so it can bend there. `params.radiusPx` is the brush's radius on screen, so it
|
|
422
|
+
* covers the same part of the canvas at every zoom, and `params.strength` how closely
|
|
423
|
+
* the outline follows; both are read on every move. The cursor is a ring the size of
|
|
424
|
+
* the brush. The stroke commits as one undo entry; canceling it leaves the paths as
|
|
425
|
+
* they were.
|
|
426
|
+
*/
|
|
427
|
+
declare const smudgeBrushAction: Action & {
|
|
428
|
+
requires: string[];
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* A warp a node is holding: the path it warped, the warp, and the tolerance
|
|
433
|
+
* the result was refitted to, kept on the node as `data.warp` beside the
|
|
434
|
+
* `data.path` (or polygon pose) they produced. The geometry stays what every
|
|
435
|
+
* reader uses; the warp only says how to make it again, so it can be edited
|
|
436
|
+
* until it is expanded away.
|
|
437
|
+
*
|
|
438
|
+
* The warp lives in its own frame, fixed when it was made. `frame` carries
|
|
439
|
+
* that frame onto the stored path, so moving, resizing or rotating the node
|
|
440
|
+
* keeps the warp without touching it. A writer that changes the geometry some
|
|
441
|
+
* other way leaves a warp that no longer reproduces it, and such a warp is
|
|
442
|
+
* ignored, the way a stale shape generator is.
|
|
443
|
+
*/
|
|
444
|
+
|
|
445
|
+
/** What `data.warp` holds. */
|
|
446
|
+
interface HeldPathWarp {
|
|
447
|
+
/** Shared by every node warped together, so one handle drives them all. */
|
|
448
|
+
id: string;
|
|
449
|
+
/** The path before warping, in the warp's frame. */
|
|
450
|
+
source: PolygonPath;
|
|
451
|
+
warp: PathWarp;
|
|
452
|
+
/** How far the refitted result may stray from the exact warp. */
|
|
453
|
+
tolerance: number;
|
|
454
|
+
/** From the warp's frame to the frame the node stores its path in. */
|
|
455
|
+
frame: Affine;
|
|
456
|
+
}
|
|
457
|
+
/** A held warp that still reproduces its node, and where its frame lands in
|
|
458
|
+
* world space now. */
|
|
459
|
+
interface ResolvedPathWarp {
|
|
460
|
+
held: HeldPathWarp;
|
|
461
|
+
/** From the warp's frame to world space. */
|
|
462
|
+
toWorld: Affine;
|
|
463
|
+
}
|
|
464
|
+
/** The warp a node's `data` holds, whether or not it still matches. */
|
|
465
|
+
declare function heldPathWarpOf(data: unknown): HeldPathWarp | null;
|
|
466
|
+
/** `data` without its warp: the shape as plain geometry. */
|
|
467
|
+
declare function withoutPathWarp<T>(data: T): T;
|
|
468
|
+
/**
|
|
469
|
+
* The warp `node` holds and its frame in world space, or null when it holds
|
|
470
|
+
* none or the one it holds no longer reproduces its geometry. A node whose
|
|
471
|
+
* stored path was rewritten by an affine map since — a polygon pose moved,
|
|
472
|
+
* resized or rotated, which rewrites its coordinates — still resolves: the
|
|
473
|
+
* map is recovered from the two sets of points and replaces `frame`.
|
|
474
|
+
*/
|
|
475
|
+
declare function resolvePathWarp(node: EditableShape | null | undefined): ResolvedPathWarp | null;
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* What every warp action shares: finding the selected paths' warps of one
|
|
479
|
+
* kind, making fresh ones where a path holds none, and writing a changed warp
|
|
480
|
+
* back as the geometry it makes plus the warp itself.
|
|
481
|
+
*/
|
|
482
|
+
|
|
483
|
+
/** Which warp a tool or action works with. */
|
|
484
|
+
type WarpKind = PathWarp['kind'];
|
|
485
|
+
/** The settings a warp is made or remade with. Each applies only to the kinds
|
|
486
|
+
* it names; absent ones leave a held warp as it is. */
|
|
487
|
+
interface WarpSettings {
|
|
488
|
+
/** A distort's map. Default `'free'`. */
|
|
489
|
+
mode?: DistortMode;
|
|
490
|
+
/** An envelope's interpolation. Default `'bicubic'`. */
|
|
491
|
+
mapping?: EnvelopeMapping;
|
|
492
|
+
/** An envelope's patch rows and columns. Default 3 each. */
|
|
493
|
+
rows?: number;
|
|
494
|
+
cols?: number;
|
|
495
|
+
/** How far, in world units, the refitted result may stray from the exact
|
|
496
|
+
* warp. Default {@link DEFAULT_WARP_TOLERANCE}. */
|
|
497
|
+
tolerance?: number;
|
|
498
|
+
}
|
|
499
|
+
/** The refit tolerance of a warp made without one. */
|
|
500
|
+
declare const DEFAULT_WARP_TOLERANCE = 0.5;
|
|
501
|
+
/** The patch rows and columns of an envelope made without them. */
|
|
502
|
+
declare const DEFAULT_ENVELOPE_SIZE = 3;
|
|
503
|
+
/**
|
|
504
|
+
* `shape` (a node's pose and data) warped by `warp`, whose controls are in
|
|
505
|
+
* world space, and holding it — for a scene that opens on a warp already
|
|
506
|
+
* made. Null when `shape` holds no editable polygon.
|
|
507
|
+
*/
|
|
508
|
+
declare function withPathWarp<S extends {
|
|
509
|
+
pose: unknown;
|
|
510
|
+
data: unknown;
|
|
511
|
+
}>(shape: S, warp: PathWarp, opts?: {
|
|
512
|
+
id?: string;
|
|
513
|
+
tolerance?: number;
|
|
514
|
+
}): {
|
|
515
|
+
pose: unknown;
|
|
516
|
+
data: unknown;
|
|
517
|
+
} | null;
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* The params this package's actions read, merged into routing's
|
|
521
|
+
* `ActionParamSchema` so `<SceneCanvas tune>` types them.
|
|
522
|
+
*/
|
|
523
|
+
|
|
524
|
+
/** A path effect's settings as params; a blend's `reverse` also takes
|
|
525
|
+
* `'auto'`, handing the direction back to `autoAlign`. */
|
|
526
|
+
type SettingsOf<E> = {
|
|
527
|
+
[K in Exclude<keyof E, 'kind'>]?: E[K];
|
|
528
|
+
};
|
|
529
|
+
type BlendParams = Omit<SettingsOf<BlendEffect>, 'reverse'> & {
|
|
530
|
+
reverse?: boolean | 'auto';
|
|
531
|
+
};
|
|
532
|
+
/** Either field left out keeps that part of each selected corner. */
|
|
533
|
+
type SetCornersParams = {
|
|
534
|
+
shape: CornerShape;
|
|
535
|
+
radius: number;
|
|
536
|
+
};
|
|
537
|
+
type EditPathEffectParams = BlendParams & SettingsOf<BendAlongEffect> & SettingsOf<RepeatAlongEffect> & {
|
|
538
|
+
ids?: readonly string[];
|
|
539
|
+
};
|
|
540
|
+
declare module '@weasel-js/routing' {
|
|
541
|
+
interface ActionParamSchema {
|
|
542
|
+
blend: BlendParams;
|
|
543
|
+
bendAlong: SettingsOf<BendAlongEffect>;
|
|
544
|
+
repeatAlong: SettingsOf<RepeatAlongEffect>;
|
|
545
|
+
editPathEffect: EditPathEffectParams;
|
|
546
|
+
simplifyBrush: SimplifyBrushParams;
|
|
547
|
+
smudgeBrush: SmudgeBrushParams;
|
|
548
|
+
lengthenPath: LengthenPathParams;
|
|
549
|
+
bridgePaths: {
|
|
550
|
+
tension?: number;
|
|
551
|
+
};
|
|
552
|
+
bridgeAnchors: {
|
|
553
|
+
tension?: number;
|
|
554
|
+
};
|
|
555
|
+
setSpiroKind: {
|
|
556
|
+
kind?: SpiroKind;
|
|
557
|
+
};
|
|
558
|
+
'spiro.placePoint': {
|
|
559
|
+
kind?: SpiroKind;
|
|
560
|
+
};
|
|
561
|
+
constrainAnchors: ConstrainAnchorsParams;
|
|
562
|
+
unconstrainAnchors: {
|
|
563
|
+
kind?: PathConstraintKind;
|
|
564
|
+
};
|
|
565
|
+
'distort.drag': WarpSettings;
|
|
566
|
+
'envelope.drag': WarpSettings;
|
|
567
|
+
'puppet.drag': WarpSettings;
|
|
568
|
+
'puppet.addPin': WarpSettings;
|
|
569
|
+
configureWarp: WarpSettings & {
|
|
570
|
+
kind?: WarpKind;
|
|
571
|
+
};
|
|
572
|
+
convertSegments: {
|
|
573
|
+
to?: SegmentType;
|
|
574
|
+
};
|
|
575
|
+
convertSegmentAt: {
|
|
576
|
+
to?: SegmentType;
|
|
577
|
+
};
|
|
578
|
+
selectEveryNthAnchor: {
|
|
579
|
+
n?: number;
|
|
580
|
+
};
|
|
581
|
+
resamplePath: ResamplePathParams;
|
|
582
|
+
setCorners: SetCornersParams;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Toggles for the locks every path-edit handle drag holds without a
|
|
588
|
+
* modifier: its angle, its length, or both, which freezes it. They set the
|
|
589
|
+
* `editAnchors` dep's `handleLocks`, so a bar, the command palette, and
|
|
590
|
+
* `<SceneCanvas tune>`'s `handleLock` param, which they start from, all
|
|
591
|
+
* reach the one value the drag reads.
|
|
592
|
+
*/
|
|
593
|
+
|
|
594
|
+
/** Hold every handle drag to the handle's angle, as Shift does. */
|
|
595
|
+
declare const handleLockAngleAction: Action & {
|
|
596
|
+
requires: string[];
|
|
597
|
+
};
|
|
598
|
+
/** Hold every handle drag to the handle's length, as Mod (Cmd or Ctrl) does. */
|
|
599
|
+
declare const handleLockLengthAction: Action & {
|
|
600
|
+
requires: string[];
|
|
601
|
+
};
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Bridge: join open path ends with a curve that leaves each end along the
|
|
605
|
+
* direction its path was heading, on whole paths or on the two anchors
|
|
606
|
+
* selected in path edit.
|
|
607
|
+
*/
|
|
608
|
+
|
|
609
|
+
/** How long Bridge makes each handle, as a fraction of the gap, when its
|
|
610
|
+
* params name no `tension`. */
|
|
611
|
+
declare const DEFAULT_BRIDGE_TENSION = 0.4;
|
|
612
|
+
/** A bridge's `params.tension`, or the default. Negative reads as `0`. */
|
|
613
|
+
declare function bridgeTensionOf(params: Record<string, unknown> | undefined): number;
|
|
614
|
+
/**
|
|
615
|
+
* Bridge open paths: as `joinPaths`, but the gap is spanned by
|
|
616
|
+
* a curve leaving each end along the direction its path was heading, each
|
|
617
|
+
* handle `params.tension` times the gap long (default
|
|
618
|
+
* {@link DEFAULT_BRIDGE_TENSION}). Two paths become one. In path edit,
|
|
619
|
+
* `bridgeAnchors` bridges the two selected anchors instead.
|
|
620
|
+
*/
|
|
621
|
+
declare const bridgePathsAction: Action & {
|
|
622
|
+
requires: string[];
|
|
623
|
+
};
|
|
624
|
+
/**
|
|
625
|
+
* Bridge the two selected anchors, each the end of an open
|
|
626
|
+
* subpath, as `joinAnchors` does, but with a curve leaving each end along the
|
|
627
|
+
* direction its path was heading, each handle `params.tension` times the gap
|
|
628
|
+
* long (`bridgePaths`'s default when absent). The anchor selection is
|
|
629
|
+
* cleared.
|
|
630
|
+
*/
|
|
631
|
+
declare const bridgeAnchorsAction: Action & {
|
|
632
|
+
requires: string[];
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
/** Trim segment: cut a stroke back to the crossings on either side of a click. */
|
|
636
|
+
|
|
637
|
+
/** What a trim at the press in `params` would do: the stroke it reaches, and
|
|
638
|
+
* what `trimPathAt` makes of it. Null when it reaches none it can trim.
|
|
639
|
+
* `params` as {@link trimPathAction} reads them; a hover's pointer serves
|
|
640
|
+
* as the press, which is how a tool previews the piece. */
|
|
641
|
+
declare function planTrim(deps: ActionDeps, params: unknown): {
|
|
642
|
+
target: PathNode;
|
|
643
|
+
result: TrimResult;
|
|
644
|
+
} | null;
|
|
645
|
+
/**
|
|
646
|
+
* Trim segment: remove the piece of the stroke under the press
|
|
647
|
+
* between the nearest crossings on either side — with any other node's
|
|
648
|
+
* outline, or with itself — as `trimPathAt` cuts it. The topmost stroke
|
|
649
|
+
* within `radiusPx` of the press (default 6) is the one trimmed; a stroke
|
|
650
|
+
* with nothing left is deleted. Params: `pressX`, `pressY` in world space,
|
|
651
|
+
* which a click binding supplies.
|
|
652
|
+
*/
|
|
653
|
+
declare const trimPathAction: Action & {
|
|
654
|
+
requires: string[];
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
/** Extend to next path: carry an open end along its tangent until it meets a stroke. */
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Extend to next path: carry each open end of the selected
|
|
661
|
+
* paths along its tangent to the first stroke it meets (`extendToMeet`). In
|
|
662
|
+
* path edit, the selected end anchors of the edited path, or all its open
|
|
663
|
+
* ends when none is selected. Given a press (`pressX`, `pressY`, as a click
|
|
664
|
+
* binding supplies), the open end nearest it of the topmost stroke within
|
|
665
|
+
* `radiusPx` instead. An end that meets nothing stays put. One undo step.
|
|
666
|
+
*/
|
|
667
|
+
declare const extendToMeetAction: Action & {
|
|
668
|
+
requires: string[];
|
|
669
|
+
};
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Make the selected smooth anchors curvature-continuous by adjusting their
|
|
673
|
+
* handle lengths, or every smooth anchor of the path while none is selected.
|
|
674
|
+
*/
|
|
675
|
+
declare const harmonizeAnchorsAction: _weasel_js_routing.Action & {
|
|
676
|
+
requires: string[];
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Where a path starts and which way it runs: make the selected anchor its
|
|
681
|
+
* subpath's start, and reverse a path's direction. Both reorder anchors
|
|
682
|
+
* without moving them, and what a node keeps per anchor moves with them.
|
|
683
|
+
*/
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
* Make the selected anchor where its subpath starts. A closed
|
|
687
|
+
* subpath turns to start there; an open one can start only at an end, so its
|
|
688
|
+
* last anchor reverses it (`setSubpathStart`). The anchor stays selected.
|
|
689
|
+
*/
|
|
690
|
+
declare const setPathStartAction: Action & {
|
|
691
|
+
requires: string[];
|
|
692
|
+
};
|
|
693
|
+
/**
|
|
694
|
+
* Run paths the other way, keeping their shape. In path edit it
|
|
695
|
+
* reverses the subpaths holding the selected anchors — every subpath when
|
|
696
|
+
* none is selected — and the selection follows its anchors. Otherwise it
|
|
697
|
+
* reverses every selected path whole, in one undo entry. A closed subpath
|
|
698
|
+
* keeps its start; an open one starts where it ended (`reverseSubpaths`).
|
|
699
|
+
*/
|
|
700
|
+
declare const reversePathAction: Action & {
|
|
701
|
+
requires: string[];
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Make segments of the path being edited straight or curved, in place
|
|
706
|
+
* (`convertSegments`): the selected segments from the keyboard, or the one
|
|
707
|
+
* under a Shift+double-click.
|
|
708
|
+
*/
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* Convert the selected segments — those whose two ends are both
|
|
712
|
+
* selected anchors. `params.to` `'line'` straightens them, `'curve'` curves
|
|
713
|
+
* them with handles at their thirds so they keep their shape, and no `to`
|
|
714
|
+
* (Shift+C) curves them all when any is straight and straightens them
|
|
715
|
+
* otherwise.
|
|
716
|
+
*/
|
|
717
|
+
declare const convertSegmentsAction: Action & {
|
|
718
|
+
requires: string[];
|
|
719
|
+
};
|
|
720
|
+
/**
|
|
721
|
+
* Shift+double-click a segment of the path being edited to flip
|
|
722
|
+
* it between straight and curved. Off every segment the click falls through.
|
|
723
|
+
*/
|
|
724
|
+
declare const convertSegmentAtAction: Action & {
|
|
725
|
+
requires: string[];
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* Anchor selection along the path in path edit: grow or shrink it by one
|
|
730
|
+
* anchor, every Nth anchor, corners or smooth anchors, and the complement.
|
|
731
|
+
* They change which anchors are selected and nothing else, so none of them
|
|
732
|
+
* is an undo step.
|
|
733
|
+
*/
|
|
734
|
+
|
|
735
|
+
/** The group every action here is in, which an `ActionBar` can show. */
|
|
736
|
+
declare const ANCHOR_SELECTION_GROUP = "anchorSelection";
|
|
737
|
+
/** Add each selected anchor's neighbors along the path. `]`. */
|
|
738
|
+
declare const growAnchorSelectionAction: Action & {
|
|
739
|
+
requires: string[];
|
|
740
|
+
};
|
|
741
|
+
/** Drop the anchors at the ends of each selected run. `[`. */
|
|
742
|
+
declare const shrinkAnchorSelectionAction: Action & {
|
|
743
|
+
requires: string[];
|
|
744
|
+
};
|
|
745
|
+
/**
|
|
746
|
+
* Select every `params.n`th anchor (default 2) along each subpath, counting
|
|
747
|
+
* from its first selected anchor, or from the start of every subpath when
|
|
748
|
+
* none is selected. Alt+N.
|
|
749
|
+
*/
|
|
750
|
+
declare const selectEveryNthAnchorAction: Action & {
|
|
751
|
+
requires: string[];
|
|
752
|
+
};
|
|
753
|
+
/** Select every corner anchor of the edited path. Alt+C. */
|
|
754
|
+
declare const selectCornerAnchorsAction: Action & {
|
|
755
|
+
requires: string[];
|
|
756
|
+
};
|
|
757
|
+
/** Select every smooth anchor of the edited path. Alt+M. */
|
|
758
|
+
declare const selectSmoothAnchorsAction: Action & {
|
|
759
|
+
requires: string[];
|
|
760
|
+
};
|
|
761
|
+
/** Select the anchors that are not selected, and only those. Alt+I. */
|
|
762
|
+
declare const invertAnchorSelectionAction: Action & {
|
|
763
|
+
requires: string[];
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
/**
|
|
767
|
+
* Add extremes in path edit: an anchor at each turn of a curved segment, in x
|
|
768
|
+
* and in y, with the shape left as it was.
|
|
769
|
+
*/
|
|
770
|
+
|
|
771
|
+
/**
|
|
772
|
+
* Split the curved segments of the edited path at their x and y extremes:
|
|
773
|
+
* those whose two ends are both selected, or every one while no anchor is.
|
|
774
|
+
* The selected anchors stay selected, and the new ones join them. Alt+X.
|
|
775
|
+
* Enabled only where it would add an anchor.
|
|
776
|
+
*/
|
|
777
|
+
declare const addExtremeAnchorsAction: Action & {
|
|
778
|
+
requires: string[];
|
|
779
|
+
};
|
|
780
|
+
|
|
781
|
+
/**
|
|
782
|
+
* The balance grip on each curved segment of the path being edited, midway
|
|
783
|
+
* along the line joining its two handle tips:
|
|
784
|
+
*
|
|
785
|
+
* - `balanceHandles` — drag the grip to scale both handles together, each
|
|
786
|
+
* along its own direction, so the segment fills out toward its corner or
|
|
787
|
+
* flattens toward its chord without turning at either end.
|
|
788
|
+
* - `equalizeHandles` — double-click the grip to give both handles the same
|
|
789
|
+
* proportion of the way to that corner.
|
|
790
|
+
*
|
|
791
|
+
* The grips are the `balance:N` affordances path edit lays out, shown and
|
|
792
|
+
* hit-tested only while chrome-caps shows `path-edit.balance`. N is the flat
|
|
793
|
+
* index of the anchor the segment starts at.
|
|
794
|
+
*
|
|
795
|
+
* Under a `pathSymmetry` dep a grip drag moves every image of both handles,
|
|
796
|
+
* as `editAnchors` moves a dragged handle's. Both keep each handle's angle, so an angle lock holds through them. A length
|
|
797
|
+
* lock in force for handle drags (the `editAnchors` dep's `handleLocks`, or Mod)
|
|
798
|
+
* holds the drag still, as it would a handle drag with the angle held too.
|
|
799
|
+
*/
|
|
800
|
+
|
|
801
|
+
/** Drag a segment's balance grip to scale both its handles together. */
|
|
802
|
+
declare const balanceHandlesAction: Action & {
|
|
803
|
+
requires: string[];
|
|
804
|
+
};
|
|
805
|
+
/** Double-click a segment's balance grip to even out its handles' proportions. */
|
|
806
|
+
declare const equalizeHandlesAction: Action & {
|
|
807
|
+
requires: string[];
|
|
808
|
+
};
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* The path-effect actions: make a live blend, bend, or repeat from the
|
|
812
|
+
* selection; change one's settings; and expand one into ordinary paths.
|
|
813
|
+
*/
|
|
814
|
+
|
|
815
|
+
/** The `group` every path-effect action is in, for an `<ActionBar>`. */
|
|
816
|
+
declare const PATH_EFFECTS_GROUP = "pathEffects";
|
|
817
|
+
/**
|
|
818
|
+
* Steps between the first two selected shapes, in the order they were
|
|
819
|
+
* selected: `params.steps` of them, each shape, fill, stroke and turn
|
|
820
|
+
* interpolated, laid along a third selected path where there is one. The
|
|
821
|
+
* blend is live — editing a source moves its steps — and goes just under the
|
|
822
|
+
* upper of the first two. Its other params are `BlendEffect`'s.
|
|
823
|
+
*/
|
|
824
|
+
declare const blendAction: Action & {
|
|
825
|
+
requires: string[];
|
|
826
|
+
};
|
|
827
|
+
/**
|
|
828
|
+
* The first selected shape bent along the second, live: editing the spine
|
|
829
|
+
* re-bends it. Params are `BendAlongEffect`'s.
|
|
830
|
+
*/
|
|
831
|
+
declare const bendAlongAction: Action & {
|
|
832
|
+
requires: string[];
|
|
833
|
+
};
|
|
834
|
+
/**
|
|
835
|
+
* Copies of the first selected shape along the second, live. Params are
|
|
836
|
+
* `RepeatAlongEffect`'s.
|
|
837
|
+
*/
|
|
838
|
+
declare const repeatAlongAction: Action & {
|
|
839
|
+
requires: string[];
|
|
840
|
+
};
|
|
841
|
+
/**
|
|
842
|
+
* Change the settings of path effects: `params.ids` when given, else the
|
|
843
|
+
* selected ones. Every other param is a setting, laid over each effect's
|
|
844
|
+
* own, and one that would change nothing commits nothing. Consecutive edits
|
|
845
|
+
* of one effect coalesce, so a slider dragged through many values is one
|
|
846
|
+
* undo step where the scene coalesces.
|
|
847
|
+
*/
|
|
848
|
+
declare const editPathEffectAction: Action & {
|
|
849
|
+
requires: string[];
|
|
850
|
+
};
|
|
851
|
+
/**
|
|
852
|
+
* Turn each selected path effect into the ordinary paths it shows, in its
|
|
853
|
+
* slot and in its paint, and select them. Its sources stay; the paths no
|
|
854
|
+
* longer follow them.
|
|
855
|
+
*/
|
|
856
|
+
declare const expandPathEffectAction: Action & {
|
|
857
|
+
requires: string[];
|
|
858
|
+
};
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* The warp actions. A warp tool binds the per-kind ones (`<kind>.drag`,
|
|
862
|
+
* `puppet.addPin`, `puppet.removePin`) and owns them; `expandWarp` and
|
|
863
|
+
* `configureWarp` work on whatever warp the selection holds and ship with
|
|
864
|
+
* the `paths` preset.
|
|
865
|
+
*/
|
|
866
|
+
|
|
867
|
+
/** What a press on a warp control hands the drag that follows. */
|
|
868
|
+
interface WarpHandleScratch {
|
|
869
|
+
/** The warp the control belongs to, or null for one shown over a selection
|
|
870
|
+
* holding none yet, which the drag makes. */
|
|
871
|
+
warpId: string | null;
|
|
872
|
+
/** The control's index, as `warpControls` counts them. */
|
|
873
|
+
index: number;
|
|
874
|
+
}
|
|
875
|
+
/** The scratch a control press carried, or null when the press was elsewhere. */
|
|
876
|
+
declare function warpHandleScratchOf(hit: unknown): WarpHandleScratch | null;
|
|
877
|
+
/**
|
|
878
|
+
* Drop the warp from each selected path, keeping the geometry it made: the
|
|
879
|
+
* shape becomes plain geometry that path editing and other warps start from.
|
|
880
|
+
*/
|
|
881
|
+
declare const expandWarpAction: Action;
|
|
882
|
+
/**
|
|
883
|
+
* Remake the selection's warps under new settings (`params`, a
|
|
884
|
+
* {@link WarpSettings}, plus an optional `kind` limiting it to one kind of
|
|
885
|
+
* warp): switch a distort between free and perspective, an envelope between
|
|
886
|
+
* its mappings or to a finer grid, or refit at another tolerance. One undo step.
|
|
887
|
+
*/
|
|
888
|
+
declare const configureWarpAction: Action;
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* Corner shape in path edit: drag a corner's widget to set its radius.
|
|
892
|
+
*
|
|
893
|
+
* A drag measures how far the pointer moves along the corner's bisector and
|
|
894
|
+
* turns that into a cut along the edges, clamped to the room the neighboring
|
|
895
|
+
* corners leave. Pressing the widget of a selected anchor gives every
|
|
896
|
+
* selected corner the same radius. The release commits one undo step.
|
|
897
|
+
*/
|
|
898
|
+
|
|
899
|
+
/** The shape a corner with no spec yet takes. */
|
|
900
|
+
declare const DEFAULT_CORNER_SHAPE: CornerShape;
|
|
901
|
+
/** Drag a corner widget to set the corner's radius. */
|
|
902
|
+
declare const editCornerAction: Action & {
|
|
903
|
+
requires: string[];
|
|
904
|
+
};
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* Commands on the corners of the anchors selected in path edit: set their
|
|
908
|
+
* shape or radius, or step their shape through the `corner-shape` keywords.
|
|
909
|
+
*/
|
|
910
|
+
|
|
911
|
+
/** The share of a corner's room that a shape given to a sharp corner cuts. */
|
|
912
|
+
declare const DEFAULT_CORNER_TRIM_SHARE = 0.25;
|
|
913
|
+
/**
|
|
914
|
+
* Set the selected corners' shape, radius, or both, from the `shape` (a
|
|
915
|
+
* keyword or a finite `superellipse()` parameter) and `radius` params; each
|
|
916
|
+
* is left alone when its param is absent, except that a shape given to a
|
|
917
|
+
* sharp corner also gives it a radius. A UI control's action: it has no
|
|
918
|
+
* default binding.
|
|
919
|
+
*/
|
|
920
|
+
declare const setCornersAction: Action & {
|
|
921
|
+
requires: string[];
|
|
922
|
+
};
|
|
923
|
+
/**
|
|
924
|
+
* Step the selected corners to the next `corner-shape` keyword, keeping
|
|
925
|
+
* their radius. Every one takes the keyword after the first selected
|
|
926
|
+
* corner's shape, so a mixed selection comes out alike, and a sharp corner
|
|
927
|
+
* gets a radius that shows it.
|
|
928
|
+
*/
|
|
929
|
+
declare const cycleCornerShapeAction: Action & {
|
|
930
|
+
requires: string[];
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
/** Options for a tool that acts on the stroke under a click. */
|
|
934
|
+
interface StrokeClickToolOptions {
|
|
935
|
+
/** Override the default keybinding. Pass `null` to omit. */
|
|
936
|
+
keybinding?: ToolKeybinding | null;
|
|
937
|
+
/** How far from a stroke a click may land and still reach it, in screen
|
|
938
|
+
* pixels. Read on every click. Default 6. */
|
|
939
|
+
radiusPx?: number | (() => number);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
/** Options for `useTrimTool`; the default keybinding is `{ key: 'Y' }`. */
|
|
943
|
+
type UseTrimToolOptions = StrokeClickToolOptions;
|
|
944
|
+
/**
|
|
945
|
+
* Trim segment tool. A click on a stroke removes its piece between the
|
|
946
|
+
* crossings on either side — a declarative shell over the `trimPath` action,
|
|
947
|
+
* which owns the hit-test and the commit. While it is up, the piece under the
|
|
948
|
+
* pointer is drawn dashed, through the same `planTrim` the click commits.
|
|
949
|
+
*/
|
|
950
|
+
declare function useTrimTool(options?: UseTrimToolOptions): Tool;
|
|
951
|
+
|
|
952
|
+
/** Options for `useExtendTool`; the default keybinding is `{ key: 'U' }`. */
|
|
953
|
+
type UseExtendToolOptions = StrokeClickToolOptions;
|
|
954
|
+
/**
|
|
955
|
+
* Extend to next path tool. A click near an open end of a stroke carries
|
|
956
|
+
* that end along its tangent to the next stroke it meets — a declarative
|
|
957
|
+
* shell over the `extendToMeet` action.
|
|
958
|
+
*/
|
|
959
|
+
declare function useExtendTool(options?: UseExtendToolOptions): Tool;
|
|
960
|
+
|
|
961
|
+
/** Options for `useSmudgeBrushTool`. */
|
|
962
|
+
interface UseSmudgeBrushToolOptions {
|
|
963
|
+
/** Override the default keybinding (`{ key: 'S' }`). Pass `null` to omit. */
|
|
964
|
+
keybinding?: ToolKeybinding | null;
|
|
965
|
+
}
|
|
966
|
+
/**
|
|
967
|
+
* Smudge brush tool. A round brush that pushes the outline of the selected
|
|
968
|
+
* paths along with the pointer — a declarative shell whose one binding routes a
|
|
969
|
+
* drag to the `smudgeBrush` action, which owns the stroke, its preview, its ring
|
|
970
|
+
* cursor, and its one undo entry. The brush's radius (screen px) and strength are
|
|
971
|
+
* that action's params: `tune={{ smudgeBrush: { params: () => ({ radiusPx, strength }) } }}`.
|
|
972
|
+
*/
|
|
973
|
+
declare function useSmudgeBrushTool(options?: UseSmudgeBrushToolOptions): Tool;
|
|
974
|
+
|
|
975
|
+
/** A warp tool: a `Tool` that also registers the layer showing its controls. */
|
|
976
|
+
type WarpTool = Tool & Pick<SurfaceContribution, 'attach'>;
|
|
977
|
+
/** Options every warp tool takes. */
|
|
978
|
+
interface WarpToolOptions {
|
|
979
|
+
/** Palette label. */
|
|
980
|
+
label?: string;
|
|
981
|
+
/** Override the default keybinding (Distort `F`, Envelope `M`, Puppet Warp
|
|
982
|
+
* `B`). Pass `null` to omit. */
|
|
983
|
+
keybinding?: ToolKeybinding | null;
|
|
984
|
+
/** How far, in world units, a warped path's refitted curves may stray from
|
|
985
|
+
* the exact warp. Default 0.5. */
|
|
986
|
+
tolerance?: number;
|
|
987
|
+
}
|
|
988
|
+
/** Options for {@link useDistortTool}. */
|
|
989
|
+
interface UseDistortToolOptions extends WarpToolOptions {
|
|
990
|
+
/** The map a new distort starts with: `'free'` (bilinear, the default) or
|
|
991
|
+
* `'perspective'` (projective). */
|
|
992
|
+
mode?: DistortMode;
|
|
993
|
+
}
|
|
994
|
+
/** Options for {@link useEnvelopeTool}. */
|
|
995
|
+
interface UseEnvelopeToolOptions extends WarpToolOptions {
|
|
996
|
+
/** Patch rows and columns of a new envelope's mesh. Default 3 each. */
|
|
997
|
+
rows?: number;
|
|
998
|
+
cols?: number;
|
|
999
|
+
/** How a new envelope interpolates its mesh. Default `'bicubic'`. */
|
|
1000
|
+
mapping?: EnvelopeMapping;
|
|
1001
|
+
}
|
|
1002
|
+
/** Options for {@link usePuppetTool}. */
|
|
1003
|
+
type UsePuppetToolOptions = WarpToolOptions;
|
|
1004
|
+
/**
|
|
1005
|
+
* Distort the selected paths by their box's four corners, each dragged on its
|
|
1006
|
+
* own. The first drag gives the selection a distort, kept on each path as
|
|
1007
|
+
* `data.warp` until it is expanded (`expandWarp`); selecting the paths again
|
|
1008
|
+
* with this tool shows its corners where they were left. `configureWarp`
|
|
1009
|
+
* switches a held distort between free and perspective.
|
|
1010
|
+
*/
|
|
1011
|
+
declare function useDistortTool(options?: UseDistortToolOptions): WarpTool;
|
|
1012
|
+
/**
|
|
1013
|
+
* Warp the selected paths through a mesh of control points over their box:
|
|
1014
|
+
* drag any point and the shape bends smoothly around it. The mesh is held on
|
|
1015
|
+
* each path until it is expanded, and `configureWarp` changes its grid or its
|
|
1016
|
+
* interpolation.
|
|
1017
|
+
*/
|
|
1018
|
+
declare function useEnvelopeTool(options?: UseEnvelopeToolOptions): WarpTool;
|
|
1019
|
+
/**
|
|
1020
|
+
* Pin the selected paths where they are clicked, and drag a pin to bend them:
|
|
1021
|
+
* the rest of the shape follows as rigidly as the pins allow, and a pin left
|
|
1022
|
+
* alone holds its place. Alt-click a pin to take it out. The pins are held on
|
|
1023
|
+
* each path until it is expanded.
|
|
1024
|
+
*/
|
|
1025
|
+
declare function usePuppetTool(options?: UsePuppetToolOptions): WarpTool;
|
|
1026
|
+
|
|
1027
|
+
/** The id of the layer showing a `kind` warp's controls. A binding reaches
|
|
1028
|
+
* its controls through `affordance:layer:<id>`. */
|
|
1029
|
+
declare const warpLayerId: (kind: WarpKind) => string;
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* Shape building: the selected paths cut into the faces their outlines bound,
|
|
1033
|
+
* then a pick of those faces united into one path, or deleted, as one undo step.
|
|
1034
|
+
*/
|
|
1035
|
+
|
|
1036
|
+
/** What a pick of faces does: unite them into one path, or delete them. */
|
|
1037
|
+
type ShapeBuilderMode = 'merge' | 'delete';
|
|
1038
|
+
/** One face of the selection: a connected region no outline crosses. */
|
|
1039
|
+
interface ShapeBuilderFace {
|
|
1040
|
+
path: PolygonPath;
|
|
1041
|
+
/** The topmost source covering the face, which a path made of it stands in for. */
|
|
1042
|
+
sourceId: NodeId;
|
|
1043
|
+
/** Set when that source's stroke went into the face: the paint it wears. */
|
|
1044
|
+
paint?: PathPaint;
|
|
1045
|
+
}
|
|
1046
|
+
/** The faces of the selection, and the commit that rebuilds it from a pick of them. */
|
|
1047
|
+
interface ShapeBuilderPlan {
|
|
1048
|
+
kind: 'faces';
|
|
1049
|
+
/** Back to front by the sources they cover, exclusives first. */
|
|
1050
|
+
faces: readonly ShapeBuilderFace[];
|
|
1051
|
+
/** The index of the face holding the world point, or -1. */
|
|
1052
|
+
faceAt(x: number, y: number): number;
|
|
1053
|
+
/**
|
|
1054
|
+
* Replace the selection with its faces, the `picked` ones united into one
|
|
1055
|
+
* path standing in for the source of the first one picked (`'merge'`) or
|
|
1056
|
+
* left out (`'delete'`). Every other face becomes a path of its own. One
|
|
1057
|
+
* undo step, and what it made is selected. Commits nothing for an empty pick.
|
|
1058
|
+
*/
|
|
1059
|
+
commit(picked: readonly number[], mode: ShapeBuilderMode): BooleanOpResult;
|
|
1060
|
+
}
|
|
1061
|
+
/**
|
|
1062
|
+
* The faces the selected paths cut each other into, or why there are none.
|
|
1063
|
+
* Reads the adapter and changes nothing; the plan's `commit` writes.
|
|
1064
|
+
*/
|
|
1065
|
+
declare function planShapeBuilder(adapter: BooleansAdapter, opts?: BooleanOpOptions): ShapeBuilderPlan | Exclude<BooleanOpResult, {
|
|
1066
|
+
kind: 'applied';
|
|
1067
|
+
}>;
|
|
1068
|
+
/**
|
|
1069
|
+
* The faces a run of world points passes through, each once, in the order
|
|
1070
|
+
* the run enters them. `step` is the world distance between the samples
|
|
1071
|
+
* taken along each segment; a face narrower than it can be stepped over.
|
|
1072
|
+
*/
|
|
1073
|
+
declare function facesAlong(plan: Pick<ShapeBuilderPlan, 'faceAt'>, run: readonly {
|
|
1074
|
+
x: number;
|
|
1075
|
+
y: number;
|
|
1076
|
+
}[], step: number): number[];
|
|
1077
|
+
|
|
1078
|
+
/** Options for `useShapeBuilderTool`. */
|
|
1079
|
+
interface UseShapeBuilderToolOptions {
|
|
1080
|
+
/** Override the default keybinding (`{ key: 'M', shift: true }`). Pass `null` to omit. */
|
|
1081
|
+
keybinding?: ToolKeybinding | null;
|
|
1082
|
+
/** What a stroked path gives the faces. Default `'unfilled'`, as the
|
|
1083
|
+
* Pathfinder actions: an unfilled stroke counts as the region it covers. */
|
|
1084
|
+
strokes?: BooleanStrokes;
|
|
1085
|
+
/** What a drag or a click does without Alt: unite the faces (`'merge'`, the
|
|
1086
|
+
* default) or delete them. With Alt it does the other. Read on every gesture. */
|
|
1087
|
+
mode?: ShapeBuilderMode;
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Shape builder. With two or more paths selected, the faces their outlines cut
|
|
1091
|
+
* each other into are what the tool works on: the face under the pointer is
|
|
1092
|
+
* shown, a drag unites every face it passes through into one path wearing the
|
|
1093
|
+
* paint of the first, and an Alt-drag deletes them (the other way round under
|
|
1094
|
+
* `mode: 'delete'`). A click takes the one face. Every face not taken becomes a path of its own, and each gesture is
|
|
1095
|
+
* one undo step. With fewer than two selected, a drag marquee-selects.
|
|
1096
|
+
*
|
|
1097
|
+
* It reads the `booleansAdapter` dep the Pathfinder actions do.
|
|
1098
|
+
*/
|
|
1099
|
+
declare function useShapeBuilderTool(options?: UseShapeBuilderToolOptions): Tool;
|
|
1100
|
+
|
|
1101
|
+
/** Options for `useGirthTool`. */
|
|
1102
|
+
interface UseGirthToolOptions {
|
|
1103
|
+
/** Override the default keybinding (`{ key: 'W', shift: true }`). Pass `null` to omit. */
|
|
1104
|
+
keybinding?: ToolKeybinding | null;
|
|
1105
|
+
/** Screen px around a stroke's edge within which a press takes hold of it,
|
|
1106
|
+
* and along the path within which it takes the anchor there rather than
|
|
1107
|
+
* inserting one. Default 6. */
|
|
1108
|
+
reach?: number;
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1111
|
+
* Girth tool: shapes a stroke's width along its length, into its
|
|
1112
|
+
* `vertexWidths`, by dragging the stroke's edges. Hovering near either edge
|
|
1113
|
+
* marks the grab point on it and the width point a press there moves: the
|
|
1114
|
+
* anchor at that spot, or a new one inserted between two, keeping the path's
|
|
1115
|
+
* shape. Dragging moves the grabbed edge along the path's normal, the other
|
|
1116
|
+
* edge mirroring it so the width stays centered; inward pinches it, down to
|
|
1117
|
+
* zero. With Alt held only the grabbed edge moves, writing a `{ left, right }`
|
|
1118
|
+
* pair. Either drag is live and one undo entry. Alt-click on a width point
|
|
1119
|
+
* clears it, so it takes the stroke's own width. The last stroke touched shows
|
|
1120
|
+
* its anchors, with a line across the stroke at each that has a width.
|
|
1121
|
+
*/
|
|
1122
|
+
declare function useGirthTool(options?: UseGirthToolOptions): Tool;
|
|
1123
|
+
|
|
1124
|
+
/** What the Girth tool's overlay shows, in world space: the anchors of the
|
|
1125
|
+
* stroke last hovered or pressed on, each with its unit normal toward its
|
|
1126
|
+
* right edge and its `vertexWidths` entry (`NaN` for none), and, over an
|
|
1127
|
+
* edge, the grab point on it and the width point a press there moves. */
|
|
1128
|
+
interface GirthFocus {
|
|
1129
|
+
anchors: readonly Point[];
|
|
1130
|
+
normals: readonly Point[];
|
|
1131
|
+
widths: readonly VertexWidth[];
|
|
1132
|
+
/** The stroke's own width, which an unset entry takes. */
|
|
1133
|
+
fallback: number;
|
|
1134
|
+
grab?: {
|
|
1135
|
+
edge: Point;
|
|
1136
|
+
at: Point;
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
/** The Girth tool's own state, shared by its actions and its overlay. */
|
|
1140
|
+
interface GirthEnv {
|
|
1141
|
+
focus(): GirthFocus | null;
|
|
1142
|
+
setFocus(next: GirthFocus | null): void;
|
|
1143
|
+
/** Screen px around a stroke's edge within which a press takes hold of it,
|
|
1144
|
+
* and along the path within which it takes the anchor there. */
|
|
1145
|
+
reachPx(): number;
|
|
1146
|
+
}
|
|
1147
|
+
/** Id of the action that drags a stroke's edge. */
|
|
1148
|
+
declare const GIRTH_DRAG_ID = "girth.drag";
|
|
1149
|
+
/** Id of the action that clears the width point under a click. */
|
|
1150
|
+
declare const GIRTH_CLEAR_ID = "girth.clear";
|
|
1151
|
+
/** Id of the action that marks the edge under a hover. */
|
|
1152
|
+
declare const GIRTH_HOVER_ID = "girth.hover";
|
|
1153
|
+
/** Id of the action that drops the hover mark when the pointer leaves. */
|
|
1154
|
+
declare const GIRTH_UNHOVER_ID = "girth.unhover";
|
|
1155
|
+
/**
|
|
1156
|
+
* The Girth tool's actions, which write a stroke's `vertexWidths`.
|
|
1157
|
+
* `girth.drag` takes hold of the stroke edge under the press, at the anchor
|
|
1158
|
+
* there or at one it inserts, shape kept, between two. The edge follows the
|
|
1159
|
+
* pointer along the path's normal, the other edge mirroring it so the width
|
|
1160
|
+
* stays centered; with Alt held only the grabbed edge moves, which writes a
|
|
1161
|
+
* `{ left, right }` pair. Either is live, and one undo entry. `girth.clear`
|
|
1162
|
+
* clears the width point under a click, so it takes the stroke's own width
|
|
1163
|
+
* again. `girth.hover` and `girth.unhover` show and hide the grab point under
|
|
1164
|
+
* the pointer.
|
|
1165
|
+
*/
|
|
1166
|
+
declare function createGirthActions(env: GirthEnv): Action[];
|
|
1167
|
+
|
|
1168
|
+
/**
|
|
1169
|
+
* A screen-space layer marking the width points of the stroke the Girth tool
|
|
1170
|
+
* last touched: a dot on each anchor, white where it has a width of its own,
|
|
1171
|
+
* with a line across the stroke from its left edge to its right. Over an
|
|
1172
|
+
* edge it adds the grab point on that edge, ringing the width point a press
|
|
1173
|
+
* there moves.
|
|
1174
|
+
*/
|
|
1175
|
+
declare function createGirthOverlay(source: {
|
|
1176
|
+
focus(): GirthFocus | null;
|
|
1177
|
+
subscribe(fn: () => void): () => void;
|
|
1178
|
+
}): RenderLayer<unknown>;
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* What the Girth tool reads and writes: the stroke edge under a point, the
|
|
1182
|
+
* width point a press on it moves — inserting an anchor where the press falls
|
|
1183
|
+
* between two — and the per-vertex widths a drag leaves behind.
|
|
1184
|
+
*/
|
|
1185
|
+
|
|
1186
|
+
/** A stroked path node and its centerline in world space. */
|
|
1187
|
+
interface WidthTarget {
|
|
1188
|
+
id: NodeId;
|
|
1189
|
+
node: SceneNode<unknown, string, unknown>;
|
|
1190
|
+
path: PolygonPath;
|
|
1191
|
+
stroke: Stroke;
|
|
1192
|
+
/** The stroke's own width in world units: what an unset entry takes. */
|
|
1193
|
+
fallback: number;
|
|
1194
|
+
}
|
|
1195
|
+
/** A stroke edge found under a point, and the width point a press there
|
|
1196
|
+
* moves: anchor `index`, or one inserted at `at` when `index` is null. */
|
|
1197
|
+
interface WidthEdgeHit {
|
|
1198
|
+
target: WidthTarget;
|
|
1199
|
+
edge: StrokeEdgeHit;
|
|
1200
|
+
index: number | null;
|
|
1201
|
+
at: Point;
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* The width point a drag edits, on a node's geometry as the press leaves it:
|
|
1205
|
+
* `path` gained an anchor at `index` when the press fell between two.
|
|
1206
|
+
*/
|
|
1207
|
+
interface WidthGrip {
|
|
1208
|
+
target: WidthTarget;
|
|
1209
|
+
/** The world path, with the inserted anchor if there is one. */
|
|
1210
|
+
path: PolygonPath;
|
|
1211
|
+
/** One entry per anchor of `path`; `NaN` takes the stroke's own width. */
|
|
1212
|
+
widths: VertexWidth[];
|
|
1213
|
+
index: number;
|
|
1214
|
+
at: Point;
|
|
1215
|
+
inserted: boolean;
|
|
1216
|
+
/** The edge taken hold of, and the unit normal it moves along. */
|
|
1217
|
+
side: StrokeSide;
|
|
1218
|
+
normal: Point;
|
|
1219
|
+
/** Each edge's distance from the path at the width point, before the drag. */
|
|
1220
|
+
start: HalfWidths;
|
|
1221
|
+
/** What the nib multiplies a stored width by there, so a drag moves the
|
|
1222
|
+
* edge as drawn. */
|
|
1223
|
+
factor: number;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
/** Spiro curves: path edit edits a spiro node's points and solves the curve
|
|
1227
|
+
* again through them (`spiroRepresentation`), `setSpiroKind` sets the kind
|
|
1228
|
+
* of the selected points, and `releaseSpiro` converts a spiro curve to an
|
|
1229
|
+
* ordinary path. `useSpiroTool` draws them. */
|
|
1230
|
+
declare const spiroPreset: FeaturePreset;
|
|
1231
|
+
|
|
1232
|
+
/** Options for {@link useSpiroTool}. */
|
|
1233
|
+
interface UseSpiroToolOptions {
|
|
1234
|
+
/** Select the new curve once it commits. Default `true`. */
|
|
1235
|
+
autoSelect?: boolean;
|
|
1236
|
+
/** Screen-px radius of "click the first point to close". Default `8`. */
|
|
1237
|
+
closeHitRadius?: number;
|
|
1238
|
+
}
|
|
1239
|
+
/**
|
|
1240
|
+
* Active-slot Tool that draws a spiro curve (`solveSpiro`) by placing its
|
|
1241
|
+
* on-curve points: each click places one, of the kind `params.kind` of the
|
|
1242
|
+
* `spiro.placePoint` action (default `'smooth'`; Alt-click places a corner),
|
|
1243
|
+
* and the preview solves the curve through the points and the cursor as it
|
|
1244
|
+
* moves. Clicking the first point of three or more closes the curve; Enter,
|
|
1245
|
+
* a double-click or Mod-click finishes it open; Backspace takes back the last
|
|
1246
|
+
* point and Escape discards them all, as does switching tools.
|
|
1247
|
+
*
|
|
1248
|
+
* The curve is inserted through the `insert` dep as a `'path'`, its spiro
|
|
1249
|
+
* form beside it on `data.representation`, so a consumer shapes the node by
|
|
1250
|
+
* overriding that dep. With `spiroPreset` on, path edit then edits its points
|
|
1251
|
+
* (`spiroRepresentation`).
|
|
1252
|
+
*/
|
|
1253
|
+
declare function useSpiroTool(options?: UseSpiroToolOptions): Tool;
|
|
1254
|
+
|
|
1255
|
+
/**
|
|
1256
|
+
* Commands on spiro curves (`spiroShape`): set the kind of the points
|
|
1257
|
+
* selected in path edit, and convert a spiro curve to an ordinary path.
|
|
1258
|
+
*/
|
|
1259
|
+
|
|
1260
|
+
/**
|
|
1261
|
+
* @experimental In path edit on a spiro curve, give the selected points the
|
|
1262
|
+
* kind `params.kind` (default `'smooth'`) and solve the curve again. One
|
|
1263
|
+
* variant per kind.
|
|
1264
|
+
*/
|
|
1265
|
+
declare const setSpiroKindAction: Action & {
|
|
1266
|
+
requires: string[];
|
|
1267
|
+
};
|
|
1268
|
+
/**
|
|
1269
|
+
* @experimental Convert the selected spiro curves, or the one in path edit, to
|
|
1270
|
+
* ordinary paths: the curve stays as drawn and its anchors and handles become
|
|
1271
|
+
* editable, while the spiro points stop being solved. Path edit's anchor
|
|
1272
|
+
* selection is cleared, since the anchors it numbered are gone.
|
|
1273
|
+
*/
|
|
1274
|
+
declare const releaseSpiroAction: Action & {
|
|
1275
|
+
requires: string[];
|
|
1276
|
+
};
|
|
1277
|
+
|
|
1278
|
+
/**
|
|
1279
|
+
* Spiro curves in path edit: a spiro node is edited through its straight-sided
|
|
1280
|
+
* control path, whose anchors are the curve's points, and every edit solves
|
|
1281
|
+
* the curve again through them. Each point draws by its kind, and a press on
|
|
1282
|
+
* the curve between two points adds one there.
|
|
1283
|
+
*/
|
|
1284
|
+
|
|
1285
|
+
/** How path edit reads and writes a spiro form. */
|
|
1286
|
+
declare const spiroRepresentation: PathRepresentation;
|
|
1287
|
+
/** The path-edit extension carrying {@link spiroRepresentation}. */
|
|
1288
|
+
declare const spiroExtension: PathEditExtension;
|
|
1289
|
+
|
|
1290
|
+
/**
|
|
1291
|
+
* How a spiro point is marked, by its kind: a circle for a smooth point, a
|
|
1292
|
+
* diamond for a g4 point, a square for a corner, and a half-disc for a point
|
|
1293
|
+
* beside a straight segment, its flat side toward the line.
|
|
1294
|
+
*/
|
|
1295
|
+
|
|
1296
|
+
/**
|
|
1297
|
+
* The marker shape of a spiro point of `kind`. A `left` point's line arrives
|
|
1298
|
+
* from its previous neighbor and a `right` point's leaves toward its next,
|
|
1299
|
+
* both in the same screen space; without that neighbor the half-disc faces
|
|
1300
|
+
* right.
|
|
1301
|
+
*/
|
|
1302
|
+
declare function spiroMarker(kind: SpiroKind): AnchorMarkerShape;
|
|
1303
|
+
|
|
1304
|
+
/** What the spiro tool has placed, as the preview reads it each frame. */
|
|
1305
|
+
interface SpiroPreviewState {
|
|
1306
|
+
points: readonly SpiroPoint[];
|
|
1307
|
+
/** Where the next point would go, or null while the pointer is away. */
|
|
1308
|
+
cursor: SpiroPoint | null;
|
|
1309
|
+
/** True while a click would close the curve on its first point. */
|
|
1310
|
+
closeHint: boolean;
|
|
1311
|
+
}
|
|
1312
|
+
/** Options for {@link createSpiroPreviewLayer}. */
|
|
1313
|
+
interface CreateSpiroPreviewLayerOptions {
|
|
1314
|
+
state: () => SpiroPreviewState;
|
|
1315
|
+
/** The color the curve and markers are drawn in. */
|
|
1316
|
+
color?: string;
|
|
1317
|
+
}
|
|
1318
|
+
/** Render layer drawing the spiro tool's curve in progress; nothing while
|
|
1319
|
+
* no point is placed. */
|
|
1320
|
+
declare function createSpiroPreviewLayer(opts: CreateSpiroPreviewLayerOptions): RenderLayer<unknown>;
|
|
1321
|
+
|
|
1322
|
+
/**
|
|
1323
|
+
* A spiro node: a path node whose `data.representation` is a spiro form,
|
|
1324
|
+
* saying its `data.path` is a solved spiro curve and which of the path's
|
|
1325
|
+
* anchors are the curve's points (`spiroToPath`). The path stays the geometry
|
|
1326
|
+
* every reader uses; path edit edits the points instead, through the
|
|
1327
|
+
* straight-sided control path, and each edit solves the curve again
|
|
1328
|
+
* (`spiroRepresentation`). Converting to a path drops the form.
|
|
1329
|
+
*/
|
|
1330
|
+
|
|
1331
|
+
/** The `kind` of a spiro form. */
|
|
1332
|
+
declare const SPIRO_FORM = "spiro";
|
|
1333
|
+
/** A spiro form, as `data.representation` holds it: each point's kind, and
|
|
1334
|
+
* the anchor of `data.path` it became. */
|
|
1335
|
+
type SpiroShape = {
|
|
1336
|
+
kind: typeof SPIRO_FORM;
|
|
1337
|
+
kinds: SpiroKind[];
|
|
1338
|
+
at: number[];
|
|
1339
|
+
};
|
|
1340
|
+
/** `form` as a spiro form, or null when it is not a well-formed one. */
|
|
1341
|
+
declare function asSpiro(form: unknown): SpiroShape | null;
|
|
1342
|
+
/** The spiro form a node's `data` holds, or `null`. */
|
|
1343
|
+
declare function spiroOf(data: unknown): SpiroShape | null;
|
|
1344
|
+
/** `data` without its spiro form: the curve as plain geometry. */
|
|
1345
|
+
declare function withoutSpiro<T>(data: T): T;
|
|
1346
|
+
/** The node data a solved spiro curve is stored as: its path, and the form
|
|
1347
|
+
* that says which anchors are points. */
|
|
1348
|
+
declare function spiroNodeData(contours: readonly SpiroContour[], like?: PolygonPath): {
|
|
1349
|
+
path: PolygonPath;
|
|
1350
|
+
representation: SpiroShape;
|
|
1351
|
+
};
|
|
1352
|
+
/** The contours `spiro` reads out of `path`, or null when it does not
|
|
1353
|
+
* describe it. */
|
|
1354
|
+
declare function spiroContours(path: PolygonPath, spiro: SpiroShape): SpiroContour[] | null;
|
|
1355
|
+
/** The straight-sided path through `spiro`'s points on `path`: what path
|
|
1356
|
+
* edit shows and moves. Null when `spiro` does not describe `path`. */
|
|
1357
|
+
declare function spiroEditPath(path: PolygonPath, spiro: SpiroShape): PolygonPath | null;
|
|
1358
|
+
/**
|
|
1359
|
+
* The curve an edit of the control path makes, solved through its anchors:
|
|
1360
|
+
* `control` is the edited control path, `path` the curve it was edited from.
|
|
1361
|
+
* Each point keeps its kind (`spiroContoursFromControl`). Null when `spiro`
|
|
1362
|
+
* does not describe `path`.
|
|
1363
|
+
*/
|
|
1364
|
+
declare function respiro(path: PolygonPath, spiro: SpiroShape, control: PolygonPath): {
|
|
1365
|
+
path: PolygonPath;
|
|
1366
|
+
spiro: SpiroShape;
|
|
1367
|
+
} | null;
|
|
1368
|
+
/** The curve `path` makes with the points at `flatIndexes` set to `kind`. Null
|
|
1369
|
+
* when `spiro` does not describe `path`, or no kind changes. */
|
|
1370
|
+
declare function respiroWithKind(path: PolygonPath, spiro: SpiroShape, flatIndexes: Iterable<number>, kind: SpiroKind): {
|
|
1371
|
+
path: PolygonPath;
|
|
1372
|
+
spiro: SpiroShape;
|
|
1373
|
+
} | null;
|
|
1374
|
+
|
|
1375
|
+
/**
|
|
1376
|
+
* Path constraints in path edit: their marks on the open path, a click
|
|
1377
|
+
* selecting one, Delete removing it, and every edit finished so they hold.
|
|
1378
|
+
*/
|
|
1379
|
+
|
|
1380
|
+
/** Owner id of the constraint marks, as `EditAnchorsDep.selectedMark` names them. */
|
|
1381
|
+
declare const CONSTRAINTS_EXTENSION_ID = "constraints";
|
|
1382
|
+
/**
|
|
1383
|
+
* Replace the open path's constraints with `constraints` as one history
|
|
1384
|
+
* entry, moving it the least that makes them all hold. When they cannot all
|
|
1385
|
+
* hold the path stays as it is and the list is stored all the same, the
|
|
1386
|
+
* conflict left for the marks to show. Clears the selected mark, since the
|
|
1387
|
+
* list is renumbered. Answers the indices in conflict, as
|
|
1388
|
+
* `constraintConflictsOf` names them — empty when every one holds — or null
|
|
1389
|
+
* when the dep cannot store.
|
|
1390
|
+
*/
|
|
1391
|
+
declare function setConstraints(dep: EditAnchorsDep, constraints: readonly PathConstraint[], label: string): number[] | null;
|
|
1392
|
+
/** The constraint selected in path edit, as an index into the open path's list, or null. */
|
|
1393
|
+
declare function selectedConstraintOf(dep: EditAnchorsDep): number | null;
|
|
1394
|
+
/** The constraints extension, its marks drawn in `style`'s colors. */
|
|
1395
|
+
declare function createConstraintsExtension(style?: Partial<ConstraintGlyphStyle>): PathEditExtension;
|
|
1396
|
+
|
|
1397
|
+
/**
|
|
1398
|
+
* Constraints between nodes. A link is a node of its own: its `dependsOn`
|
|
1399
|
+
* names the nodes it ties, in order, and its `data.constraintLink` holds one
|
|
1400
|
+
* `PathConstraint` whose anchors are numbered over theirs one after another —
|
|
1401
|
+
* with two nodes of 4 and 5 anchors, anchor 6 is the second node's anchor 2.
|
|
1402
|
+
* Being a node, it is saved and undone with the scene, and deleting a node it
|
|
1403
|
+
* ties deletes it too. It draws nothing and takes no clicks; keep it on a
|
|
1404
|
+
* layer that is not exported, such as an annotation layer.
|
|
1405
|
+
*
|
|
1406
|
+
* An edit of any node a link ties solves every node the links reach in one
|
|
1407
|
+
* solve: an anchor held on another node's segment slides along it when
|
|
1408
|
+
* dragged and follows it when that node is edited.
|
|
1409
|
+
*/
|
|
1410
|
+
|
|
1411
|
+
/** What a link node keeps in `data`. */
|
|
1412
|
+
interface ConstraintLinkData {
|
|
1413
|
+
constraintLink: PathConstraint;
|
|
1414
|
+
}
|
|
1415
|
+
/** The constraint `data` holds as a link, or null when it is not one. */
|
|
1416
|
+
declare function constraintLinkOf(data: unknown): PathConstraint | null;
|
|
1417
|
+
/** Options for {@link constraintLinkNode}. */
|
|
1418
|
+
interface ConstraintLinkNodeOptions<TPose> {
|
|
1419
|
+
layer: string;
|
|
1420
|
+
/** The nodes it ties, in the order its anchors number them. */
|
|
1421
|
+
nodes: readonly string[];
|
|
1422
|
+
constraint: PathConstraint;
|
|
1423
|
+
id?: string;
|
|
1424
|
+
/** Default: an empty box at the origin. */
|
|
1425
|
+
pose?: TPose;
|
|
1426
|
+
}
|
|
1427
|
+
/** A link node, ready for `scene.add`. Registers the painter that keeps link nodes from drawing. */
|
|
1428
|
+
declare function constraintLinkNode<TPose = RectPose>(opts: ConstraintLinkNodeOptions<TPose>): AddNodeSpec<ConstraintLinkData, string, TPose>;
|
|
1429
|
+
|
|
1430
|
+
/**
|
|
1431
|
+
* The controls for the selected corners of a path in edit: a schema any
|
|
1432
|
+
* prefs form draws, the values and mixed fields it shows for a selection,
|
|
1433
|
+
* and the `setCorners` params a change to one of them makes.
|
|
1434
|
+
*/
|
|
1435
|
+
|
|
1436
|
+
/** How far the parameter slider reaches either side of the bevel; the
|
|
1437
|
+
* `square` and `notch` keywords stand for the two infinities beyond it. */
|
|
1438
|
+
declare const CORNER_K_SLIDER_RANGE = 4;
|
|
1439
|
+
/** What the corner controls ask for while no corner is selected. */
|
|
1440
|
+
declare const CORNER_CONTROLS_PROMPT = "Click a corner anchor (Shift-click for more) to edit it";
|
|
1441
|
+
/** The corner controls as a prefs schema: the keywords, the parameter, and
|
|
1442
|
+
* the radius, each disabled while no corner is selected. */
|
|
1443
|
+
declare const CORNER_CONTROLS: PrefGroup;
|
|
1444
|
+
/** What the controls show for a selection. */
|
|
1445
|
+
interface CornerControlsState {
|
|
1446
|
+
/** `shape` is null where no keyword applies, so a form does not fall back
|
|
1447
|
+
* to the leaf's default. */
|
|
1448
|
+
values: {
|
|
1449
|
+
count: number;
|
|
1450
|
+
shape: CornerKeyword | null;
|
|
1451
|
+
k?: number;
|
|
1452
|
+
radius?: number;
|
|
1453
|
+
};
|
|
1454
|
+
/** The fields whose selected corners disagree. */
|
|
1455
|
+
mixed: ReadonlySet<string>;
|
|
1456
|
+
}
|
|
1457
|
+
/** The controls for the corners of `path` among `selected` anchors. A sharp
|
|
1458
|
+
* corner shows no shape and no parameter. */
|
|
1459
|
+
declare function cornerControlsState(path: PolygonPath | null, selected: ReadonlySet<number>): CornerControlsState;
|
|
1460
|
+
/** The `setCorners` params a change of `field` to `value` makes, or null for
|
|
1461
|
+
* a field that sets nothing. */
|
|
1462
|
+
declare function cornerControlsParams(field: string, value: unknown): {
|
|
1463
|
+
shape: CornerShape;
|
|
1464
|
+
} | {
|
|
1465
|
+
radius: number;
|
|
1466
|
+
} | null;
|
|
1467
|
+
|
|
1468
|
+
/** The part of a scene the controls read. */
|
|
1469
|
+
interface CornerControlsScene {
|
|
1470
|
+
get(id: NodeId): EditableShape | undefined;
|
|
1471
|
+
subscribe(listener: () => void): () => void;
|
|
1472
|
+
}
|
|
1473
|
+
/** Which path is open for anchor editing and which of its anchors are
|
|
1474
|
+
* selected: what a `PathEditHost` that owns the anchor selection knows. */
|
|
1475
|
+
interface CornerControlsSelection {
|
|
1476
|
+
editingId(): string | null;
|
|
1477
|
+
selectedAnchors(): ReadonlySet<number>;
|
|
1478
|
+
subscribe(listener: () => void): () => void;
|
|
1479
|
+
}
|
|
1480
|
+
/** What {@link useCornerControls} gives a corner panel to draw. */
|
|
1481
|
+
interface UseCornerControlsReturn {
|
|
1482
|
+
/** The schema a prefs form draws: `CORNER_CONTROLS`. Its `name` is the
|
|
1483
|
+
* controls' title. */
|
|
1484
|
+
schema: typeof CORNER_CONTROLS;
|
|
1485
|
+
/** What to show above the form, or null once a corner is selected. */
|
|
1486
|
+
prompt: string | null;
|
|
1487
|
+
values: Record<string, unknown>;
|
|
1488
|
+
mixed: ReadonlySet<string>;
|
|
1489
|
+
/** A prefs form's `onChange` for `CORNER_CONTROLS`. */
|
|
1490
|
+
onChange: (field: string, value: unknown) => void;
|
|
1491
|
+
}
|
|
1492
|
+
/**
|
|
1493
|
+
* A corner panel over the selected corners of the path open for anchor
|
|
1494
|
+
* editing: their shared shape and radius, kept current as the scene or the
|
|
1495
|
+
* selection changes, and an `onChange` that writes through `setCorners`.
|
|
1496
|
+
*/
|
|
1497
|
+
declare function useCornerControls(scene: CornerControlsScene, selection: CornerControlsSelection): UseCornerControlsReturn;
|
|
1498
|
+
|
|
1499
|
+
/**
|
|
1500
|
+
* A node's path constraints: kept as `data.constraints`, numbered by the
|
|
1501
|
+
* anchors of its editable polygon, and solved in the frame that polygon is
|
|
1502
|
+
* drawn in, so `horizontal` on a rotated `data.path` node turns with it.
|
|
1503
|
+
*/
|
|
1504
|
+
|
|
1505
|
+
/** The constraints a node's data holds, or none. */
|
|
1506
|
+
declare function constraintsOf(data: unknown): readonly PathConstraint[];
|
|
1507
|
+
/** Radians the frame `horizontal` and `vertical` read is turned from the world's: a `data.path` node's rotation. */
|
|
1508
|
+
declare function constraintAxisOf(node: EditableShape | null | undefined): number;
|
|
1509
|
+
/**
|
|
1510
|
+
* Indices of `node`'s constraints that do not hold in its committed path, and
|
|
1511
|
+
* the others each conflict needs: every member of a smallest set that cannot
|
|
1512
|
+
* all hold. Edits leave the ones that do not hold out of the solve, and so
|
|
1513
|
+
* does a whole-shape transform — resize, rotate, flip — which carries the
|
|
1514
|
+
* list unchanged: a constraint the transform breaks, such as a set length
|
|
1515
|
+
* under a scale or an equal length under a non-uniform one, is reported here
|
|
1516
|
+
* rather than solved back.
|
|
1517
|
+
*/
|
|
1518
|
+
declare function constraintConflictsOf(node: EditableShape | null | undefined): number[];
|
|
1519
|
+
|
|
1520
|
+
/** A glyph this package draws, by its bare name. */
|
|
1521
|
+
type PathToolsIconName = 'smudgeBrush' | 'distort' | 'envelope' | 'puppetWarp' | 'blend' | 'bendAlong' | 'repeatAlong' | 'expand' | 'balanceHandles' | 'equalizeHandles' | 'lengthen' | 'trim' | 'extend' | 'girth' | 'spiro' | 'reversePath' | 'setPathStart' | 'cornerRadius' | 'cornerShape' | 'convertSegment' | 'straightenSegment' | 'curveSegment' | 'extremeAnchors';
|
|
1522
|
+
declare module '@weasel-js/icons' {
|
|
1523
|
+
interface IconName {
|
|
1524
|
+
'path-tools:smudgeBrush': true;
|
|
1525
|
+
'path-tools:distort': true;
|
|
1526
|
+
'path-tools:envelope': true;
|
|
1527
|
+
'path-tools:puppetWarp': true;
|
|
1528
|
+
'path-tools:blend': true;
|
|
1529
|
+
'path-tools:bendAlong': true;
|
|
1530
|
+
'path-tools:repeatAlong': true;
|
|
1531
|
+
'path-tools:expand': true;
|
|
1532
|
+
'path-tools:balanceHandles': true;
|
|
1533
|
+
'path-tools:equalizeHandles': true;
|
|
1534
|
+
'path-tools:lengthen': true;
|
|
1535
|
+
'path-tools:trim': true;
|
|
1536
|
+
'path-tools:extend': true;
|
|
1537
|
+
'path-tools:girth': true;
|
|
1538
|
+
'path-tools:spiro': true;
|
|
1539
|
+
'path-tools:reversePath': true;
|
|
1540
|
+
'path-tools:setPathStart': true;
|
|
1541
|
+
'path-tools:cornerRadius': true;
|
|
1542
|
+
'path-tools:cornerShape': true;
|
|
1543
|
+
'path-tools:convertSegment': true;
|
|
1544
|
+
'path-tools:straightenSegment': true;
|
|
1545
|
+
'path-tools:curveSegment': true;
|
|
1546
|
+
'path-tools:extremeAnchors': true;
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
export { ANCHOR_SELECTION_GROUP, CONSTRAINTS_EXTENSION_ID, CORNER_CONTROLS, CORNER_CONTROLS_PROMPT, CORNER_K_SLIDER_RANGE, CORNER_WIDGET_STANDOFF_PX, type ConstrainAnchorsParams, type ConstraintGlyphStyle, type ConstraintLinkData, type ConstraintLinkNodeOptions, type CornerControlsScene, type CornerControlsSelection, type CornerControlsState, type CornerWidgetStyle, type CreateSpiroPreviewLayerOptions, DEFAULT_BRIDGE_TENSION, DEFAULT_CORNER_SHAPE, DEFAULT_CORNER_TRIM_SHARE, DEFAULT_ENVELOPE_SIZE, DEFAULT_SMUDGE_RADIUS_PX, DEFAULT_SMUDGE_STRENGTH, DEFAULT_WARP_TOLERANCE, GIRTH_CLEAR_ID, GIRTH_DRAG_ID, GIRTH_HOVER_ID, GIRTH_UNHOVER_ID, type GirthEnv, type GirthFocus, type HandleSnapOptions, type HandleSnapOptionsInput, type HeldPathWarp, LENGTHEN_TOOL, type LengthenPathParams, PATH_BALANCE_CHROME_ID, PATH_COMB_CHROME_ID, PATH_CORNERS_CHROME_ID, PATH_DIRECTION_CHROME_ID, PATH_EFFECTS_GROUP, type PathDirectionStyle, type PathEditBalanceStyle, type PathEditCombOptions, type PathToolsIconName, type ResamplePathParams, type ResolvedPathWarp, SIMPLIFY_BRUSH_RADIUS_PX, SIMPLIFY_BRUSH_TOOL, SPIRO_FORM, type ShapeBuilderFace, type ShapeBuilderMode, type ShapeBuilderPlan, type SimplifyBrushParams, type SmudgeBrushParams, type SoftSelectionOptions, type SpiroPreviewState, type SpiroShape, type StrokeClickToolOptions, type UseCornerControlsReturn, type UseDistortToolOptions, type UseEnvelopeToolOptions, type UseExtendToolOptions, type UseGirthToolOptions, type UsePuppetToolOptions, type UseShapeBuilderToolOptions, type UseSmudgeBrushToolOptions, type UseSpiroToolOptions, type UseTrimToolOptions, type WarpHandleScratch, type WarpKind, type WarpSettings, type WarpTool, type WarpToolOptions, type WidthEdgeHit, type WidthGrip, type WidthTarget, addExtremeAnchorsAction, addExtremesPreset, anchorSelectionPreset, asSpiro, balanceCommands, balanceHandlesAction, balancePreset, bendAlongAction, blendAction, bridgeAnchorsAction, bridgePathsAction, bridgePreset, bridgeTensionOf, brushRingCursor, combCommands, configureWarpAction, constrainAnchorsAction, constraintAxisOf, constraintConflictsOf, constraintLinkNode, constraintLinkOf, constraintsForAnchors, constraintsOf, constraintsPreset, convertSegmentAtAction, convertSegmentsAction, cornerControlsParams, cornerControlsState, cornerShapePreset, cornerWidgetCommands, cornerWidgetFrames, createBalanceExtension, createBalancePreset, createCombExtension, createConstraintsExtension, createConstraintsPreset, createCornerShapePreset, createCornerWidgetsExtension, createCurvatureCombPreset, createDirectionExtension, createGirthActions, createGirthOverlay, createHandleSnapExtension, createHandleSnapPreset, createPathStructurePreset, createSoftSelectionExtension, createSoftSelectionPreset, createSpiroPreviewLayer, curvatureCombPreset, cycleCornerShapeAction, deleteConstraintAction, directionCommands, editCornerAction, editPathEffectAction, equalizeHandlesAction, expandPathEffectAction, expandWarpAction, extendPreset, extendToMeetAction, facesAlong, growAnchorSelectionAction, handleLockAngleAction, handleLockLengthAction, handleLocksPreset, handleSnapPreset, handleSnapSource, harmonizeAnchorsAction, harmonizePreset, heldPathWarpOf, invertAnchorSelectionAction, lengthenPathAction, lengthenPreset, lengthenToolAction, pathEffectsPreset, pathStructurePreset, pathTools, planShapeBuilder, planTrim, releaseSpiroAction, repeatAlongAction, resamplePathAction, resamplePreset, resolvePathWarp, respiro, respiroWithKind, reversePathAction, segmentTypePreset, selectCornerAnchorsAction, selectEveryNthAnchorAction, selectSmoothAnchorsAction, selectedConstraintOf, setConstraints, setCornersAction, setPathStartAction, setSpiroKindAction, shrinkAnchorSelectionAction, simplifyBrushAction, simplifyBrushPreset, simplifyBrushToolAction, smudgeBrushAction, smudgePreset, spiroContours, spiroEditPath, spiroExtension, spiroMarker, spiroNodeData, spiroOf, spiroPreset, spiroRepresentation, trimPathAction, trimPreset, unconstrainAnchorsAction, useCornerControls, useDistortTool, useEnvelopeTool, useExtendTool, useGirthTool, usePuppetTool, useShapeBuilderTool, useSmudgeBrushTool, useSpiroTool, useTrimTool, warpHandleScratchOf, warpLayerId, warpPreset, withPathWarp, withoutPathWarp, withoutSpiro };
|