@weasel-js/path-tools 0.0.0-stage → 1.10.1
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 +47 -2
- package/dist/index.d.ts +713 -0
- package/dist/index.js +1730 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -4
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,713 @@
|
|
|
1
|
+
import { PathEditExtension, FeaturePreset, EditableShape, BlendEffect, BendAlongEffect, RepeatAlongEffect, PathNode, Tool, SurfaceContribution, EditAnchorsDep } from '@weasel-js/core';
|
|
2
|
+
import { DrawCommand } from '@weasel-js/renderer';
|
|
3
|
+
import { AnchorSet, PathConstraintKind, PolygonPath, PathConstraint, PathWarp, Affine, DistortMode, EnvelopeMapping, TrimResult } 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
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The balance lines path edit can draw over the open path: one per curved
|
|
11
|
+
* segment, from its first handle's tip to its second's, with the grip
|
|
12
|
+
* `balanceHandles` drags at the middle, pressed as `balance:N`.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** Chrome-caps id the balance lines and their grips are drawn and hit-tested
|
|
16
|
+
* under. Off by default. */
|
|
17
|
+
declare const PATH_BALANCE_CHROME_ID = "path-edit.balance";
|
|
18
|
+
/** How the balance lines are drawn. */
|
|
19
|
+
interface PathEditBalanceStyle {
|
|
20
|
+
/** Color of the line between a segment's handle tips and of its grip's rim. */
|
|
21
|
+
color?: string;
|
|
22
|
+
/** Fill of the grip. */
|
|
23
|
+
gripFill?: string;
|
|
24
|
+
/** Radius of the grip, in screen px. Default 4. */
|
|
25
|
+
gripRadiusPx?: number;
|
|
26
|
+
}
|
|
27
|
+
type ToScreen$1 = (p: {
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
}) => {
|
|
31
|
+
x: number;
|
|
32
|
+
y: number;
|
|
33
|
+
};
|
|
34
|
+
/** Draw commands for `set`'s balance lines and their grips, in screen space. */
|
|
35
|
+
declare function balanceCommands(set: AnchorSet, toScreen: ToScreen$1, style?: PathEditBalanceStyle): DrawCommand[];
|
|
36
|
+
/** The balance lines as a path-edit extension: drawn, and their grips
|
|
37
|
+
* pressed, while chrome-caps shows {@link PATH_BALANCE_CHROME_ID}. */
|
|
38
|
+
declare function createBalanceExtension(style?: PathEditBalanceStyle): PathEditExtension;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The curvature comb path edit can draw over the open path.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/** Chrome-caps id the curvature comb is drawn under. Off by default. */
|
|
45
|
+
declare const PATH_COMB_CHROME_ID = "path-edit.comb";
|
|
46
|
+
/** How the curvature comb is drawn. */
|
|
47
|
+
interface PathEditCombOptions {
|
|
48
|
+
/** Tooth length per unit of curvature, in world units: a tooth over a
|
|
49
|
+
* stretch of radius r is `scale / r` long. Default 2000. */
|
|
50
|
+
scale?: number;
|
|
51
|
+
/** Teeth per segment, ends included. Default 24. */
|
|
52
|
+
samplesPerSegment?: number;
|
|
53
|
+
/** Color of the teeth and of the line through their tips. */
|
|
54
|
+
color?: string;
|
|
55
|
+
}
|
|
56
|
+
type ToScreen = (p: {
|
|
57
|
+
x: number;
|
|
58
|
+
y: number;
|
|
59
|
+
}) => {
|
|
60
|
+
x: number;
|
|
61
|
+
y: number;
|
|
62
|
+
};
|
|
63
|
+
/** Draw commands for `set`'s curvature comb, in screen space. */
|
|
64
|
+
declare function combCommands(set: AnchorSet, toScreen: ToScreen, opts?: PathEditCombOptions): DrawCommand[];
|
|
65
|
+
/** The comb as a path-edit extension, drawn while chrome-caps shows
|
|
66
|
+
* {@link PATH_COMB_CHROME_ID}. `options` is read every frame. */
|
|
67
|
+
declare function createCombExtension(options?: () => PathEditCombOptions | undefined): PathEditExtension;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The small marks the path-edit overlay draws for a path's constraints, in
|
|
71
|
+
* screen pixels, and where a click finds them: a letter beside a horizontal
|
|
72
|
+
* or vertical segment, paired strokes beside parallel ones, a foot beside
|
|
73
|
+
* perpendicular ones, ticks across equal ones, a dimension bar beside a fixed
|
|
74
|
+
* length, a pin by a fixed anchor, and a ring by coincident ones. Marks sit
|
|
75
|
+
* on the inside of the shape, toward the centroid of its anchors, so a click
|
|
76
|
+
* on one lands on the shape rather than on empty canvas.
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
/** Colors for the constraint marks. */
|
|
80
|
+
interface ConstraintGlyphStyle {
|
|
81
|
+
/** A constraint that holds. */
|
|
82
|
+
stroke: string;
|
|
83
|
+
/** One that does not: it conflicts with the others. */
|
|
84
|
+
conflictStroke: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The package's behavior as `<SceneCanvas features>` presets: one per tool
|
|
89
|
+
* family, and `pathTools` for all of them. Each assumes core's `paths`
|
|
90
|
+
* preset, which opens a path for editing.
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/** The Simplify brush, a path-edit tool that refits the curve it passes over. */
|
|
94
|
+
declare const simplifyBrushPreset: FeaturePreset;
|
|
95
|
+
/** The `handleLock.angle` and `handleLock.length` toggles. */
|
|
96
|
+
declare const handleLocksPreset: FeaturePreset;
|
|
97
|
+
/** Bridge, on whole paths and on two selected anchors. */
|
|
98
|
+
declare const bridgePreset: FeaturePreset;
|
|
99
|
+
/** `trimPath`, which `useTrimTool` binds. */
|
|
100
|
+
declare const trimPreset: FeaturePreset;
|
|
101
|
+
/** `extendToMeet`, which `useExtendTool` binds. */
|
|
102
|
+
declare const extendPreset: FeaturePreset;
|
|
103
|
+
/** `smudgeBrush`, which `useSmudgeBrushTool` binds. */
|
|
104
|
+
declare const smudgePreset: FeaturePreset;
|
|
105
|
+
/** Harmonize curvature. */
|
|
106
|
+
declare const harmonizePreset: FeaturePreset;
|
|
107
|
+
/** The curvature comb over the open path, drawn as `options` says, read every
|
|
108
|
+
* frame. Off until chrome-caps shows `path-edit.comb`. */
|
|
109
|
+
declare function createCurvatureCombPreset(options?: () => PathEditCombOptions | undefined): FeaturePreset;
|
|
110
|
+
/** The curvature comb with its default look. */
|
|
111
|
+
declare const curvatureCombPreset: FeaturePreset;
|
|
112
|
+
/**
|
|
113
|
+
* Balance handles: a line between each curved segment's handle tips with a
|
|
114
|
+
* grip to drag (`balanceHandles`) or double-click (`equalizeHandles`), drawn
|
|
115
|
+
* in `style`. Off until chrome-caps shows `path-edit.balance`. It refines
|
|
116
|
+
* `paths`, so a grip's double-click goes ahead of entering path edit.
|
|
117
|
+
*/
|
|
118
|
+
declare function createBalancePreset(style?: PathEditBalanceStyle): FeaturePreset;
|
|
119
|
+
/** Balance handles with their default look. */
|
|
120
|
+
declare const balancePreset: FeaturePreset;
|
|
121
|
+
/** Path constraints: their actions, their marks in `style`'s colors, and
|
|
122
|
+
* every edit of a constrained path finished so they hold. */
|
|
123
|
+
declare function createConstraintsPreset(style?: Partial<ConstraintGlyphStyle>): FeaturePreset;
|
|
124
|
+
/** Path constraints with their default colors. */
|
|
125
|
+
declare const constraintsPreset: FeaturePreset;
|
|
126
|
+
/** Blend, Bend along, and Repeat along, live, and the actions that edit and
|
|
127
|
+
* expand them. The scene must hold `withPathEffectsRegistry`'s derivations. */
|
|
128
|
+
declare const pathEffectsPreset: FeaturePreset;
|
|
129
|
+
/** `expandWarp` and `configureWarp`; the warp tools bring their own drags. */
|
|
130
|
+
declare const warpPreset: FeaturePreset;
|
|
131
|
+
/** Every preset above, the comb, balance, and constraints with their defaults. */
|
|
132
|
+
declare const pathTools: FeaturePreset;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Add and remove geometric constraints on the anchors selected in path edit.
|
|
136
|
+
* Neither has a default binding: a consumer binds each kind it offers, with
|
|
137
|
+
* the kind as a param (see `<SceneCanvas tune>`).
|
|
138
|
+
*/
|
|
139
|
+
|
|
140
|
+
/** Params for `constrainAnchors`. */
|
|
141
|
+
interface ConstrainAnchorsParams {
|
|
142
|
+
kind: PathConstraintKind;
|
|
143
|
+
/** For `length`: the length to hold. Default: each pair's length now. */
|
|
144
|
+
length?: number;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The constraints of `kind` that `anchors`, in the order they were selected,
|
|
148
|
+
* ask for: each anchor for `fixed`; each consecutive pair for `horizontal`,
|
|
149
|
+
* `vertical`, `length`, and `coincident`; and for the kinds relating two
|
|
150
|
+
* segments, three anchors as two segments sharing the middle one or four as
|
|
151
|
+
* two pairs. Empty when the anchors cannot make that kind.
|
|
152
|
+
*/
|
|
153
|
+
declare function constraintsForAnchors(kind: PathConstraintKind, anchors: readonly number[], path: PolygonPath, length?: number): PathConstraint[];
|
|
154
|
+
/**
|
|
155
|
+
* Delete the constraint selected in path edit, as a command. Delete and
|
|
156
|
+
* Backspace reach it through `deleteAnchors`, which deletes whichever of the
|
|
157
|
+
* two is selected, so the keys have one binding.
|
|
158
|
+
*/
|
|
159
|
+
declare const deleteConstraintAction: Action & {
|
|
160
|
+
requires: string[];
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Constrain the selected anchors: params `{ kind, length? }`, read as
|
|
164
|
+
* {@link constraintsForAnchors} reads them. The path moves the least that
|
|
165
|
+
* makes every constraint hold; a constraint that conflicts with the rest is
|
|
166
|
+
* kept all the same, left unsolved, and shown as a conflict.
|
|
167
|
+
*/
|
|
168
|
+
declare const constrainAnchorsAction: Action & {
|
|
169
|
+
requires: string[];
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Remove the constraints whose anchors are all selected — only those of
|
|
173
|
+
* `kind` when the params name one.
|
|
174
|
+
*/
|
|
175
|
+
declare const unconstrainAnchorsAction: Action & {
|
|
176
|
+
requires: string[];
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/** The path-edit tool under which a plain drag brushes. */
|
|
180
|
+
declare const SIMPLIFY_BRUSH_TOOL = "simplifyBrush";
|
|
181
|
+
/** The brush's radius on screen when no param names one. */
|
|
182
|
+
declare const SIMPLIFY_BRUSH_RADIUS_PX = 12;
|
|
183
|
+
/** Params the brush reads on every move, so a thunk can change them mid-stroke. */
|
|
184
|
+
interface SimplifyBrushParams {
|
|
185
|
+
/** Brush radius in screen pixels. */
|
|
186
|
+
radiusPx?: number;
|
|
187
|
+
/** How far the refit may stray from the original, in world units, as for
|
|
188
|
+
* the Simplify command. */
|
|
189
|
+
tolerance?: number;
|
|
190
|
+
}
|
|
191
|
+
/** The kit's brush-ring cursor drawn `radiusPx` in radius on screen. */
|
|
192
|
+
declare function brushRingCursor(radiusPx: number): CursorSpec;
|
|
193
|
+
/**
|
|
194
|
+
* The Simplify command, brushed on. While path edit's
|
|
195
|
+
* `simplifyBrush` tool is on, a plain drag gathers every anchor a round brush
|
|
196
|
+
* passes over, and each unbroken stretch of them along a subpath is refitted
|
|
197
|
+
* as one span by Simplify's own fitter (`simplifyAnchorsAt`) at `tolerance`.
|
|
198
|
+
* Only anchors the shape does not need go, so brushing again goes further.
|
|
199
|
+
* The path previews the result while the brush is down and commits as one
|
|
200
|
+
* undo step on release.
|
|
201
|
+
*/
|
|
202
|
+
declare const simplifyBrushAction: Action & {
|
|
203
|
+
requires: string[];
|
|
204
|
+
};
|
|
205
|
+
/** The bar toggle for the brush: `pathEditTool.simplifyBrush`. */
|
|
206
|
+
declare const simplifyBrushToolAction: Action & {
|
|
207
|
+
requires: string[];
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* The Smudge brush's drag: the selected paths' outlines under a round brush
|
|
212
|
+
* follow the pointer, as one undo entry per stroke.
|
|
213
|
+
*/
|
|
214
|
+
|
|
215
|
+
/** The brush's radius in screen px when no param gives one. */
|
|
216
|
+
declare const DEFAULT_SMUDGE_RADIUS_PX = 40;
|
|
217
|
+
/** How much of the pointer's motion the outline under the brush's center follows,
|
|
218
|
+
* when no param gives it. */
|
|
219
|
+
declare const DEFAULT_SMUDGE_STRENGTH = 0.6;
|
|
220
|
+
/** The params `smudgeBrush` reads, each on every pointer move. */
|
|
221
|
+
interface SmudgeBrushParams {
|
|
222
|
+
/** The brush's radius, in screen px. */
|
|
223
|
+
radiusPx?: number;
|
|
224
|
+
/** `1` moves the outline under the brush's center as far as the pointer; less, less. */
|
|
225
|
+
strength?: number;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* @experimental A drag that pushes the outline of every selected path along with
|
|
229
|
+
* the pointer (`smudgePath` in `@weasel-js/geom`). Each pointer move is one dab from
|
|
230
|
+
* where the last one ended: points under the brush move with it, most at its center
|
|
231
|
+
* and not at all at its rim, and a long segment the brush meets gets anchors added
|
|
232
|
+
* so it can bend there. `params.radiusPx` is the brush's radius on screen, so it
|
|
233
|
+
* covers the same part of the canvas at every zoom, and `params.strength` how closely
|
|
234
|
+
* the outline follows; both are read on every move. The cursor is a ring the size of
|
|
235
|
+
* the brush. The stroke commits as one undo entry; canceling it leaves the paths as
|
|
236
|
+
* they were.
|
|
237
|
+
*/
|
|
238
|
+
declare const smudgeBrushAction: Action & {
|
|
239
|
+
requires: string[];
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* A warp a node is holding: the path it warped, the warp, and the tolerance
|
|
244
|
+
* the result was refitted to, kept on the node as `data.warp` beside the
|
|
245
|
+
* `data.path` (or polygon pose) they produced. The geometry stays what every
|
|
246
|
+
* reader uses; the warp only says how to make it again, so it can be edited
|
|
247
|
+
* until it is expanded away.
|
|
248
|
+
*
|
|
249
|
+
* The warp lives in its own frame, fixed when it was made. `frame` carries
|
|
250
|
+
* that frame onto the stored path, so moving, resizing or rotating the node
|
|
251
|
+
* keeps the warp without touching it. A writer that changes the geometry some
|
|
252
|
+
* other way leaves a warp that no longer reproduces it, and such a warp is
|
|
253
|
+
* ignored, the way a stale shape generator is.
|
|
254
|
+
*/
|
|
255
|
+
|
|
256
|
+
/** What `data.warp` holds. */
|
|
257
|
+
interface HeldPathWarp {
|
|
258
|
+
/** Shared by every node warped together, so one handle drives them all. */
|
|
259
|
+
id: string;
|
|
260
|
+
/** The path before warping, in the warp's frame. */
|
|
261
|
+
source: PolygonPath;
|
|
262
|
+
warp: PathWarp;
|
|
263
|
+
/** How far the refitted result may stray from the exact warp. */
|
|
264
|
+
tolerance: number;
|
|
265
|
+
/** From the warp's frame to the frame the node stores its path in. */
|
|
266
|
+
frame: Affine;
|
|
267
|
+
}
|
|
268
|
+
/** A held warp that still reproduces its node, and where its frame lands in
|
|
269
|
+
* world space now. */
|
|
270
|
+
interface ResolvedPathWarp {
|
|
271
|
+
held: HeldPathWarp;
|
|
272
|
+
/** From the warp's frame to world space. */
|
|
273
|
+
toWorld: Affine;
|
|
274
|
+
}
|
|
275
|
+
/** The warp a node's `data` holds, whether or not it still matches. */
|
|
276
|
+
declare function heldPathWarpOf(data: unknown): HeldPathWarp | null;
|
|
277
|
+
/** `data` without its warp: the shape as plain geometry. */
|
|
278
|
+
declare function withoutPathWarp<T>(data: T): T;
|
|
279
|
+
/**
|
|
280
|
+
* The warp `node` holds and its frame in world space, or null when it holds
|
|
281
|
+
* none or the one it holds no longer reproduces its geometry. A node whose
|
|
282
|
+
* stored path was only scaled and moved since — a polygon pose dragged, say —
|
|
283
|
+
* still resolves: the box-to-box map between the two is folded into `frame`.
|
|
284
|
+
*/
|
|
285
|
+
declare function resolvePathWarp(node: EditableShape | null | undefined): ResolvedPathWarp | null;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* What every warp action shares: finding the selected paths' warps of one
|
|
289
|
+
* kind, making fresh ones where a path holds none, and writing a changed warp
|
|
290
|
+
* back as the geometry it makes plus the warp itself.
|
|
291
|
+
*/
|
|
292
|
+
|
|
293
|
+
/** Which warp a tool or action works with. */
|
|
294
|
+
type WarpKind = PathWarp['kind'];
|
|
295
|
+
/** The settings a warp is made or remade with. Each applies only to the kinds
|
|
296
|
+
* it names; absent ones leave a held warp as it is. */
|
|
297
|
+
interface WarpSettings {
|
|
298
|
+
/** A distort's map. Default `'free'`. */
|
|
299
|
+
mode?: DistortMode;
|
|
300
|
+
/** An envelope's interpolation. Default `'bicubic'`. */
|
|
301
|
+
mapping?: EnvelopeMapping;
|
|
302
|
+
/** An envelope's patch rows and columns. Default 3 each. */
|
|
303
|
+
rows?: number;
|
|
304
|
+
cols?: number;
|
|
305
|
+
/** How far, in world units, the refitted result may stray from the exact
|
|
306
|
+
* warp. Default {@link DEFAULT_WARP_TOLERANCE}. */
|
|
307
|
+
tolerance?: number;
|
|
308
|
+
}
|
|
309
|
+
/** The refit tolerance of a warp made without one. */
|
|
310
|
+
declare const DEFAULT_WARP_TOLERANCE = 0.5;
|
|
311
|
+
/** The patch rows and columns of an envelope made without them. */
|
|
312
|
+
declare const DEFAULT_ENVELOPE_SIZE = 3;
|
|
313
|
+
/**
|
|
314
|
+
* `shape` (a node's pose and data) warped by `warp`, whose controls are in
|
|
315
|
+
* world space, and holding it — for a scene that opens on a warp already
|
|
316
|
+
* made. Null when `shape` holds no editable polygon.
|
|
317
|
+
*/
|
|
318
|
+
declare function withPathWarp<S extends {
|
|
319
|
+
pose: unknown;
|
|
320
|
+
data: unknown;
|
|
321
|
+
}>(shape: S, warp: PathWarp, opts?: {
|
|
322
|
+
id?: string;
|
|
323
|
+
tolerance?: number;
|
|
324
|
+
}): {
|
|
325
|
+
pose: unknown;
|
|
326
|
+
data: unknown;
|
|
327
|
+
} | null;
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* The params this package's actions read, merged into routing's
|
|
331
|
+
* `ActionParamSchema` so `<SceneCanvas tune>` types them.
|
|
332
|
+
*/
|
|
333
|
+
|
|
334
|
+
/** A path effect's settings as params; a blend's `reverse` also takes
|
|
335
|
+
* `'auto'`, handing the direction back to `autoAlign`. */
|
|
336
|
+
type SettingsOf<E> = {
|
|
337
|
+
[K in Exclude<keyof E, 'kind'>]?: E[K];
|
|
338
|
+
};
|
|
339
|
+
type BlendParams = Omit<SettingsOf<BlendEffect>, 'reverse'> & {
|
|
340
|
+
reverse?: boolean | 'auto';
|
|
341
|
+
};
|
|
342
|
+
type EditPathEffectParams = BlendParams & SettingsOf<BendAlongEffect> & SettingsOf<RepeatAlongEffect> & {
|
|
343
|
+
ids?: readonly string[];
|
|
344
|
+
};
|
|
345
|
+
declare module '@weasel-js/routing' {
|
|
346
|
+
interface ActionParamSchema {
|
|
347
|
+
blend: BlendParams;
|
|
348
|
+
bendAlong: SettingsOf<BendAlongEffect>;
|
|
349
|
+
repeatAlong: SettingsOf<RepeatAlongEffect>;
|
|
350
|
+
editPathEffect: EditPathEffectParams;
|
|
351
|
+
simplifyBrush: SimplifyBrushParams;
|
|
352
|
+
smudgeBrush: SmudgeBrushParams;
|
|
353
|
+
bridgePaths: {
|
|
354
|
+
tension?: number;
|
|
355
|
+
};
|
|
356
|
+
bridgeAnchors: {
|
|
357
|
+
tension?: number;
|
|
358
|
+
};
|
|
359
|
+
constrainAnchors: ConstrainAnchorsParams;
|
|
360
|
+
unconstrainAnchors: {
|
|
361
|
+
kind?: PathConstraintKind;
|
|
362
|
+
};
|
|
363
|
+
'distort.drag': WarpSettings;
|
|
364
|
+
'envelope.drag': WarpSettings;
|
|
365
|
+
'puppet.drag': WarpSettings;
|
|
366
|
+
'puppet.addPin': WarpSettings;
|
|
367
|
+
configureWarp: WarpSettings & {
|
|
368
|
+
kind?: WarpKind;
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Toggles for the locks every path-edit handle drag holds without a
|
|
375
|
+
* modifier: its angle, its length, or both, which freezes it. They set the
|
|
376
|
+
* `editAnchors` dep's `handleLocks`, so a bar, the command palette, and
|
|
377
|
+
* `<SceneCanvas tune>`'s `handleLock` param, which they start from, all
|
|
378
|
+
* reach the one value the drag reads.
|
|
379
|
+
*/
|
|
380
|
+
|
|
381
|
+
/** Hold every handle drag to the handle's angle, as Shift does. */
|
|
382
|
+
declare const handleLockAngleAction: Action & {
|
|
383
|
+
requires: string[];
|
|
384
|
+
};
|
|
385
|
+
/** Hold every handle drag to the handle's length, as Mod (Cmd or Ctrl) does. */
|
|
386
|
+
declare const handleLockLengthAction: Action & {
|
|
387
|
+
requires: string[];
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Bridge: join open path ends with a curve that leaves each end along the
|
|
392
|
+
* direction its path was heading, on whole paths or on the two anchors
|
|
393
|
+
* selected in path edit.
|
|
394
|
+
*/
|
|
395
|
+
|
|
396
|
+
/** How long Bridge makes each handle, as a fraction of the gap, when its
|
|
397
|
+
* params name no `tension`. */
|
|
398
|
+
declare const DEFAULT_BRIDGE_TENSION = 0.4;
|
|
399
|
+
/** A bridge's `params.tension`, or the default. Negative reads as `0`. */
|
|
400
|
+
declare function bridgeTensionOf(params: Record<string, unknown> | undefined): number;
|
|
401
|
+
/**
|
|
402
|
+
* @experimental Bridge open paths: as `joinPaths`, but the gap is spanned by
|
|
403
|
+
* a curve leaving each end along the direction its path was heading, each
|
|
404
|
+
* handle `params.tension` times the gap long (default
|
|
405
|
+
* {@link DEFAULT_BRIDGE_TENSION}). Two paths become one. In path edit,
|
|
406
|
+
* `bridgeAnchors` bridges the two selected anchors instead.
|
|
407
|
+
*/
|
|
408
|
+
declare const bridgePathsAction: Action & {
|
|
409
|
+
requires: string[];
|
|
410
|
+
};
|
|
411
|
+
/**
|
|
412
|
+
* @experimental Bridge the two selected anchors, each the end of an open
|
|
413
|
+
* subpath, as `joinAnchors` does, but with a curve leaving each end along the
|
|
414
|
+
* direction its path was heading, each handle `params.tension` times the gap
|
|
415
|
+
* long (`bridgePaths`'s default when absent). The anchor selection is
|
|
416
|
+
* cleared.
|
|
417
|
+
*/
|
|
418
|
+
declare const bridgeAnchorsAction: Action & {
|
|
419
|
+
requires: string[];
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
/** Trim segment: cut a stroke back to the crossings on either side of a click. */
|
|
423
|
+
|
|
424
|
+
/** What a trim at the press in `params` would do: the stroke it reaches, and
|
|
425
|
+
* what `trimPathAt` makes of it. Null when it reaches none it can trim.
|
|
426
|
+
* `params` as {@link trimPathAction} reads them; a hover's pointer serves
|
|
427
|
+
* as the press, which is how a tool previews the piece. */
|
|
428
|
+
declare function planTrim(deps: ActionDeps, params: unknown): {
|
|
429
|
+
target: PathNode;
|
|
430
|
+
result: TrimResult;
|
|
431
|
+
} | null;
|
|
432
|
+
/**
|
|
433
|
+
* @experimental Trim segment: remove the piece of the stroke under the press
|
|
434
|
+
* between the nearest crossings on either side — with any other node's
|
|
435
|
+
* outline, or with itself — as `trimPathAt` cuts it. The topmost stroke
|
|
436
|
+
* within `radiusPx` of the press (default 6) is the one trimmed; a stroke
|
|
437
|
+
* with nothing left is deleted. Params: `pressX`, `pressY` in world space,
|
|
438
|
+
* which a click binding supplies.
|
|
439
|
+
*/
|
|
440
|
+
declare const trimPathAction: Action & {
|
|
441
|
+
requires: string[];
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
/** Extend to next path: carry an open end along its tangent until it meets a stroke. */
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* @experimental Extend to next path: carry each open end of the selected
|
|
448
|
+
* paths along its tangent to the first stroke it meets (`extendToMeet`). In
|
|
449
|
+
* path edit, the selected end anchors of the edited path, or all its open
|
|
450
|
+
* ends when none is selected. Given a press (`pressX`, `pressY`, as a click
|
|
451
|
+
* binding supplies), the open end nearest it of the topmost stroke within
|
|
452
|
+
* `radiusPx` instead. An end that meets nothing stays put. One undo step.
|
|
453
|
+
*/
|
|
454
|
+
declare const extendToMeetAction: Action & {
|
|
455
|
+
requires: string[];
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Make the selected smooth anchors curvature-continuous by adjusting their
|
|
460
|
+
* handle lengths, or every smooth anchor of the path while none is selected.
|
|
461
|
+
*/
|
|
462
|
+
declare const harmonizeAnchorsAction: _weasel_js_routing.Action & {
|
|
463
|
+
requires: string[];
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* The balance grip on each curved segment of the path being edited, midway
|
|
468
|
+
* along the line joining its two handle tips:
|
|
469
|
+
*
|
|
470
|
+
* - `balanceHandles` — drag the grip to scale both handles together, each
|
|
471
|
+
* along its own direction, so the segment fills out toward its corner or
|
|
472
|
+
* flattens toward its chord without turning at either end.
|
|
473
|
+
* - `equalizeHandles` — double-click the grip to give both handles the same
|
|
474
|
+
* proportion of the way to that corner.
|
|
475
|
+
*
|
|
476
|
+
* The grips are the `balance:N` affordances path edit lays out, shown and
|
|
477
|
+
* hit-tested only while chrome-caps shows `path-edit.balance`. N is the flat
|
|
478
|
+
* index of the anchor the segment starts at.
|
|
479
|
+
*
|
|
480
|
+
* Under a `pathSymmetry` dep a grip drag moves every image of both handles,
|
|
481
|
+
* as `editAnchors` moves a dragged handle's. Both keep each handle's angle, so an angle lock holds through them. A length
|
|
482
|
+
* lock in force for handle drags (the `editAnchors` dep's `handleLocks`, or Mod)
|
|
483
|
+
* holds the drag still, as it would a handle drag with the angle held too.
|
|
484
|
+
*/
|
|
485
|
+
|
|
486
|
+
/** Drag a segment's balance grip to scale both its handles together. */
|
|
487
|
+
declare const balanceHandlesAction: Action & {
|
|
488
|
+
requires: string[];
|
|
489
|
+
};
|
|
490
|
+
/** Double-click a segment's balance grip to even out its handles' proportions. */
|
|
491
|
+
declare const equalizeHandlesAction: Action & {
|
|
492
|
+
requires: string[];
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* The path-effect actions: make a live blend, bend, or repeat from the
|
|
497
|
+
* selection; change one's settings; and expand one into ordinary paths.
|
|
498
|
+
*/
|
|
499
|
+
|
|
500
|
+
/** The `group` every path-effect action is in, for an `<ActionBar>`. */
|
|
501
|
+
declare const PATH_EFFECTS_GROUP = "pathEffects";
|
|
502
|
+
/**
|
|
503
|
+
* Steps between the first two selected shapes, in the order they were
|
|
504
|
+
* selected: `params.steps` of them, each shape, fill, stroke and turn
|
|
505
|
+
* interpolated. The blend is live — editing either source moves its steps —
|
|
506
|
+
* and goes just under the upper source. Its other params are
|
|
507
|
+
* `BlendEffect`'s.
|
|
508
|
+
*/
|
|
509
|
+
declare const blendAction: Action & {
|
|
510
|
+
requires: string[];
|
|
511
|
+
};
|
|
512
|
+
/**
|
|
513
|
+
* The first selected shape bent along the second, live: editing the spine
|
|
514
|
+
* re-bends it. Params are `BendAlongEffect`'s.
|
|
515
|
+
*/
|
|
516
|
+
declare const bendAlongAction: Action & {
|
|
517
|
+
requires: string[];
|
|
518
|
+
};
|
|
519
|
+
/**
|
|
520
|
+
* Copies of the first selected shape along the second, live. Params are
|
|
521
|
+
* `RepeatAlongEffect`'s.
|
|
522
|
+
*/
|
|
523
|
+
declare const repeatAlongAction: Action & {
|
|
524
|
+
requires: string[];
|
|
525
|
+
};
|
|
526
|
+
/**
|
|
527
|
+
* Change the settings of path effects: `params.ids` when given, else the
|
|
528
|
+
* selected ones. Every other param is a setting, laid over each effect's
|
|
529
|
+
* own, and one that would change nothing commits nothing. Consecutive edits
|
|
530
|
+
* of one effect coalesce, so a slider dragged through many values is one
|
|
531
|
+
* undo step where the scene coalesces.
|
|
532
|
+
*/
|
|
533
|
+
declare const editPathEffectAction: Action & {
|
|
534
|
+
requires: string[];
|
|
535
|
+
};
|
|
536
|
+
/**
|
|
537
|
+
* Turn each selected path effect into the ordinary paths it shows, in its
|
|
538
|
+
* slot and in its paint, and select them. Its sources stay; the paths no
|
|
539
|
+
* longer follow them.
|
|
540
|
+
*/
|
|
541
|
+
declare const expandPathEffectAction: Action & {
|
|
542
|
+
requires: string[];
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* The warp actions. A warp tool binds the per-kind ones (`<kind>.drag`,
|
|
547
|
+
* `puppet.addPin`, `puppet.removePin`) and owns them; `expandWarp` and
|
|
548
|
+
* `configureWarp` work on whatever warp the selection holds and ship with
|
|
549
|
+
* the `paths` preset.
|
|
550
|
+
*/
|
|
551
|
+
|
|
552
|
+
/** What a press on a warp control hands the drag that follows. */
|
|
553
|
+
interface WarpHandleScratch {
|
|
554
|
+
/** The warp the control belongs to, or null for one shown over a selection
|
|
555
|
+
* holding none yet, which the drag makes. */
|
|
556
|
+
warpId: string | null;
|
|
557
|
+
/** The control's index, as `warpControls` counts them. */
|
|
558
|
+
index: number;
|
|
559
|
+
}
|
|
560
|
+
/** The scratch a control press carried, or null when the press was elsewhere. */
|
|
561
|
+
declare function warpHandleScratchOf(hit: unknown): WarpHandleScratch | null;
|
|
562
|
+
/**
|
|
563
|
+
* Drop the warp from each selected path, keeping the geometry it made: the
|
|
564
|
+
* shape becomes plain geometry that path editing and other warps start from.
|
|
565
|
+
*/
|
|
566
|
+
declare const expandWarpAction: Action;
|
|
567
|
+
/**
|
|
568
|
+
* Remake the selection's warps under new settings (`params`, a
|
|
569
|
+
* {@link WarpSettings}, plus an optional `kind` limiting it to one kind of
|
|
570
|
+
* warp): switch a distort between free and perspective, an envelope between
|
|
571
|
+
* its mappings or to a finer grid, or refit at another tolerance. One undo step.
|
|
572
|
+
*/
|
|
573
|
+
declare const configureWarpAction: Action;
|
|
574
|
+
|
|
575
|
+
/** Options for a tool that acts on the stroke under a click. */
|
|
576
|
+
interface StrokeClickToolOptions {
|
|
577
|
+
/** Override the default keybinding. Pass `null` to omit. */
|
|
578
|
+
keybinding?: ToolKeybinding | null;
|
|
579
|
+
/** How far from a stroke a click may land and still reach it, in screen
|
|
580
|
+
* pixels. Read on every click. Default 6. */
|
|
581
|
+
radiusPx?: number | (() => number);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/** Options for `useTrimTool`; the default keybinding is `{ key: 'Y' }`. */
|
|
585
|
+
type UseTrimToolOptions = StrokeClickToolOptions;
|
|
586
|
+
/**
|
|
587
|
+
* Trim segment tool. A click on a stroke removes its piece between the
|
|
588
|
+
* crossings on either side — a declarative shell over the `trimPath` action,
|
|
589
|
+
* which owns the hit-test and the commit. While it is up, the piece under the
|
|
590
|
+
* pointer is drawn dashed, through the same `planTrim` the click commits.
|
|
591
|
+
*/
|
|
592
|
+
declare function useTrimTool(options?: UseTrimToolOptions): Tool;
|
|
593
|
+
|
|
594
|
+
/** Options for `useExtendTool`; the default keybinding is `{ key: 'U' }`. */
|
|
595
|
+
type UseExtendToolOptions = StrokeClickToolOptions;
|
|
596
|
+
/**
|
|
597
|
+
* Extend to next path tool. A click near an open end of a stroke carries
|
|
598
|
+
* that end along its tangent to the next stroke it meets — a declarative
|
|
599
|
+
* shell over the `extendToMeet` action.
|
|
600
|
+
*/
|
|
601
|
+
declare function useExtendTool(options?: UseExtendToolOptions): Tool;
|
|
602
|
+
|
|
603
|
+
/** Options for `useSmudgeBrushTool`. */
|
|
604
|
+
interface UseSmudgeBrushToolOptions {
|
|
605
|
+
/** Override the default keybinding (`{ key: 'S' }`). Pass `null` to omit. */
|
|
606
|
+
keybinding?: ToolKeybinding | null;
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Smudge brush tool. A round brush that pushes the outline of the selected
|
|
610
|
+
* paths along with the pointer — a declarative shell whose one binding routes a
|
|
611
|
+
* drag to the `smudgeBrush` action, which owns the stroke, its preview, its ring
|
|
612
|
+
* cursor, and its one undo entry. The brush's radius (screen px) and strength are
|
|
613
|
+
* that action's params: `tune={{ smudgeBrush: { params: () => ({ radiusPx, strength }) } }}`.
|
|
614
|
+
*/
|
|
615
|
+
declare function useSmudgeBrushTool(options?: UseSmudgeBrushToolOptions): Tool;
|
|
616
|
+
|
|
617
|
+
/** A warp tool: a `Tool` that also registers the layer showing its controls. */
|
|
618
|
+
type WarpTool = Tool & Pick<SurfaceContribution, 'attach'>;
|
|
619
|
+
/** Options every warp tool takes. */
|
|
620
|
+
interface WarpToolOptions {
|
|
621
|
+
/** Palette label. */
|
|
622
|
+
label?: string;
|
|
623
|
+
/** Override the default keybinding (Distort `F`, Envelope `M`, Puppet Warp
|
|
624
|
+
* `B`). Pass `null` to omit. */
|
|
625
|
+
keybinding?: ToolKeybinding | null;
|
|
626
|
+
/** How far, in world units, a warped path's refitted curves may stray from
|
|
627
|
+
* the exact warp. Default 0.5. */
|
|
628
|
+
tolerance?: number;
|
|
629
|
+
}
|
|
630
|
+
/** Options for {@link useDistortTool}. */
|
|
631
|
+
interface UseDistortToolOptions extends WarpToolOptions {
|
|
632
|
+
/** The map a new distort starts with: `'free'` (bilinear, the default) or
|
|
633
|
+
* `'perspective'` (projective). */
|
|
634
|
+
mode?: DistortMode;
|
|
635
|
+
}
|
|
636
|
+
/** Options for {@link useEnvelopeTool}. */
|
|
637
|
+
interface UseEnvelopeToolOptions extends WarpToolOptions {
|
|
638
|
+
/** Patch rows and columns of a new envelope's mesh. Default 3 each. */
|
|
639
|
+
rows?: number;
|
|
640
|
+
cols?: number;
|
|
641
|
+
/** How a new envelope interpolates its mesh. Default `'bicubic'`. */
|
|
642
|
+
mapping?: EnvelopeMapping;
|
|
643
|
+
}
|
|
644
|
+
/** Options for {@link usePuppetTool}. */
|
|
645
|
+
type UsePuppetToolOptions = WarpToolOptions;
|
|
646
|
+
/**
|
|
647
|
+
* Distort the selected paths by their box's four corners, each dragged on its
|
|
648
|
+
* own. The first drag gives the selection a distort, kept on each path as
|
|
649
|
+
* `data.warp` until it is expanded (`expandWarp`); selecting the paths again
|
|
650
|
+
* with this tool shows its corners where they were left. `configureWarp`
|
|
651
|
+
* switches a held distort between free and perspective.
|
|
652
|
+
*/
|
|
653
|
+
declare function useDistortTool(options?: UseDistortToolOptions): WarpTool;
|
|
654
|
+
/**
|
|
655
|
+
* Warp the selected paths through a mesh of control points over their box:
|
|
656
|
+
* drag any point and the shape bends smoothly around it. The mesh is held on
|
|
657
|
+
* each path until it is expanded, and `configureWarp` changes its grid or its
|
|
658
|
+
* interpolation.
|
|
659
|
+
*/
|
|
660
|
+
declare function useEnvelopeTool(options?: UseEnvelopeToolOptions): WarpTool;
|
|
661
|
+
/**
|
|
662
|
+
* Pin the selected paths where they are clicked, and drag a pin to bend them:
|
|
663
|
+
* the rest of the shape follows as rigidly as the pins allow, and a pin left
|
|
664
|
+
* alone holds its place. Alt-click a pin to take it out. The pins are held on
|
|
665
|
+
* each path until it is expanded.
|
|
666
|
+
*/
|
|
667
|
+
declare function usePuppetTool(options?: UsePuppetToolOptions): WarpTool;
|
|
668
|
+
|
|
669
|
+
/** The id of the layer showing a `kind` warp's controls. A binding reaches
|
|
670
|
+
* its controls through `affordance:layer:<id>`. */
|
|
671
|
+
declare const warpLayerId: (kind: WarpKind) => string;
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Path constraints in path edit: their marks on the open path, a click
|
|
675
|
+
* selecting one, Delete removing it, and every edit finished so they hold.
|
|
676
|
+
*/
|
|
677
|
+
|
|
678
|
+
/** Owner id of the constraint marks, as `EditAnchorsDep.selectedMark` names them. */
|
|
679
|
+
declare const CONSTRAINTS_EXTENSION_ID = "constraints";
|
|
680
|
+
/**
|
|
681
|
+
* Replace the open path's constraints with `constraints` as one history
|
|
682
|
+
* entry, moving it the least that makes them all hold. When they cannot all
|
|
683
|
+
* hold the path stays as it is and the list is stored all the same, the
|
|
684
|
+
* conflict left for the marks to show. Clears the selected mark, since the
|
|
685
|
+
* list is renumbered. False when the dep cannot store.
|
|
686
|
+
*/
|
|
687
|
+
declare function setConstraints(dep: EditAnchorsDep, constraints: readonly PathConstraint[], label: string): boolean;
|
|
688
|
+
/** The constraint selected in path edit, as an index into the open path's list, or null. */
|
|
689
|
+
declare function selectedConstraintOf(dep: EditAnchorsDep): number | null;
|
|
690
|
+
/** The constraints extension, its marks drawn in `style`'s colors. */
|
|
691
|
+
declare function createConstraintsExtension(style?: Partial<ConstraintGlyphStyle>): PathEditExtension;
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* A node's path constraints: kept as `data.constraints`, numbered by the
|
|
695
|
+
* anchors of its editable polygon, and solved in the frame that polygon is
|
|
696
|
+
* drawn in, so `horizontal` on a rotated `data.path` node turns with it.
|
|
697
|
+
*/
|
|
698
|
+
|
|
699
|
+
/** The constraints a node's data holds, or none. */
|
|
700
|
+
declare function constraintsOf(data: unknown): readonly PathConstraint[];
|
|
701
|
+
/** Radians the frame `horizontal` and `vertical` read is turned from the world's: a `data.path` node's rotation. */
|
|
702
|
+
declare function constraintAxisOf(node: EditableShape | null | undefined): number;
|
|
703
|
+
/**
|
|
704
|
+
* Indices of `node`'s constraints that do not hold in its committed path:
|
|
705
|
+
* the ones that conflict with the rest. Edits leave them out of the solve,
|
|
706
|
+
* and so does a whole-shape transform — resize, rotate, flip — which carries
|
|
707
|
+
* the list unchanged: a constraint the transform breaks, such as a set
|
|
708
|
+
* length under a scale or an equal length under a non-uniform one, is
|
|
709
|
+
* reported here rather than solved back.
|
|
710
|
+
*/
|
|
711
|
+
declare function constraintConflictsOf(node: EditableShape | null | undefined): number[];
|
|
712
|
+
|
|
713
|
+
export { CONSTRAINTS_EXTENSION_ID, type ConstrainAnchorsParams, type ConstraintGlyphStyle, DEFAULT_BRIDGE_TENSION, DEFAULT_ENVELOPE_SIZE, DEFAULT_SMUDGE_RADIUS_PX, DEFAULT_SMUDGE_STRENGTH, DEFAULT_WARP_TOLERANCE, type HeldPathWarp, PATH_BALANCE_CHROME_ID, PATH_COMB_CHROME_ID, PATH_EFFECTS_GROUP, type PathEditBalanceStyle, type PathEditCombOptions, type ResolvedPathWarp, SIMPLIFY_BRUSH_RADIUS_PX, SIMPLIFY_BRUSH_TOOL, type SimplifyBrushParams, type SmudgeBrushParams, type StrokeClickToolOptions, type UseDistortToolOptions, type UseEnvelopeToolOptions, type UseExtendToolOptions, type UsePuppetToolOptions, type UseSmudgeBrushToolOptions, type UseTrimToolOptions, type WarpHandleScratch, type WarpKind, type WarpSettings, type WarpTool, balanceCommands, balanceHandlesAction, balancePreset, bendAlongAction, blendAction, bridgeAnchorsAction, bridgePathsAction, bridgePreset, bridgeTensionOf, brushRingCursor, combCommands, configureWarpAction, constrainAnchorsAction, constraintAxisOf, constraintConflictsOf, constraintsForAnchors, constraintsOf, constraintsPreset, createBalanceExtension, createBalancePreset, createCombExtension, createConstraintsExtension, createConstraintsPreset, createCurvatureCombPreset, curvatureCombPreset, deleteConstraintAction, editPathEffectAction, equalizeHandlesAction, expandPathEffectAction, expandWarpAction, extendPreset, extendToMeetAction, handleLockAngleAction, handleLockLengthAction, handleLocksPreset, harmonizeAnchorsAction, harmonizePreset, heldPathWarpOf, pathEffectsPreset, pathTools, planTrim, repeatAlongAction, resolvePathWarp, selectedConstraintOf, setConstraints, simplifyBrushAction, simplifyBrushPreset, simplifyBrushToolAction, smudgeBrushAction, smudgePreset, trimPathAction, trimPreset, unconstrainAnchorsAction, useDistortTool, useEnvelopeTool, useExtendTool, usePuppetTool, useSmudgeBrushTool, useTrimTool, warpHandleScratchOf, warpLayerId, warpPreset, withPathWarp, withoutPathWarp };
|