@svgsketch/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/index.d.mts +2756 -0
- package/dist/index.d.ts +2756 -0
- package/dist/index.js +14 -0
- package/dist/index.mjs +14 -0
- package/package.json +43 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2756 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @svgsketch/core — Animation types.
|
|
3
|
+
*
|
|
4
|
+
* These types define the animation timeline model used by the
|
|
5
|
+
* SDK, CLI, and editor. They mirror the editor's runtime animation
|
|
6
|
+
* engine but live in core so every consumer shares the same schema.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Easing functions available for keyframe interpolation.
|
|
10
|
+
* Each value maps to a CSS cubic-bezier curve.
|
|
11
|
+
*/
|
|
12
|
+
declare enum EasingType {
|
|
13
|
+
LINEAR = "linear",
|
|
14
|
+
EASE = "ease",
|
|
15
|
+
EASE_IN = "ease-in",
|
|
16
|
+
EASE_OUT = "ease-out",
|
|
17
|
+
EASE_IN_OUT = "ease-in-out",
|
|
18
|
+
EASE_IN_QUAD = "ease-in-quad",
|
|
19
|
+
EASE_OUT_QUAD = "ease-out-quad",
|
|
20
|
+
EASE_IN_OUT_QUAD = "ease-in-out-quad",
|
|
21
|
+
EASE_IN_CUBIC = "ease-in-cubic",
|
|
22
|
+
EASE_OUT_CUBIC = "ease-out-cubic",
|
|
23
|
+
EASE_IN_OUT_CUBIC = "ease-in-out-cubic",
|
|
24
|
+
EASE_IN_QUART = "ease-in-quart",
|
|
25
|
+
EASE_OUT_QUART = "ease-out-quart",
|
|
26
|
+
EASE_IN_OUT_QUART = "ease-in-out-quart",
|
|
27
|
+
EASE_IN_SINE = "ease-in-sine",
|
|
28
|
+
EASE_OUT_SINE = "ease-out-sine",
|
|
29
|
+
EASE_IN_OUT_SINE = "ease-in-out-sine",
|
|
30
|
+
EASE_IN_BACK = "ease-in-back",
|
|
31
|
+
EASE_OUT_BACK = "ease-out-back",
|
|
32
|
+
EASE_IN_OUT_BACK = "ease-in-out-back"
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Map from EasingType → cubic-bezier control points [x1, y1, x2, y2].
|
|
36
|
+
* LINEAR maps to `null` (no curve needed).
|
|
37
|
+
*/
|
|
38
|
+
declare const EASING_CURVES: Record<EasingType, [number, number, number, number] | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Get the CSS cubic-bezier string for an easing type.
|
|
41
|
+
* Returns `'linear'` for LINEAR.
|
|
42
|
+
*/
|
|
43
|
+
declare function getEasingCubicBezier(easing: EasingType): string;
|
|
44
|
+
/** How an animation track is triggered. */
|
|
45
|
+
type AnimationTriggerType = 'time' | 'event' | 'expression';
|
|
46
|
+
/** A trigger that begins or ends an animation track. */
|
|
47
|
+
interface AnimationTrigger {
|
|
48
|
+
type: AnimationTriggerType;
|
|
49
|
+
/** For 'time': seconds offset (e.g. '0.5'). For 'event': DOM event name (e.g. 'click'). */
|
|
50
|
+
value: string;
|
|
51
|
+
}
|
|
52
|
+
/** Common event names available for event-based triggers. */
|
|
53
|
+
declare const EVENT_TRIGGER_OPTIONS: readonly [{
|
|
54
|
+
readonly value: "click";
|
|
55
|
+
readonly label: "Click";
|
|
56
|
+
}, {
|
|
57
|
+
readonly value: "mouseenter";
|
|
58
|
+
readonly label: "Mouse Enter";
|
|
59
|
+
}, {
|
|
60
|
+
readonly value: "mouseleave";
|
|
61
|
+
readonly label: "Mouse Leave";
|
|
62
|
+
}, {
|
|
63
|
+
readonly value: "focus";
|
|
64
|
+
readonly label: "Focus";
|
|
65
|
+
}, {
|
|
66
|
+
readonly value: "blur";
|
|
67
|
+
readonly label: "Blur";
|
|
68
|
+
}, {
|
|
69
|
+
readonly value: "load";
|
|
70
|
+
readonly label: "Page Load";
|
|
71
|
+
}];
|
|
72
|
+
/** How a repeating animation behaves after completing a cycle. */
|
|
73
|
+
type CycleBehavior = 'restart' | 'alternate';
|
|
74
|
+
/**
|
|
75
|
+
* A single keyframe in an animation track.
|
|
76
|
+
*
|
|
77
|
+
* - `time` — Absolute time in seconds within the track.
|
|
78
|
+
* - `value` — The property value at this point (number for numeric, string for colors/paths).
|
|
79
|
+
* - `easing` — The easing curve *leading into* this keyframe (from the previous keyframe).
|
|
80
|
+
*/
|
|
81
|
+
interface AnimationKeyframe {
|
|
82
|
+
time: number;
|
|
83
|
+
value: number | string;
|
|
84
|
+
easing: EasingType;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* An animation track binds a single property of a single shape
|
|
88
|
+
* to a sequence of keyframes.
|
|
89
|
+
*/
|
|
90
|
+
interface AnimationTrack {
|
|
91
|
+
id: string;
|
|
92
|
+
/** The shape ID this track animates. */
|
|
93
|
+
shapeId: string;
|
|
94
|
+
/** The property to animate (e.g. 'cx', 'opacity', 'rotation', 'fillColor'). */
|
|
95
|
+
property: string;
|
|
96
|
+
/** Ordered keyframes for this property. */
|
|
97
|
+
keyframes: AnimationKeyframe[];
|
|
98
|
+
/** Whether this track is active during playback/export. */
|
|
99
|
+
enabled: boolean;
|
|
100
|
+
/** Whether the track is locked from editing. */
|
|
101
|
+
locked: boolean;
|
|
102
|
+
/** SVG path data for motion-path animation (property should be 'pathMotion'). */
|
|
103
|
+
motionPath?: string;
|
|
104
|
+
/** Trigger to begin the animation (defaults to '0s'). */
|
|
105
|
+
beginTrigger?: AnimationTrigger;
|
|
106
|
+
/** Trigger to end the animation. */
|
|
107
|
+
endTrigger?: AnimationTrigger;
|
|
108
|
+
/** Override the track's cycle duration (seconds). */
|
|
109
|
+
cycleDuration?: number;
|
|
110
|
+
/** Number of times to repeat the cycle. */
|
|
111
|
+
cycleRepeats?: number;
|
|
112
|
+
/** Repeat indefinitely. */
|
|
113
|
+
cycleInfinite?: boolean;
|
|
114
|
+
/** Behavior on repeat: restart from beginning or alternate direction. */
|
|
115
|
+
cycleBehavior?: CycleBehavior;
|
|
116
|
+
/** Center point for transform animations (rotation, skew). */
|
|
117
|
+
transformOrigin?: {
|
|
118
|
+
x: number;
|
|
119
|
+
y: number;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Rotation behavior for motion-path animation.
|
|
123
|
+
* - `'auto'` — rotate to match path direction
|
|
124
|
+
* - `'auto-reverse'` — rotate to match path direction + 180°
|
|
125
|
+
* - `number` — fixed rotation angle in degrees
|
|
126
|
+
*/
|
|
127
|
+
motionRotate?: 'auto' | 'auto-reverse' | number;
|
|
128
|
+
/**
|
|
129
|
+
* Whether this track's values add to or replace the base value.
|
|
130
|
+
* @default 'replace' (except transforms, which default to 'sum')
|
|
131
|
+
*/
|
|
132
|
+
additive?: 'sum' | 'replace';
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The top-level animation timeline for a document.
|
|
136
|
+
* Contains all animation tracks and playback configuration.
|
|
137
|
+
*/
|
|
138
|
+
interface AnimationTimeline {
|
|
139
|
+
/** Total timeline duration in seconds. */
|
|
140
|
+
duration: number;
|
|
141
|
+
/** Whether the timeline loops after completing. */
|
|
142
|
+
loop: boolean;
|
|
143
|
+
/** Playback speed multiplier (1 = normal). */
|
|
144
|
+
playbackSpeed: number;
|
|
145
|
+
/** All animation tracks in this timeline. */
|
|
146
|
+
tracks: AnimationTrack[];
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Serialized animation timeline for persistence in .svgs files.
|
|
150
|
+
* Identical to AnimationTimeline but uses plain string for easing
|
|
151
|
+
* to keep the format forward-compatible.
|
|
152
|
+
*/
|
|
153
|
+
interface SerializedAnimationTimeline {
|
|
154
|
+
duration: number;
|
|
155
|
+
loop: boolean;
|
|
156
|
+
playbackSpeed: number;
|
|
157
|
+
tracks: {
|
|
158
|
+
id: string;
|
|
159
|
+
shapeId: string;
|
|
160
|
+
property: string;
|
|
161
|
+
enabled: boolean;
|
|
162
|
+
locked?: boolean;
|
|
163
|
+
motionPath?: string;
|
|
164
|
+
motionPathMatrix?: number[];
|
|
165
|
+
beginTrigger?: AnimationTrigger;
|
|
166
|
+
endTrigger?: AnimationTrigger;
|
|
167
|
+
cycleDuration?: number;
|
|
168
|
+
cycleRepeats?: number;
|
|
169
|
+
cycleInfinite?: boolean;
|
|
170
|
+
cycleBehavior?: CycleBehavior;
|
|
171
|
+
transformOrigin?: {
|
|
172
|
+
x: number;
|
|
173
|
+
y: number;
|
|
174
|
+
};
|
|
175
|
+
motionRotate?: 'auto' | 'auto-reverse' | number;
|
|
176
|
+
additive?: 'sum' | 'replace';
|
|
177
|
+
keyframes: {
|
|
178
|
+
time: number;
|
|
179
|
+
value: number | string;
|
|
180
|
+
easing: string;
|
|
181
|
+
}[];
|
|
182
|
+
}[];
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Describes a shape property that can be animated.
|
|
186
|
+
* Used by the editor UI to build the property picker, but also
|
|
187
|
+
* available for programmatic introspection.
|
|
188
|
+
*/
|
|
189
|
+
interface AnimatablePropertyDescriptor {
|
|
190
|
+
/** Internal property key (e.g. 'cx', 'opacity'). */
|
|
191
|
+
key: string;
|
|
192
|
+
/** Human-readable label. */
|
|
193
|
+
label: string;
|
|
194
|
+
/** Value type: number, color (hex string), or path (SVG path data). */
|
|
195
|
+
type: 'number' | 'color' | 'path';
|
|
196
|
+
/** The SVG attribute name this maps to (e.g. 'cx', 'fill'). */
|
|
197
|
+
attr?: string;
|
|
198
|
+
/** Minimum value for numeric properties. */
|
|
199
|
+
min?: number;
|
|
200
|
+
/** Maximum value for numeric properties. */
|
|
201
|
+
max?: number;
|
|
202
|
+
/** Step increment for numeric properties. */
|
|
203
|
+
step?: number;
|
|
204
|
+
/** Logical category for UI grouping. */
|
|
205
|
+
category?: 'position' | 'size' | 'transform' | 'style' | 'path';
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* @svgsketch/core — Enums used by the document format.
|
|
210
|
+
*
|
|
211
|
+
* Only enums referenced by SerializedShape or HistorySnapshot live here.
|
|
212
|
+
* Editor-only enums (Mode, ControlPointPosition, etc.) stay in the editor.
|
|
213
|
+
*/
|
|
214
|
+
declare enum SplineCurveType {
|
|
215
|
+
LINEAR = "linear",
|
|
216
|
+
QUADRATIC = "quadratic",
|
|
217
|
+
CUBIC = "cubic",
|
|
218
|
+
CATMULL_ROM = "catmull-rom",
|
|
219
|
+
ARC = "arc",
|
|
220
|
+
BASIS = "basis",
|
|
221
|
+
MIXED = "mixed"
|
|
222
|
+
}
|
|
223
|
+
declare enum SplinePointType {
|
|
224
|
+
SMOOTH = "smooth",
|
|
225
|
+
CORNER = "corner",
|
|
226
|
+
SYMMETRIC = "symmetric"
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* @svgsketch/core — Interfaces used by the document format.
|
|
231
|
+
*
|
|
232
|
+
* Only types referenced by SerializedShape or HistorySnapshot live here.
|
|
233
|
+
* Editor-only types (ShapeState, ControlPoint, ChartConfig, etc.) stay in the editor.
|
|
234
|
+
*/
|
|
235
|
+
|
|
236
|
+
interface Point {
|
|
237
|
+
x: number;
|
|
238
|
+
y: number;
|
|
239
|
+
}
|
|
240
|
+
interface Viewbox {
|
|
241
|
+
id: string;
|
|
242
|
+
x: number;
|
|
243
|
+
y: number;
|
|
244
|
+
width: number;
|
|
245
|
+
height: number;
|
|
246
|
+
}
|
|
247
|
+
type FillType = 'solid' | 'linear-gradient' | 'radial-gradient' | 'pattern' | 'none';
|
|
248
|
+
type StrokeType = 'solid' | 'linear-gradient' | 'radial-gradient' | 'pattern' | 'none';
|
|
249
|
+
type GradientSpreadMethod = 'pad' | 'repeat' | 'reflect';
|
|
250
|
+
type PatternType = 'stripes' | 'dots' | 'grid' | 'checkerboard' | 'diagonal' | 'crosshatch' | 'zigzag' | 'waves' | 'triangles' | 'hexagons' | 'diamonds' | 'circles' | 'bricks' | 'herringbone' | 'custom';
|
|
251
|
+
interface GradientStop {
|
|
252
|
+
offset: number;
|
|
253
|
+
color: string;
|
|
254
|
+
opacity: number;
|
|
255
|
+
}
|
|
256
|
+
interface LinearGradient {
|
|
257
|
+
type: 'linear-gradient';
|
|
258
|
+
id: string;
|
|
259
|
+
x1: number;
|
|
260
|
+
y1: number;
|
|
261
|
+
x2: number;
|
|
262
|
+
y2: number;
|
|
263
|
+
stops: GradientStop[];
|
|
264
|
+
spreadMethod: GradientSpreadMethod;
|
|
265
|
+
opacity: number;
|
|
266
|
+
}
|
|
267
|
+
interface RadialGradient {
|
|
268
|
+
type: 'radial-gradient';
|
|
269
|
+
id: string;
|
|
270
|
+
cx: number;
|
|
271
|
+
cy: number;
|
|
272
|
+
fx: number;
|
|
273
|
+
fy: number;
|
|
274
|
+
r: number;
|
|
275
|
+
ry: number;
|
|
276
|
+
rotation: number;
|
|
277
|
+
stops: GradientStop[];
|
|
278
|
+
spreadMethod: GradientSpreadMethod;
|
|
279
|
+
opacity: number;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Per-pattern-type tuneable parameters.
|
|
283
|
+
*
|
|
284
|
+
* All values are **ratios relative to the tile size** so they scale cleanly
|
|
285
|
+
* when the user drags the Scale slider. Each preset pattern type uses only
|
|
286
|
+
* the subset of params that make sense for its geometry — the rest are
|
|
287
|
+
* ignored. Omitted fields fall back to the built-in defaults inside
|
|
288
|
+
* `getPatternElements()`.
|
|
289
|
+
*/
|
|
290
|
+
interface PatternParams {
|
|
291
|
+
/** Line / stroke thickness ratio (0.02–0.5, default varies per type). */
|
|
292
|
+
strokeWidth?: number;
|
|
293
|
+
/** Dot / circle radius ratio (0.05–0.45, default 0.25). */
|
|
294
|
+
dotRadius?: number;
|
|
295
|
+
/** Wave / zigzag amplitude ratio (0.05–0.5, default 0.25). */
|
|
296
|
+
amplitude?: number;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Pattern fill definition.
|
|
300
|
+
*
|
|
301
|
+
* SVG 2 §14.3 — a pre-defined graphic object replicated at fixed intervals
|
|
302
|
+
* to tile an area. When `svgContent` is present it is the single source of
|
|
303
|
+
* truth for rendering and is emitted directly inside the `<pattern>` element.
|
|
304
|
+
*
|
|
305
|
+
* Legacy fields (`patternType`, `color`, `backgroundColor`, `scale`,
|
|
306
|
+
* `rotation`) are kept for backward compatibility with existing documents
|
|
307
|
+
* and provide preset metadata for the UI. For imported (custom) patterns
|
|
308
|
+
* they carry fallback values only.
|
|
309
|
+
*/
|
|
310
|
+
interface PatternFill {
|
|
311
|
+
type: 'pattern';
|
|
312
|
+
id: string;
|
|
313
|
+
/** Preset identifier, or `'custom'` for imported / user-provided patterns. */
|
|
314
|
+
patternType: PatternType;
|
|
315
|
+
/** Preset foreground colour, or dominant-colour fallback for custom. */
|
|
316
|
+
color: string;
|
|
317
|
+
/** Preset background colour. */
|
|
318
|
+
backgroundColor: string;
|
|
319
|
+
/** Preset scale multiplier (base tile size = 10 × scale). */
|
|
320
|
+
scale: number;
|
|
321
|
+
/** Preset rotation in degrees (written into `patternTransform`). */
|
|
322
|
+
rotation: number;
|
|
323
|
+
/** Fill-opacity applied to the painted area (0–1). */
|
|
324
|
+
opacity: number;
|
|
325
|
+
/** Per-preset tuneable geometry parameters (stroke width, dot radius …). */
|
|
326
|
+
patternParams?: PatternParams;
|
|
327
|
+
/**
|
|
328
|
+
* Serialised inner markup of the `<pattern>` tile.
|
|
329
|
+
* When present this is used **instead of** generating content from the
|
|
330
|
+
* preset helpers — it can contain arbitrary SVG (rects, paths, images …).
|
|
331
|
+
*/
|
|
332
|
+
svgContent?: string;
|
|
333
|
+
/** Tile width in the coordinate system defined by `patternUnits`. */
|
|
334
|
+
width?: number;
|
|
335
|
+
/** Tile height in the coordinate system defined by `patternUnits`. */
|
|
336
|
+
height?: number;
|
|
337
|
+
/**
|
|
338
|
+
* Coordinate system for `x`, `y`, `width`, `height`.
|
|
339
|
+
* SVG 2 initial value: `objectBoundingBox`.
|
|
340
|
+
* SVGSketch presets default to `userSpaceOnUse` for simplicity.
|
|
341
|
+
*/
|
|
342
|
+
patternUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
|
|
343
|
+
/**
|
|
344
|
+
* Coordinate system for the pattern tile contents.
|
|
345
|
+
* SVG 2 initial value: `userSpaceOnUse`.
|
|
346
|
+
* Has no effect when `viewBox` is specified.
|
|
347
|
+
*/
|
|
348
|
+
patternContentUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
|
|
349
|
+
/** Full SVG `patternTransform` string (e.g. `"rotate(45) scale(2)"`). */
|
|
350
|
+
patternTransform?: string;
|
|
351
|
+
/** Optional `viewBox` attribute for the tile coordinate system. */
|
|
352
|
+
viewBox?: string;
|
|
353
|
+
/** Optional `preserveAspectRatio` attribute. */
|
|
354
|
+
preserveAspectRatio?: string;
|
|
355
|
+
/** Tile origin X offset (default 0). */
|
|
356
|
+
x?: number;
|
|
357
|
+
/** Tile origin Y offset (default 0). */
|
|
358
|
+
y?: number;
|
|
359
|
+
/** ID of the `CustomPatternDef` this fill was built from (if any). */
|
|
360
|
+
customPatternId?: string;
|
|
361
|
+
}
|
|
362
|
+
type GradientDefinition = LinearGradient | RadialGradient | PatternFill;
|
|
363
|
+
/** Style overrides for a single rich-text segment. */
|
|
364
|
+
interface RichTextSegmentStyle {
|
|
365
|
+
fontFamily?: string;
|
|
366
|
+
fontWeight?: string;
|
|
367
|
+
fontStyle?: string;
|
|
368
|
+
textDecoration?: {
|
|
369
|
+
underline?: boolean;
|
|
370
|
+
strikethrough?: boolean;
|
|
371
|
+
overline?: boolean;
|
|
372
|
+
};
|
|
373
|
+
textTransform?: string;
|
|
374
|
+
baselineShift?: string;
|
|
375
|
+
fontSize?: number;
|
|
376
|
+
fillColor?: string;
|
|
377
|
+
}
|
|
378
|
+
/** A single styled text segment within a rich-text line. */
|
|
379
|
+
interface RichTextSegment {
|
|
380
|
+
text: string;
|
|
381
|
+
style: RichTextSegmentStyle;
|
|
382
|
+
}
|
|
383
|
+
/** A line of rich text containing styled segments. */
|
|
384
|
+
interface RichTextLine {
|
|
385
|
+
segments: RichTextSegment[];
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Rich text data for per-segment styling within a text shape.
|
|
389
|
+
* Each line contains independently styled segments.
|
|
390
|
+
*/
|
|
391
|
+
interface RichTextData {
|
|
392
|
+
lines: RichTextLine[];
|
|
393
|
+
baseStyle: RichTextSegmentStyle;
|
|
394
|
+
lineHeight: number;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* A user-defined custom pattern stored in the document.
|
|
398
|
+
* Created by serialising selected shapes into a reusable pattern tile.
|
|
399
|
+
*/
|
|
400
|
+
interface CustomPatternDef {
|
|
401
|
+
/** Unique identifier for this pattern definition. */
|
|
402
|
+
id: string;
|
|
403
|
+
/** User-assigned name shown in the pattern picker. */
|
|
404
|
+
name: string;
|
|
405
|
+
/** Serialised inner SVG markup of the pattern tile. */
|
|
406
|
+
svgContent: string;
|
|
407
|
+
/** Tile width in userSpaceOnUse coordinates. */
|
|
408
|
+
width: number;
|
|
409
|
+
/** Tile height in userSpaceOnUse coordinates. */
|
|
410
|
+
height: number;
|
|
411
|
+
}
|
|
412
|
+
type FilterType = 'drop-shadow' | 'inner-shadow' | 'gaussian-blur' | 'motion-blur' | 'point-light' | 'spot-light' | 'outline' | 'sharpen' | 'pixelate' | 'warp' | 'morphology' | 'contouring-discrete' | 'contouring-table' | 'round-edges' | 'grayscale' | 'channel-painter' | 'brightness' | 'contrast' | 'opacity' | 'invert' | 'hue-rotate' | 'saturate' | 'black-and-white' | 'sepia' | 'duotone' | 'xray' | 'noise' | 'emboss' | 'film-grain' | 'watercolor' | 'gouache' | 'ink-blot' | 'crumpled-plastic' | 'riddled' | 'glow' | 'inner-glow';
|
|
413
|
+
type BlurQuality = 'normal' | 'high';
|
|
414
|
+
interface BaseFilter {
|
|
415
|
+
id: string;
|
|
416
|
+
type: FilterType;
|
|
417
|
+
enabled: boolean;
|
|
418
|
+
}
|
|
419
|
+
interface DropShadowFilter extends BaseFilter {
|
|
420
|
+
type: 'drop-shadow';
|
|
421
|
+
offsetX: number;
|
|
422
|
+
offsetY: number;
|
|
423
|
+
blurRadius: number;
|
|
424
|
+
spread: number;
|
|
425
|
+
color: string;
|
|
426
|
+
opacity: number;
|
|
427
|
+
}
|
|
428
|
+
interface InnerShadowFilter extends BaseFilter {
|
|
429
|
+
type: 'inner-shadow';
|
|
430
|
+
offsetX: number;
|
|
431
|
+
offsetY: number;
|
|
432
|
+
blurRadius: number;
|
|
433
|
+
choke: number;
|
|
434
|
+
color: string;
|
|
435
|
+
opacity: number;
|
|
436
|
+
}
|
|
437
|
+
interface GaussianBlurFilter extends BaseFilter {
|
|
438
|
+
type: 'gaussian-blur';
|
|
439
|
+
blurX: number;
|
|
440
|
+
blurY: number;
|
|
441
|
+
linked: boolean;
|
|
442
|
+
quality: BlurQuality;
|
|
443
|
+
}
|
|
444
|
+
interface MotionBlurFilter extends BaseFilter {
|
|
445
|
+
type: 'motion-blur';
|
|
446
|
+
distance: number;
|
|
447
|
+
angle: number;
|
|
448
|
+
quality: BlurQuality;
|
|
449
|
+
}
|
|
450
|
+
interface PointLightFilter extends BaseFilter {
|
|
451
|
+
type: 'point-light';
|
|
452
|
+
x: number;
|
|
453
|
+
y: number;
|
|
454
|
+
z: number;
|
|
455
|
+
color: string;
|
|
456
|
+
surfaceScale: number;
|
|
457
|
+
diffuseConstant: number;
|
|
458
|
+
specularConstant: number;
|
|
459
|
+
specularExponent: number;
|
|
460
|
+
}
|
|
461
|
+
interface SpotLightFilter extends BaseFilter {
|
|
462
|
+
type: 'spot-light';
|
|
463
|
+
x: number;
|
|
464
|
+
y: number;
|
|
465
|
+
z: number;
|
|
466
|
+
pointsAtX: number;
|
|
467
|
+
pointsAtY: number;
|
|
468
|
+
pointsAtZ: number;
|
|
469
|
+
coneAngle: number;
|
|
470
|
+
color: string;
|
|
471
|
+
surfaceScale: number;
|
|
472
|
+
specularConstant: number;
|
|
473
|
+
specularExponent: number;
|
|
474
|
+
}
|
|
475
|
+
type OutlinePosition = 'outside' | 'center' | 'inside';
|
|
476
|
+
interface OutlineFilter extends BaseFilter {
|
|
477
|
+
type: 'outline';
|
|
478
|
+
width: number;
|
|
479
|
+
color: string;
|
|
480
|
+
opacity: number;
|
|
481
|
+
position: OutlinePosition;
|
|
482
|
+
}
|
|
483
|
+
interface SharpenFilter extends BaseFilter {
|
|
484
|
+
type: 'sharpen';
|
|
485
|
+
amount: number;
|
|
486
|
+
}
|
|
487
|
+
interface PixelateFilter extends BaseFilter {
|
|
488
|
+
type: 'pixelate';
|
|
489
|
+
blockSize: number;
|
|
490
|
+
}
|
|
491
|
+
type WarpType = 'turbulence' | 'fractalNoise';
|
|
492
|
+
interface WarpFilter extends BaseFilter {
|
|
493
|
+
type: 'warp';
|
|
494
|
+
scale: number;
|
|
495
|
+
frequency: number;
|
|
496
|
+
octaves: number;
|
|
497
|
+
warpType: WarpType;
|
|
498
|
+
}
|
|
499
|
+
type MorphologyOperator = 'erode' | 'dilate';
|
|
500
|
+
interface MorphologyFilter extends BaseFilter {
|
|
501
|
+
type: 'morphology';
|
|
502
|
+
operator: MorphologyOperator;
|
|
503
|
+
radiusX: number;
|
|
504
|
+
radiusY: number;
|
|
505
|
+
linked: boolean;
|
|
506
|
+
}
|
|
507
|
+
interface ContouringDiscreteFilter extends BaseFilter {
|
|
508
|
+
type: 'contouring-discrete';
|
|
509
|
+
levels: number;
|
|
510
|
+
}
|
|
511
|
+
interface ContouringTableFilter extends BaseFilter {
|
|
512
|
+
type: 'contouring-table';
|
|
513
|
+
levels: number;
|
|
514
|
+
contrast: number;
|
|
515
|
+
}
|
|
516
|
+
interface RoundEdgesFilter extends BaseFilter {
|
|
517
|
+
type: 'round-edges';
|
|
518
|
+
radius: number;
|
|
519
|
+
}
|
|
520
|
+
interface GrayscaleFilter extends BaseFilter {
|
|
521
|
+
type: 'grayscale';
|
|
522
|
+
amount: number;
|
|
523
|
+
}
|
|
524
|
+
interface ChannelPainterFilter extends BaseFilter {
|
|
525
|
+
type: 'channel-painter';
|
|
526
|
+
red: number;
|
|
527
|
+
green: number;
|
|
528
|
+
blue: number;
|
|
529
|
+
}
|
|
530
|
+
interface BrightnessFilter extends BaseFilter {
|
|
531
|
+
type: 'brightness';
|
|
532
|
+
amount: number;
|
|
533
|
+
}
|
|
534
|
+
interface ContrastFilter extends BaseFilter {
|
|
535
|
+
type: 'contrast';
|
|
536
|
+
amount: number;
|
|
537
|
+
}
|
|
538
|
+
interface OpacityFilter extends BaseFilter {
|
|
539
|
+
type: 'opacity';
|
|
540
|
+
amount: number;
|
|
541
|
+
}
|
|
542
|
+
interface InvertFilter extends BaseFilter {
|
|
543
|
+
type: 'invert';
|
|
544
|
+
amount: number;
|
|
545
|
+
}
|
|
546
|
+
interface HueRotateFilter extends BaseFilter {
|
|
547
|
+
type: 'hue-rotate';
|
|
548
|
+
angle: number;
|
|
549
|
+
}
|
|
550
|
+
interface SaturateFilter extends BaseFilter {
|
|
551
|
+
type: 'saturate';
|
|
552
|
+
amount: number;
|
|
553
|
+
}
|
|
554
|
+
interface BlackAndWhiteFilter extends BaseFilter {
|
|
555
|
+
type: 'black-and-white';
|
|
556
|
+
threshold: number;
|
|
557
|
+
}
|
|
558
|
+
interface SepiaFilter extends BaseFilter {
|
|
559
|
+
type: 'sepia';
|
|
560
|
+
amount: number;
|
|
561
|
+
}
|
|
562
|
+
interface DuotoneFilter extends BaseFilter {
|
|
563
|
+
type: 'duotone';
|
|
564
|
+
shadowColor: string;
|
|
565
|
+
highlightColor: string;
|
|
566
|
+
}
|
|
567
|
+
interface XrayFilter extends BaseFilter {
|
|
568
|
+
type: 'xray';
|
|
569
|
+
intensity: number;
|
|
570
|
+
}
|
|
571
|
+
interface NoiseFilter extends BaseFilter {
|
|
572
|
+
type: 'noise';
|
|
573
|
+
amount: number;
|
|
574
|
+
scale: number;
|
|
575
|
+
}
|
|
576
|
+
interface EmbossFilter extends BaseFilter {
|
|
577
|
+
type: 'emboss';
|
|
578
|
+
strength: number;
|
|
579
|
+
angle: number;
|
|
580
|
+
}
|
|
581
|
+
interface FilmGrainFilter extends BaseFilter {
|
|
582
|
+
type: 'film-grain';
|
|
583
|
+
amount: number;
|
|
584
|
+
size: number;
|
|
585
|
+
}
|
|
586
|
+
interface WatercolorFilter extends BaseFilter {
|
|
587
|
+
type: 'watercolor';
|
|
588
|
+
wetness: number;
|
|
589
|
+
turbulence: number;
|
|
590
|
+
}
|
|
591
|
+
interface GouacheFilter extends BaseFilter {
|
|
592
|
+
type: 'gouache';
|
|
593
|
+
thickness: number;
|
|
594
|
+
texture: number;
|
|
595
|
+
}
|
|
596
|
+
interface InkBlotFilter extends BaseFilter {
|
|
597
|
+
type: 'ink-blot';
|
|
598
|
+
spread: number;
|
|
599
|
+
edges: number;
|
|
600
|
+
}
|
|
601
|
+
interface CrumpledPlasticFilter extends BaseFilter {
|
|
602
|
+
type: 'crumpled-plastic';
|
|
603
|
+
wrinkles: number;
|
|
604
|
+
shine: number;
|
|
605
|
+
}
|
|
606
|
+
interface RiddledFilter extends BaseFilter {
|
|
607
|
+
type: 'riddled';
|
|
608
|
+
density: number;
|
|
609
|
+
size: number;
|
|
610
|
+
}
|
|
611
|
+
interface GlowFilter extends BaseFilter {
|
|
612
|
+
type: 'glow';
|
|
613
|
+
color: string;
|
|
614
|
+
radius: number;
|
|
615
|
+
intensity: number;
|
|
616
|
+
}
|
|
617
|
+
interface InnerGlowFilter extends BaseFilter {
|
|
618
|
+
type: 'inner-glow';
|
|
619
|
+
color: string;
|
|
620
|
+
radius: number;
|
|
621
|
+
intensity: number;
|
|
622
|
+
}
|
|
623
|
+
type ShapeFilter = DropShadowFilter | InnerShadowFilter | GaussianBlurFilter | MotionBlurFilter | PointLightFilter | SpotLightFilter | OutlineFilter | SharpenFilter | PixelateFilter | WarpFilter | MorphologyFilter | ContouringDiscreteFilter | ContouringTableFilter | RoundEdgesFilter | GrayscaleFilter | ChannelPainterFilter | BrightnessFilter | ContrastFilter | OpacityFilter | InvertFilter | HueRotateFilter | SaturateFilter | BlackAndWhiteFilter | SepiaFilter | DuotoneFilter | XrayFilter | NoiseFilter | EmbossFilter | FilmGrainFilter | WatercolorFilter | GouacheFilter | InkBlotFilter | CrumpledPlasticFilter | RiddledFilter | GlowFilter | InnerGlowFilter;
|
|
624
|
+
type SegmentCurveType = 'LINEAR' | 'CUBIC' | 'QUADRATIC' | 'ARC';
|
|
625
|
+
interface SplinePoint {
|
|
626
|
+
x: number;
|
|
627
|
+
y: number;
|
|
628
|
+
handleIn?: Point;
|
|
629
|
+
handleOut?: Point;
|
|
630
|
+
pointType: SplinePointType;
|
|
631
|
+
isSubpathStart?: boolean;
|
|
632
|
+
segmentType?: SegmentCurveType;
|
|
633
|
+
arcParams?: ArcParams$1;
|
|
634
|
+
}
|
|
635
|
+
interface ArcParams$1 {
|
|
636
|
+
rx: number;
|
|
637
|
+
ry: number;
|
|
638
|
+
rotation: number;
|
|
639
|
+
largeArc: boolean;
|
|
640
|
+
sweep: boolean;
|
|
641
|
+
}
|
|
642
|
+
type LinkTarget = '_self' | '_blank' | '_parent' | '_top';
|
|
643
|
+
type AriaRole = '' | 'img' | 'button' | 'link' | 'presentation' | 'none' | 'graphics-document' | 'graphics-object' | 'graphics-symbol';
|
|
644
|
+
interface ShapeMetadata {
|
|
645
|
+
name: string;
|
|
646
|
+
classes: string[];
|
|
647
|
+
title: string;
|
|
648
|
+
description: string;
|
|
649
|
+
role: AriaRole;
|
|
650
|
+
ariaLabel: string;
|
|
651
|
+
linkUrl: string;
|
|
652
|
+
linkTarget: LinkTarget;
|
|
653
|
+
customData: Record<string, string>;
|
|
654
|
+
}
|
|
655
|
+
type LicenseType = '' | 'cc0' | 'cc-by' | 'cc-by-sa' | 'cc-by-nc' | 'cc-by-nc-sa' | 'cc-by-nd' | 'cc-by-nc-nd' | 'mit' | 'apache-2.0' | 'custom';
|
|
656
|
+
interface DocumentMetadata {
|
|
657
|
+
title: string;
|
|
658
|
+
description: string;
|
|
659
|
+
author: string;
|
|
660
|
+
keywords: string[];
|
|
661
|
+
license: LicenseType;
|
|
662
|
+
licenseUrl: string;
|
|
663
|
+
language: string;
|
|
664
|
+
customMetadata: Record<string, string>;
|
|
665
|
+
}
|
|
666
|
+
/** Type of a template variable's value. */
|
|
667
|
+
type TemplateVariableType = 'string' | 'color' | 'number';
|
|
668
|
+
/** A template variable definition stored in the document. */
|
|
669
|
+
interface TemplateVariable {
|
|
670
|
+
/** Variable name (used in `{{name}}` placeholders). */
|
|
671
|
+
name: string;
|
|
672
|
+
/** The type of value this variable holds. */
|
|
673
|
+
type: TemplateVariableType;
|
|
674
|
+
/** Default value (used when no override is provided). */
|
|
675
|
+
defaultValue: string;
|
|
676
|
+
/** Human-readable label for UI display. */
|
|
677
|
+
label?: string;
|
|
678
|
+
/** Description / help text. */
|
|
679
|
+
description?: string;
|
|
680
|
+
}
|
|
681
|
+
interface Guide {
|
|
682
|
+
id: string;
|
|
683
|
+
orientation: 'horizontal' | 'vertical';
|
|
684
|
+
position: number;
|
|
685
|
+
controlPointOffset: number;
|
|
686
|
+
color?: string;
|
|
687
|
+
opacity?: number;
|
|
688
|
+
}
|
|
689
|
+
interface Measurement {
|
|
690
|
+
id: string;
|
|
691
|
+
type: 'distance' | 'angle';
|
|
692
|
+
points: Point[];
|
|
693
|
+
visible: boolean;
|
|
694
|
+
snapDivisions: number;
|
|
695
|
+
color?: string;
|
|
696
|
+
opacity?: number;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* @svgsketch/core — Serialized document types.
|
|
701
|
+
*
|
|
702
|
+
* These types define the .svgs document format. SerializedShape and
|
|
703
|
+
* HistorySnapshot are the canonical data structures for persisting
|
|
704
|
+
* SVGSketch documents.
|
|
705
|
+
*/
|
|
706
|
+
|
|
707
|
+
interface SerializedShape {
|
|
708
|
+
id: string;
|
|
709
|
+
/** Shape type identifier. Built-in types: 'circle', 'rectangle', etc. Plugin shapes use custom ids. */
|
|
710
|
+
type: string;
|
|
711
|
+
state: {
|
|
712
|
+
x?: number;
|
|
713
|
+
y?: number;
|
|
714
|
+
width?: number;
|
|
715
|
+
height?: number;
|
|
716
|
+
radius?: number;
|
|
717
|
+
rx?: number;
|
|
718
|
+
ry?: number;
|
|
719
|
+
cornerRadius?: number;
|
|
720
|
+
fontSize?: number;
|
|
721
|
+
text?: string;
|
|
722
|
+
fontFamily?: string;
|
|
723
|
+
fontWeight?: string;
|
|
724
|
+
fontStyle?: string;
|
|
725
|
+
textDecoration?: {
|
|
726
|
+
underline?: boolean;
|
|
727
|
+
strikethrough?: boolean;
|
|
728
|
+
overline?: boolean;
|
|
729
|
+
};
|
|
730
|
+
textTransform?: string;
|
|
731
|
+
baselineShift?: string;
|
|
732
|
+
dominantBaseline?: string;
|
|
733
|
+
writingMode?: 'horizontal-tb' | 'vertical-rl' | 'vertical-lr';
|
|
734
|
+
textAnchor?: string;
|
|
735
|
+
letterSpacing?: number;
|
|
736
|
+
wordSpacing?: number;
|
|
737
|
+
lineHeight?: number;
|
|
738
|
+
inlineSize?: number;
|
|
739
|
+
overflowWrap?: 'normal' | 'break-word' | 'anywhere';
|
|
740
|
+
whiteSpace?: 'normal' | 'nowrap' | 'pre' | 'pre-wrap' | 'pre-line' | 'break-spaces';
|
|
741
|
+
textDirection?: 'ltr' | 'rtl';
|
|
742
|
+
unicodeBidi?: 'normal' | 'embed' | 'bidi-override' | 'isolate' | 'isolate-override' | 'plaintext';
|
|
743
|
+
fontVariationSettings?: Record<string, number>;
|
|
744
|
+
charOffsets?: {
|
|
745
|
+
x: number;
|
|
746
|
+
y: number;
|
|
747
|
+
rotate: number;
|
|
748
|
+
}[];
|
|
749
|
+
richTextData?: RichTextData;
|
|
750
|
+
scaleX?: number;
|
|
751
|
+
scaleY?: number;
|
|
752
|
+
textX?: number;
|
|
753
|
+
textY?: number;
|
|
754
|
+
scaleAnchor?: Point | null;
|
|
755
|
+
rotation?: number;
|
|
756
|
+
skewX?: number;
|
|
757
|
+
skewY?: number;
|
|
758
|
+
customPivot?: Point | null;
|
|
759
|
+
fillColor?: string;
|
|
760
|
+
fillOpacity?: number;
|
|
761
|
+
borderColor?: string;
|
|
762
|
+
borderWidth?: number | string;
|
|
763
|
+
strokeOpacity?: number;
|
|
764
|
+
cx?: number;
|
|
765
|
+
cy?: number;
|
|
766
|
+
sides?: number;
|
|
767
|
+
arms?: number;
|
|
768
|
+
innerRadiusPercent?: number;
|
|
769
|
+
shiftAngle?: number;
|
|
770
|
+
armWidthPercent?: number;
|
|
771
|
+
teeth?: number;
|
|
772
|
+
toothDepthPercent?: number;
|
|
773
|
+
holeRadiusPercent?: number;
|
|
774
|
+
turns?: number;
|
|
775
|
+
thicknessPercent?: number;
|
|
776
|
+
direction?: number;
|
|
777
|
+
headWidthPercent?: number;
|
|
778
|
+
headLengthPercent?: number;
|
|
779
|
+
shaftWidthPercent?: number;
|
|
780
|
+
x1?: number;
|
|
781
|
+
y1?: number;
|
|
782
|
+
x2?: number;
|
|
783
|
+
y2?: number;
|
|
784
|
+
lineStyle?: 'solid' | 'dashed' | 'dotted' | 'custom';
|
|
785
|
+
dashLength?: number;
|
|
786
|
+
gapLength?: number;
|
|
787
|
+
dashOffset?: number;
|
|
788
|
+
/** Raw SVG stroke-dasharray for multi-value patterns. */
|
|
789
|
+
strokeDasharray?: string;
|
|
790
|
+
startEndpoint?: 'none' | 'arrow' | 'open-arrow' | 'circle' | 'diamond' | 'square';
|
|
791
|
+
endEndpoint?: 'none' | 'arrow' | 'open-arrow' | 'circle' | 'diamond' | 'square';
|
|
792
|
+
locked?: boolean;
|
|
793
|
+
visible?: boolean;
|
|
794
|
+
fillType?: FillType;
|
|
795
|
+
fillGradient?: LinearGradient | RadialGradient | PatternFill;
|
|
796
|
+
strokeType?: StrokeType;
|
|
797
|
+
strokeGradient?: LinearGradient | RadialGradient | PatternFill;
|
|
798
|
+
filters?: ShapeFilter[];
|
|
799
|
+
splinePoints?: SplinePoint[];
|
|
800
|
+
splineCurveType?: SplineCurveType;
|
|
801
|
+
splineClosed?: boolean;
|
|
802
|
+
splineTension?: number;
|
|
803
|
+
splineArcParams?: ArcParams$1[];
|
|
804
|
+
polylinePoints?: Point[];
|
|
805
|
+
polylineClosed?: boolean;
|
|
806
|
+
href?: string;
|
|
807
|
+
originalWidth?: number;
|
|
808
|
+
originalHeight?: number;
|
|
809
|
+
preserveAspectRatio?: boolean;
|
|
810
|
+
imageOpacity?: number;
|
|
811
|
+
shapeInsideRef?: string;
|
|
812
|
+
shapePadding?: number;
|
|
813
|
+
isTextPath?: boolean;
|
|
814
|
+
textPathPoints?: SplinePoint[];
|
|
815
|
+
textPathStartOffset?: number;
|
|
816
|
+
textPathSide?: 'left' | 'right';
|
|
817
|
+
fillRule?: 'nonzero' | 'evenodd';
|
|
818
|
+
strokeLinejoin?: 'miter' | 'round' | 'bevel';
|
|
819
|
+
strokeLinecap?: 'butt' | 'round' | 'square';
|
|
820
|
+
strokeMiterlimit?: number;
|
|
821
|
+
opacity?: number;
|
|
822
|
+
metadata?: Partial<ShapeMetadata>;
|
|
823
|
+
groupId?: string;
|
|
824
|
+
cssClipPath?: string;
|
|
825
|
+
cssMaskProperties?: Record<string, string>;
|
|
826
|
+
symbolId?: string;
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
type SerializedViewbox = Viewbox;
|
|
830
|
+
/**
|
|
831
|
+
* Schema version for the HistorySnapshot format.
|
|
832
|
+
*
|
|
833
|
+
* IMPORTANT — Serialization compatibility rules:
|
|
834
|
+
*
|
|
835
|
+
* 1. NEVER rename an existing serialized property — add a new one alongside
|
|
836
|
+
* the old and read both with a fallback (e.g. state.newName ?? state.oldName).
|
|
837
|
+
* 2. NEVER change a property's type — add a new property instead.
|
|
838
|
+
* 3. NEVER make a previously optional field required without providing a
|
|
839
|
+
* default in the migration path.
|
|
840
|
+
* 4. NEVER remove a shape type — old documents referencing it would silently
|
|
841
|
+
* lose those shapes.
|
|
842
|
+
* 5. When adding new optional properties, always handle their absence in
|
|
843
|
+
* restoreFromSerialized with ?? or if-guards.
|
|
844
|
+
*
|
|
845
|
+
* When you need a breaking change:
|
|
846
|
+
* a. Bump CURRENT_SCHEMA_VERSION below.
|
|
847
|
+
* b. Add a migration function in the migrations module that transforms
|
|
848
|
+
* (version - 1) snapshots into the new format.
|
|
849
|
+
* c. Register it in the migrateSnapshot() chain.
|
|
850
|
+
*/
|
|
851
|
+
declare const CURRENT_SCHEMA_VERSION = 1;
|
|
852
|
+
interface HistorySnapshot {
|
|
853
|
+
/**
|
|
854
|
+
* Schema version — written on save, read on load to trigger migrations.
|
|
855
|
+
* If absent, the snapshot predates versioning and is treated as version 1.
|
|
856
|
+
*/
|
|
857
|
+
schemaVersion?: number;
|
|
858
|
+
shapes: SerializedShape[];
|
|
859
|
+
viewboxes: SerializedViewbox[];
|
|
860
|
+
guides?: Guide[];
|
|
861
|
+
measurements?: Measurement[];
|
|
862
|
+
/** Group structure: array of group IDs with their parent group ID (null for top-level) */
|
|
863
|
+
groups?: SerializedGroup[];
|
|
864
|
+
/** Clip/mask group structure for undo/redo support */
|
|
865
|
+
clipMaskGroups?: SerializedClipMaskGroup[];
|
|
866
|
+
/** Document-level metadata (title, description, author, etc.) */
|
|
867
|
+
documentMetadata?: DocumentMetadata;
|
|
868
|
+
/** Template variable definitions with defaults. */
|
|
869
|
+
templateVariables?: TemplateVariable[];
|
|
870
|
+
/** Animation timeline (tracks, keyframes, easing). */
|
|
871
|
+
animationTimeline?: SerializedAnimationTimeline;
|
|
872
|
+
/** User-defined custom patterns stored in the document. */
|
|
873
|
+
customPatterns?: CustomPatternDef[];
|
|
874
|
+
/** Symbol definitions (reusable component templates). */
|
|
875
|
+
symbols?: SerializedSymbolDef[];
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* A reusable symbol definition. Contains the shapes that make up the
|
|
879
|
+
* symbol template, plus metadata for the symbols panel.
|
|
880
|
+
*/
|
|
881
|
+
interface SerializedSymbolDef {
|
|
882
|
+
/** Unique identifier for this symbol definition. */
|
|
883
|
+
id: string;
|
|
884
|
+
/** Human-readable name shown in the symbols panel. */
|
|
885
|
+
name: string;
|
|
886
|
+
/** SVG viewBox string ("minX minY width height"). */
|
|
887
|
+
viewBox: string;
|
|
888
|
+
/** The shapes that make up this symbol's content. */
|
|
889
|
+
shapes: SerializedShape[];
|
|
890
|
+
/** Groups within the symbol. */
|
|
891
|
+
groups?: SerializedGroup[];
|
|
892
|
+
/** Base64 data-URI thumbnail for the symbols panel. */
|
|
893
|
+
thumbnail?: string;
|
|
894
|
+
}
|
|
895
|
+
interface SerializedGroup {
|
|
896
|
+
id: string;
|
|
897
|
+
parentId: string | null;
|
|
898
|
+
/** CSS transform-origin value (e.g. "50px 50px") for group animations */
|
|
899
|
+
transformOrigin?: string;
|
|
900
|
+
/**
|
|
901
|
+
* Zero-based position of this group among its parent container's
|
|
902
|
+
* children (including both sibling groups and sibling shape nodes).
|
|
903
|
+
* Used during restoration to correctly interleave groups and shapes
|
|
904
|
+
* so that SVG document order (painting order) is preserved.
|
|
905
|
+
*/
|
|
906
|
+
siblingIndex?: number;
|
|
907
|
+
}
|
|
908
|
+
/** Serialized clip or mask group */
|
|
909
|
+
interface SerializedClipMaskGroup {
|
|
910
|
+
id: string;
|
|
911
|
+
type: 'clip' | 'mask';
|
|
912
|
+
/**
|
|
913
|
+
* @deprecated Use `clipShapeIds` instead. Kept for backward compatibility
|
|
914
|
+
* when reading older documents that used a single clip/mask shape.
|
|
915
|
+
*/
|
|
916
|
+
clipShapeId?: string;
|
|
917
|
+
/** IDs of shape(s) that form the clip/mask definition. */
|
|
918
|
+
clipShapeIds: string[];
|
|
919
|
+
/** IDs of the content shapes being clipped/masked. */
|
|
920
|
+
contentShapeIds: string[];
|
|
921
|
+
parentId: string | null;
|
|
922
|
+
/**
|
|
923
|
+
* Position of the clip/mask group among its parent container's children,
|
|
924
|
+
* so that SVG document order (painting order) is preserved across
|
|
925
|
+
* save / restore.
|
|
926
|
+
*/
|
|
927
|
+
siblingIndex?: number;
|
|
928
|
+
/**
|
|
929
|
+
* Coordinate system for the `<mask>` bounds (`x`, `y`, `width`, `height`).
|
|
930
|
+
* @see CSS Masking Module §9.1 — `maskUnits`
|
|
931
|
+
* @default 'objectBoundingBox'
|
|
932
|
+
*/
|
|
933
|
+
maskUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
|
|
934
|
+
/**
|
|
935
|
+
* Coordinate system for the **contents** of a `<mask>`.
|
|
936
|
+
* @see CSS Masking Module §9.1 — `maskContentUnits`
|
|
937
|
+
* @default 'userSpaceOnUse'
|
|
938
|
+
*/
|
|
939
|
+
maskContentUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
|
|
940
|
+
/**
|
|
941
|
+
* Coordinate system for the contents of a `<clipPath>`.
|
|
942
|
+
* @see CSS Masking Module §6.1 — `clipPathUnits`
|
|
943
|
+
* @default 'userSpaceOnUse'
|
|
944
|
+
*/
|
|
945
|
+
clipPathUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
|
|
946
|
+
/**
|
|
947
|
+
* Explicit mask bounds (`x`, `y`, `width`, `height`).
|
|
948
|
+
* When omitted the browser defaults apply (−10% / 120%).
|
|
949
|
+
*/
|
|
950
|
+
maskBounds?: {
|
|
951
|
+
x: string;
|
|
952
|
+
y: string;
|
|
953
|
+
width: string;
|
|
954
|
+
height: string;
|
|
955
|
+
};
|
|
956
|
+
/**
|
|
957
|
+
* Whether the mask uses luminance or alpha channel.
|
|
958
|
+
* @see CSS Masking Module §9.2 — `mask-type`
|
|
959
|
+
* @default 'luminance'
|
|
960
|
+
*/
|
|
961
|
+
maskType?: 'luminance' | 'alpha';
|
|
962
|
+
/**
|
|
963
|
+
* Raw SVG markup for imported mask/clip definitions that cannot be
|
|
964
|
+
* decomposed into editor `Shape` objects (e.g. multi-element masks
|
|
965
|
+
* with gradients, patterns, or nested groups). When present the
|
|
966
|
+
* editor preserves the original `<mask>` / `<clipPath>` verbatim
|
|
967
|
+
* and `clipShapeIds` may be empty.
|
|
968
|
+
*/
|
|
969
|
+
rawDefinition?: string;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
/**
|
|
973
|
+
* @svgsketch/core — Schema migrations.
|
|
974
|
+
*
|
|
975
|
+
* Migrates a HistorySnapshot from any previous schema version to
|
|
976
|
+
* CURRENT_SCHEMA_VERSION. Each migration step is a pure function
|
|
977
|
+
* that transforms version N to N+1.
|
|
978
|
+
*
|
|
979
|
+
* To add a new migration:
|
|
980
|
+
* 1. Bump CURRENT_SCHEMA_VERSION in types/serialized.ts
|
|
981
|
+
* 2. Add a function migrateVNtoVN+1(snapshot) below
|
|
982
|
+
* 3. Add a case in the switch inside migrateSnapshot()
|
|
983
|
+
*/
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* Migrate a snapshot from any older schema version to the current version.
|
|
987
|
+
*
|
|
988
|
+
* The function is idempotent — if the snapshot is already at the current
|
|
989
|
+
* version (or newer), it is returned unchanged.
|
|
990
|
+
*
|
|
991
|
+
* @param snapshot - The snapshot to migrate (not mutated; a new object is returned)
|
|
992
|
+
* @returns The migrated snapshot at CURRENT_SCHEMA_VERSION
|
|
993
|
+
*/
|
|
994
|
+
declare function migrateSnapshot(snapshot: HistorySnapshot): HistorySnapshot;
|
|
995
|
+
|
|
996
|
+
/**
|
|
997
|
+
* @svgsketch/core — Document validation.
|
|
998
|
+
*
|
|
999
|
+
* Validates the structural correctness of a HistorySnapshot (the .svgs
|
|
1000
|
+
* document format). This is NOT JSON Schema — it performs semantic
|
|
1001
|
+
* validation that static types cannot express:
|
|
1002
|
+
* - required fields present & correct types
|
|
1003
|
+
* - shape IDs are unique
|
|
1004
|
+
* - group references point to existing shapes
|
|
1005
|
+
* - viewbox dimensions are positive
|
|
1006
|
+
* - enum values are valid
|
|
1007
|
+
*/
|
|
1008
|
+
/** A single validation problem. */
|
|
1009
|
+
interface ValidationError {
|
|
1010
|
+
/** Dot-path to the problematic value, e.g. "shapes[2].state.width" */
|
|
1011
|
+
path: string;
|
|
1012
|
+
/** Human-readable description */
|
|
1013
|
+
message: string;
|
|
1014
|
+
/** 'error' = invalid document, 'warning' = loadable but suspicious */
|
|
1015
|
+
severity: 'error' | 'warning';
|
|
1016
|
+
}
|
|
1017
|
+
/** Result returned by validateSnapshot(). */
|
|
1018
|
+
interface ValidationResult {
|
|
1019
|
+
valid: boolean;
|
|
1020
|
+
errors: ValidationError[];
|
|
1021
|
+
warnings: ValidationError[];
|
|
1022
|
+
}
|
|
1023
|
+
/**
|
|
1024
|
+
* Validate a HistorySnapshot for structural and semantic correctness.
|
|
1025
|
+
*
|
|
1026
|
+
* @param snapshot - The document to validate
|
|
1027
|
+
* @returns ValidationResult with `valid` flag plus error/warning lists
|
|
1028
|
+
*/
|
|
1029
|
+
declare function validateSnapshot(snapshot: unknown): ValidationResult;
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* @svgsketch/core — Document factory helpers.
|
|
1033
|
+
*
|
|
1034
|
+
* Pure functions for creating HistorySnapshot documents and adding
|
|
1035
|
+
* shapes programmatically. These are the building blocks for the SDK.
|
|
1036
|
+
*/
|
|
1037
|
+
|
|
1038
|
+
/**
|
|
1039
|
+
* Generate a unique ID suitable for shapes, viewboxes, and guides.
|
|
1040
|
+
* Uses crypto.randomUUID when available, falls back to a timestamp-based ID.
|
|
1041
|
+
*/
|
|
1042
|
+
declare function generateId(): string;
|
|
1043
|
+
/** Options for createDocument(). All fields are optional. */
|
|
1044
|
+
interface CreateDocumentOptions {
|
|
1045
|
+
/** Shapes to include. Default: [] */
|
|
1046
|
+
shapes?: SerializedShape[];
|
|
1047
|
+
/** Viewboxes to include. Default: [] */
|
|
1048
|
+
viewboxes?: SerializedViewbox[];
|
|
1049
|
+
/** Document metadata (title, author, etc.) */
|
|
1050
|
+
metadata?: Partial<DocumentMetadata>;
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Create a new, valid HistorySnapshot.
|
|
1054
|
+
*
|
|
1055
|
+
* @param options - Optional shapes, viewboxes, and metadata
|
|
1056
|
+
* @returns A well-formed HistorySnapshot at the current schema version
|
|
1057
|
+
*/
|
|
1058
|
+
declare function createDocument(options?: CreateDocumentOptions): HistorySnapshot;
|
|
1059
|
+
/** Minimal options for creating a shape. */
|
|
1060
|
+
interface CreateShapeOptions {
|
|
1061
|
+
/** Shape type (required) */
|
|
1062
|
+
type: SerializedShape['type'];
|
|
1063
|
+
/** Optional ID. Auto-generated if omitted. */
|
|
1064
|
+
id?: string;
|
|
1065
|
+
/** Position and dimensions */
|
|
1066
|
+
x?: number;
|
|
1067
|
+
y?: number;
|
|
1068
|
+
width?: number;
|
|
1069
|
+
height?: number;
|
|
1070
|
+
radius?: number;
|
|
1071
|
+
/** Fill */
|
|
1072
|
+
fillColor?: string;
|
|
1073
|
+
fillOpacity?: number;
|
|
1074
|
+
/** Stroke */
|
|
1075
|
+
borderColor?: string;
|
|
1076
|
+
borderWidth?: number;
|
|
1077
|
+
strokeOpacity?: number;
|
|
1078
|
+
/** Transform */
|
|
1079
|
+
rotation?: number;
|
|
1080
|
+
/** Text (for text shapes) */
|
|
1081
|
+
text?: string;
|
|
1082
|
+
fontSize?: number;
|
|
1083
|
+
/** Any additional state properties */
|
|
1084
|
+
[key: string]: unknown;
|
|
1085
|
+
}
|
|
1086
|
+
/**
|
|
1087
|
+
* Create a SerializedShape with sensible defaults.
|
|
1088
|
+
*
|
|
1089
|
+
* @param options - Shape type plus optional position/style/text
|
|
1090
|
+
* @returns A valid SerializedShape ready to add to a document
|
|
1091
|
+
*/
|
|
1092
|
+
declare function createShape(options: CreateShapeOptions): SerializedShape;
|
|
1093
|
+
/**
|
|
1094
|
+
* Create a viewbox (artboard).
|
|
1095
|
+
*
|
|
1096
|
+
* @param x - X position
|
|
1097
|
+
* @param y - Y position
|
|
1098
|
+
* @param width - Width (must be positive)
|
|
1099
|
+
* @param height - Height (must be positive)
|
|
1100
|
+
* @param id - Optional ID. Auto-generated if omitted.
|
|
1101
|
+
* @returns A valid SerializedViewbox
|
|
1102
|
+
*/
|
|
1103
|
+
declare function createViewbox(x: number, y: number, width: number, height: number, id?: string): SerializedViewbox;
|
|
1104
|
+
|
|
1105
|
+
/**
|
|
1106
|
+
* @svgsketch/core — Git-friendly .svgs serializer.
|
|
1107
|
+
*
|
|
1108
|
+
* Converts a HistorySnapshot to a deterministic, human-readable JSON
|
|
1109
|
+
* string optimized for version-control diffs. The output:
|
|
1110
|
+
*
|
|
1111
|
+
* - Sorts top-level sections in a fixed order (schemaVersion, documentMetadata,
|
|
1112
|
+
* viewboxes, guides, measurements, groups, clipMaskGroups, shapes)
|
|
1113
|
+
* - Sorts shapes, viewboxes, groups, guides by `id`
|
|
1114
|
+
* - Sorts object keys alphabetically within each shape/state
|
|
1115
|
+
* - Uses 2-space indentation, one property per line
|
|
1116
|
+
* - Strips `undefined` values (but keeps explicit `null`)
|
|
1117
|
+
* - Produces consistent output regardless of insertion order
|
|
1118
|
+
*
|
|
1119
|
+
* The result can be saved as a `.svgs` file and tracked in Git with
|
|
1120
|
+
* meaningful line-by-line diffs.
|
|
1121
|
+
*/
|
|
1122
|
+
|
|
1123
|
+
/** Options for stringifyDocument(). */
|
|
1124
|
+
interface StringifyOptions {
|
|
1125
|
+
/** Number of spaces per indentation level. Default: 2 */
|
|
1126
|
+
indent?: number;
|
|
1127
|
+
/** Include a trailing newline. Default: true */
|
|
1128
|
+
trailingNewline?: boolean;
|
|
1129
|
+
/** Validate before serializing; throws on invalid docs. Default: false */
|
|
1130
|
+
validate?: boolean;
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Serialize a HistorySnapshot to a deterministic, git-friendly JSON string.
|
|
1134
|
+
*
|
|
1135
|
+
* @param snapshot - The document to serialize
|
|
1136
|
+
* @param options - Formatting options
|
|
1137
|
+
* @returns A formatted JSON string suitable for `.svgs` files
|
|
1138
|
+
* @throws If `options.validate` is true and the snapshot is invalid
|
|
1139
|
+
*/
|
|
1140
|
+
declare function stringifyDocument(snapshot: HistorySnapshot, options?: StringifyOptions): string;
|
|
1141
|
+
/** Options for parseDocument(). */
|
|
1142
|
+
interface ParseOptions {
|
|
1143
|
+
/** Validate after parsing; throws on invalid docs. Default: true */
|
|
1144
|
+
validate?: boolean;
|
|
1145
|
+
/** Run migrations to bring old docs to current schema. Default: true */
|
|
1146
|
+
migrate?: boolean;
|
|
1147
|
+
}
|
|
1148
|
+
/**
|
|
1149
|
+
* Parse a `.svgs` JSON string into a HistorySnapshot.
|
|
1150
|
+
*
|
|
1151
|
+
* @param input - The JSON string to parse
|
|
1152
|
+
* @param options - Parsing options
|
|
1153
|
+
* @returns The parsed (and optionally migrated/validated) HistorySnapshot
|
|
1154
|
+
* @throws On invalid JSON or failed validation
|
|
1155
|
+
*/
|
|
1156
|
+
declare function parseDocument(input: string, options?: ParseOptions): HistorySnapshot;
|
|
1157
|
+
|
|
1158
|
+
/**
|
|
1159
|
+
* @svgsketch/core — Template variable engine.
|
|
1160
|
+
*
|
|
1161
|
+
* Substitutes `{{variableName}}` placeholders in a HistorySnapshot.
|
|
1162
|
+
* Variables can appear in:
|
|
1163
|
+
* - Text content (`state.text`)
|
|
1164
|
+
* - Color values (`state.fillColor`, `state.borderColor`)
|
|
1165
|
+
* - Numeric values (font size, dimensions, etc.)
|
|
1166
|
+
* - Any string property in `state`
|
|
1167
|
+
*
|
|
1168
|
+
* The engine deep-clones the snapshot before substitution so the
|
|
1169
|
+
* original is never mutated.
|
|
1170
|
+
*
|
|
1171
|
+
* @example
|
|
1172
|
+
* ```ts
|
|
1173
|
+
* const result = substituteVariables(snapshot, {
|
|
1174
|
+
* primaryColor: '#e74c3c',
|
|
1175
|
+
* title: 'Hello World',
|
|
1176
|
+
* radius: '50',
|
|
1177
|
+
* });
|
|
1178
|
+
* ```
|
|
1179
|
+
*/
|
|
1180
|
+
|
|
1181
|
+
/** A map of variable name → value for substitution. */
|
|
1182
|
+
type VariableMap = Record<string, string | number>;
|
|
1183
|
+
/**
|
|
1184
|
+
* The result of extracting variable definitions from a document.
|
|
1185
|
+
*/
|
|
1186
|
+
interface ExtractedVariables {
|
|
1187
|
+
/** Defined variables with their defaults and types. */
|
|
1188
|
+
defined: TemplateVariable[];
|
|
1189
|
+
/**
|
|
1190
|
+
* Variable names found in templates (`{{name}}`) that have
|
|
1191
|
+
* no matching definition.
|
|
1192
|
+
*/
|
|
1193
|
+
undeclared: string[];
|
|
1194
|
+
}
|
|
1195
|
+
/**
|
|
1196
|
+
* Substitute `{{var}}` placeholders in a string.
|
|
1197
|
+
* Returns the original string if it contains no placeholders.
|
|
1198
|
+
*/
|
|
1199
|
+
declare function substituteString(template: string, vars: VariableMap): string;
|
|
1200
|
+
/**
|
|
1201
|
+
* Substitute template variables throughout a HistorySnapshot.
|
|
1202
|
+
*
|
|
1203
|
+
* Creates a deep clone, then walks every shape's `state` and replaces
|
|
1204
|
+
* `{{varName}}` in string properties. If a variable resolves to a
|
|
1205
|
+
* number and the target property is numeric, it's coerced.
|
|
1206
|
+
*
|
|
1207
|
+
* Variable values are resolved in this order:
|
|
1208
|
+
* 1. Explicit `vars` argument (highest priority)
|
|
1209
|
+
* 2. Default values from `snapshot.templateVariables`
|
|
1210
|
+
*
|
|
1211
|
+
* @param snapshot - The source snapshot (not mutated)
|
|
1212
|
+
* @param vars - Variable values to substitute
|
|
1213
|
+
* @returns A new HistorySnapshot with substitutions applied
|
|
1214
|
+
*/
|
|
1215
|
+
declare function substituteVariables(snapshot: HistorySnapshot, vars?: VariableMap): HistorySnapshot;
|
|
1216
|
+
/**
|
|
1217
|
+
* Extract variable references from a snapshot.
|
|
1218
|
+
* Returns defined variables and any undeclared references found in templates.
|
|
1219
|
+
*/
|
|
1220
|
+
declare function extractVariables(snapshot: HistorySnapshot): ExtractedVariables;
|
|
1221
|
+
/**
|
|
1222
|
+
* Parse a `key=value` string (from CLI `--var` flags) into a VariableMap.
|
|
1223
|
+
*
|
|
1224
|
+
* @example
|
|
1225
|
+
* ```ts
|
|
1226
|
+
* parseVariableArgs(['primaryColor=#e74c3c', 'title=Hello World', 'radius=50'])
|
|
1227
|
+
* // → { primaryColor: '#e74c3c', title: 'Hello World', radius: '50' }
|
|
1228
|
+
* ```
|
|
1229
|
+
*/
|
|
1230
|
+
declare function parseVariableArgs(args: string[]): VariableMap;
|
|
1231
|
+
|
|
1232
|
+
/**
|
|
1233
|
+
* Document-level SVG renderer.
|
|
1234
|
+
*
|
|
1235
|
+
* Takes a {@link HistorySnapshot} (from a .svgs file) and produces a
|
|
1236
|
+
* standalone SVG string that can be written to disk or piped to a
|
|
1237
|
+
* rasterizer.
|
|
1238
|
+
*/
|
|
1239
|
+
|
|
1240
|
+
interface RenderOptions {
|
|
1241
|
+
/** Explicit width; defaults to first viewbox width or 800. */
|
|
1242
|
+
width?: number;
|
|
1243
|
+
/** Explicit height; defaults to first viewbox height or 600. */
|
|
1244
|
+
height?: number;
|
|
1245
|
+
/** Custom viewBox string, e.g. "0 0 800 600". */
|
|
1246
|
+
viewBox?: string;
|
|
1247
|
+
/** Whether to include the XML declaration. Default true. */
|
|
1248
|
+
xmlDeclaration?: boolean;
|
|
1249
|
+
/** Background color. If set, a <rect> is drawn behind all shapes. */
|
|
1250
|
+
backgroundColor?: string;
|
|
1251
|
+
/** Pretty-print with indentation. Default true. */
|
|
1252
|
+
indent?: boolean;
|
|
1253
|
+
/** CSS class to add to the root <svg>. */
|
|
1254
|
+
className?: string;
|
|
1255
|
+
}
|
|
1256
|
+
/**
|
|
1257
|
+
* Render a snapshot to a standalone SVG string.
|
|
1258
|
+
*
|
|
1259
|
+
* @param snapshot - The deserialized document snapshot
|
|
1260
|
+
* @param options - Optional rendering overrides
|
|
1261
|
+
* @returns A complete SVG document as a string
|
|
1262
|
+
*/
|
|
1263
|
+
declare function renderToSvg(snapshot: HistorySnapshot, options?: RenderOptions): string;
|
|
1264
|
+
|
|
1265
|
+
/**
|
|
1266
|
+
* Filter renderers — convert ShapeFilter[] → SVG `<filter>` definition strings.
|
|
1267
|
+
*
|
|
1268
|
+
* Each filter type maps to one or more SVG filter primitives (feGaussianBlur,
|
|
1269
|
+
* feDropShadow, feColorMatrix, etc.). The logic mirrors the editor's
|
|
1270
|
+
* FilterManager (apps/editor/src/canvas/filter-manager.ts) but produces
|
|
1271
|
+
* strings instead of D3 DOM nodes.
|
|
1272
|
+
*
|
|
1273
|
+
* @packageDocumentation
|
|
1274
|
+
*/
|
|
1275
|
+
|
|
1276
|
+
/**
|
|
1277
|
+
* Render SVG filter primitive string(s) for a single filter.
|
|
1278
|
+
*
|
|
1279
|
+
* This is the canonical implementation used by both the core string renderer
|
|
1280
|
+
* and the editor's DOM-based filter manager (via insertAdjacentHTML).
|
|
1281
|
+
*
|
|
1282
|
+
* @param filter - The filter definition
|
|
1283
|
+
* @param input - Input result name (e.g., 'SourceGraphic' or previous result)
|
|
1284
|
+
* @param output - Output result name for this filter
|
|
1285
|
+
* @param shapeCenter - Optional shape center for light positioning
|
|
1286
|
+
* (point-light, spot-light). When provided, light coordinates are offset
|
|
1287
|
+
* relative to the shape center. When omitted, coordinates are absolute.
|
|
1288
|
+
* @returns SVG string of filter primitives
|
|
1289
|
+
*/
|
|
1290
|
+
declare function renderFilterPrimitivesForType(filter: ShapeFilter, input: string, output: string, shapeCenter?: {
|
|
1291
|
+
x: number;
|
|
1292
|
+
y: number;
|
|
1293
|
+
}): string;
|
|
1294
|
+
/**
|
|
1295
|
+
* Generate `<filter>` definition strings for all shapes that have filters.
|
|
1296
|
+
*
|
|
1297
|
+
* @returns Concatenated `<filter>` elements to include in `<defs>`.
|
|
1298
|
+
*/
|
|
1299
|
+
declare function renderFilterDefs(shapes: SerializedShape[]): string;
|
|
1300
|
+
/**
|
|
1301
|
+
* Get the `filter="url(#...)"` attribute value for a shape, or empty string
|
|
1302
|
+
* if the shape has no enabled filters.
|
|
1303
|
+
*/
|
|
1304
|
+
declare function filterAttr(shapeId: string, filters: ShapeFilter[] | undefined): string;
|
|
1305
|
+
|
|
1306
|
+
/**
|
|
1307
|
+
* Shape renderers — convert SerializedShape → SVG element string.
|
|
1308
|
+
*
|
|
1309
|
+
* Each renderer produces one SVG element (circle, rect, path, text, etc.)
|
|
1310
|
+
* as a string. The caller wraps them in <svg> with <defs>.
|
|
1311
|
+
*/
|
|
1312
|
+
|
|
1313
|
+
declare function renderCircle(shape: SerializedShape): string;
|
|
1314
|
+
declare function renderEllipse(shape: SerializedShape): string;
|
|
1315
|
+
declare function renderRectangle(shape: SerializedShape): string;
|
|
1316
|
+
declare function renderLine(shape: SerializedShape): string;
|
|
1317
|
+
declare function renderText(shape: SerializedShape): string;
|
|
1318
|
+
declare function renderSpline(shape: SerializedShape): string;
|
|
1319
|
+
declare function renderPolyline(shape: SerializedShape): string;
|
|
1320
|
+
declare function renderImage(shape: SerializedShape): string;
|
|
1321
|
+
declare function renderPolygonShape(shape: SerializedShape): string;
|
|
1322
|
+
/** Render any SerializedShape to an SVG element string. */
|
|
1323
|
+
declare function renderShape(shape: SerializedShape): string;
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* Pure geometry functions for computing shape vertices and paths.
|
|
1327
|
+
*
|
|
1328
|
+
* These are headless — no DOM required. They take numeric parameters
|
|
1329
|
+
* and return vertex arrays or SVG path-data strings.
|
|
1330
|
+
*/
|
|
1331
|
+
|
|
1332
|
+
/**
|
|
1333
|
+
* Compute equally-spaced vertices around a circle (for triangle, ngon).
|
|
1334
|
+
* Path is centered at origin; caller applies translate(cx, cy).
|
|
1335
|
+
*/
|
|
1336
|
+
declare function computePolygonVertices(sides: number, radius: number, shiftAngleDeg?: number): Point[];
|
|
1337
|
+
/**
|
|
1338
|
+
* Compute star vertices with alternating outer/inner radii.
|
|
1339
|
+
*/
|
|
1340
|
+
declare function computeStarVertices(arms: number, radius: number, innerRadiusPercent: number, shiftAngleDeg?: number): Point[];
|
|
1341
|
+
/**
|
|
1342
|
+
* Compute cross vertices (12 points forming a plus shape).
|
|
1343
|
+
*/
|
|
1344
|
+
declare function computeCrossVertices(radius: number, armWidthPercent: number, shiftAngleDeg?: number): Point[];
|
|
1345
|
+
/**
|
|
1346
|
+
* Compute arrow vertices (7 points forming an arrow).
|
|
1347
|
+
*/
|
|
1348
|
+
declare function computeArrowVertices(radius: number, headWidthPercent: number, headLengthPercent: number, shaftWidthPercent: number, shiftAngleDeg?: number): Point[];
|
|
1349
|
+
/**
|
|
1350
|
+
* Convert an array of vertices to an SVG path string.
|
|
1351
|
+
* Supports optional rounded corners via quadratic Bézier.
|
|
1352
|
+
*/
|
|
1353
|
+
declare function verticesToPath(vertices: Point[], cornerRadius?: number, radius?: number): string;
|
|
1354
|
+
/**
|
|
1355
|
+
* Generate SVG path for a ring (two concentric circles).
|
|
1356
|
+
*/
|
|
1357
|
+
declare function computeRingPath(radius: number, innerRadiusPercent: number, fillRule?: 'nonzero' | 'evenodd'): string;
|
|
1358
|
+
/**
|
|
1359
|
+
* Generate SVG path for an Archimedean spiral.
|
|
1360
|
+
*/
|
|
1361
|
+
declare function computeSpiralPath(radius: number, turns: number, thicknessPercent: number, spiralDirection?: number, shiftAngleDeg?: number): string;
|
|
1362
|
+
/**
|
|
1363
|
+
* Compute gear vertices (4 vertices per tooth).
|
|
1364
|
+
*/
|
|
1365
|
+
declare function computeGearVertices(teeth: number, radius: number, toothDepthPercent: number, shiftAngleDeg?: number): Point[];
|
|
1366
|
+
/**
|
|
1367
|
+
* Generate full gear path including optional center hole.
|
|
1368
|
+
*/
|
|
1369
|
+
declare function computeGearPath(teeth: number, radius: number, toothDepthPercent: number, cornerRadius?: number, holeRadiusPercent?: number, fillRule?: 'nonzero' | 'evenodd', shiftAngleDeg?: number): string;
|
|
1370
|
+
type CornerShape = 'round' | 'bevel' | 'notch' | 'scoop';
|
|
1371
|
+
/**
|
|
1372
|
+
* Generate SVG path for a rectangle with per-corner radius and shape.
|
|
1373
|
+
* Returns null if all corners are simple (use <rect> instead).
|
|
1374
|
+
*/
|
|
1375
|
+
declare function computeRectanglePath(x: number, y: number, width: number, height: number, cornerRadius: number, cornerShape?: CornerShape, cornerMode?: 'uniform' | 'non-uniform', perCorner?: {
|
|
1376
|
+
radiusTL?: number;
|
|
1377
|
+
radiusTR?: number;
|
|
1378
|
+
radiusBR?: number;
|
|
1379
|
+
radiusBL?: number;
|
|
1380
|
+
shapeTL?: CornerShape;
|
|
1381
|
+
shapeTR?: CornerShape;
|
|
1382
|
+
shapeBR?: CornerShape;
|
|
1383
|
+
shapeBL?: CornerShape;
|
|
1384
|
+
}): string | null;
|
|
1385
|
+
interface SplinePointInput {
|
|
1386
|
+
x: number;
|
|
1387
|
+
y: number;
|
|
1388
|
+
handleIn?: Point;
|
|
1389
|
+
handleOut?: Point;
|
|
1390
|
+
pointType?: string;
|
|
1391
|
+
isSubpathStart?: boolean;
|
|
1392
|
+
segmentType?: string;
|
|
1393
|
+
arcParams?: ArcParams;
|
|
1394
|
+
}
|
|
1395
|
+
interface ArcParams {
|
|
1396
|
+
rx: number;
|
|
1397
|
+
ry: number;
|
|
1398
|
+
rotation: number;
|
|
1399
|
+
largeArc: boolean;
|
|
1400
|
+
sweep: boolean;
|
|
1401
|
+
}
|
|
1402
|
+
/**
|
|
1403
|
+
* Compute SVG path data from spline points.
|
|
1404
|
+
*/
|
|
1405
|
+
declare function computeSplinePath(points: SplinePointInput[], curveType: string, closed?: boolean, tension?: number, arcParams?: ArcParams[]): string;
|
|
1406
|
+
/**
|
|
1407
|
+
* Compute a dash-array string for a given line style.
|
|
1408
|
+
*
|
|
1409
|
+
* @returns A `stroke-dasharray` value like `"8 4"`, or `null` for solid lines.
|
|
1410
|
+
*/
|
|
1411
|
+
declare function computeDashArray(style: string, dashLength: number, gapLength: number): string | null;
|
|
1412
|
+
|
|
1413
|
+
/**
|
|
1414
|
+
* Shared pattern geometry descriptors.
|
|
1415
|
+
*
|
|
1416
|
+
* Both the editor (D3 DOM) and the headless renderer (string concatenation)
|
|
1417
|
+
* consume these declarative element descriptions, eliminating code duplication.
|
|
1418
|
+
*
|
|
1419
|
+
* @packageDocumentation
|
|
1420
|
+
*/
|
|
1421
|
+
|
|
1422
|
+
/**
|
|
1423
|
+
* A declarative description of an SVG element within a pattern tile.
|
|
1424
|
+
*/
|
|
1425
|
+
interface PatternElement {
|
|
1426
|
+
tag: 'rect' | 'circle' | 'path';
|
|
1427
|
+
attrs: Record<string, string | number>;
|
|
1428
|
+
}
|
|
1429
|
+
/**
|
|
1430
|
+
* Return the foreground geometry elements for a given pattern type.
|
|
1431
|
+
*
|
|
1432
|
+
* @param type - One of the 14 built-in pattern type names.
|
|
1433
|
+
* @param size - Tile size in user-space units.
|
|
1434
|
+
* @param color - Foreground CSS colour string.
|
|
1435
|
+
* @param params - Optional per-pattern tuneable parameters (ratios relative to size).
|
|
1436
|
+
* @returns An array of element descriptors (empty for unknown types).
|
|
1437
|
+
*/
|
|
1438
|
+
declare function getPatternElements(type: string, size: number, color: string, params?: PatternParams): PatternElement[];
|
|
1439
|
+
/**
|
|
1440
|
+
* Result of generating pattern SVG content from a preset.
|
|
1441
|
+
*/
|
|
1442
|
+
interface PatternSvgContentResult {
|
|
1443
|
+
/** Serialised SVG markup for the pattern tile (goes inside `<pattern>`). */
|
|
1444
|
+
svgContent: string;
|
|
1445
|
+
/** Tile width in user-space units. */
|
|
1446
|
+
width: number;
|
|
1447
|
+
/** Tile height in user-space units. */
|
|
1448
|
+
height: number;
|
|
1449
|
+
}
|
|
1450
|
+
/**
|
|
1451
|
+
* Generate the full inner SVG markup for a preset pattern tile.
|
|
1452
|
+
*
|
|
1453
|
+
* This produces the exact content that goes inside a `<pattern>` element:
|
|
1454
|
+
* a background rect followed by the foreground geometry from
|
|
1455
|
+
* {@link getPatternElements}.
|
|
1456
|
+
*
|
|
1457
|
+
* @param patternType - One of the 14 built-in pattern type names.
|
|
1458
|
+
* @param scale - Scale multiplier (base tile = 10 × scale).
|
|
1459
|
+
* @param color - Foreground CSS colour string.
|
|
1460
|
+
* @param backgroundColor - Background CSS colour string.
|
|
1461
|
+
* @param params - Optional per-pattern tuneable parameters.
|
|
1462
|
+
* @returns Object with `svgContent`, `width`, and `height`.
|
|
1463
|
+
*/
|
|
1464
|
+
declare function generatePatternSvgContent(patternType: string, scale: number, color: string, backgroundColor: string, params?: PatternParams): PatternSvgContentResult;
|
|
1465
|
+
|
|
1466
|
+
/**
|
|
1467
|
+
* Shared marker descriptors for line endpoints.
|
|
1468
|
+
*
|
|
1469
|
+
* Returns declarative descriptions of SVG `<marker>` definitions.
|
|
1470
|
+
* Consumed by both the core string renderer and the editor's D3 DOM builder.
|
|
1471
|
+
*
|
|
1472
|
+
* @packageDocumentation
|
|
1473
|
+
*/
|
|
1474
|
+
interface MarkerDescriptor {
|
|
1475
|
+
/** Marker element id (e.g., 'line-marker-arrow'). */
|
|
1476
|
+
id: string;
|
|
1477
|
+
/** Reference point X for the marker tip. */
|
|
1478
|
+
refX: number;
|
|
1479
|
+
/** Reference point Y for the marker center. */
|
|
1480
|
+
refY: number;
|
|
1481
|
+
/** The child shape element inside the marker. */
|
|
1482
|
+
element: {
|
|
1483
|
+
tag: string;
|
|
1484
|
+
attrs: Record<string, string | number>;
|
|
1485
|
+
};
|
|
1486
|
+
}
|
|
1487
|
+
/** All markers share this viewBox. */
|
|
1488
|
+
declare const MARKER_VIEWBOX = "0 0 10 10";
|
|
1489
|
+
declare const MARKER_WIDTH = 6;
|
|
1490
|
+
declare const MARKER_HEIGHT = 6;
|
|
1491
|
+
/**
|
|
1492
|
+
* Return the canonical marker descriptors for all line endpoint types.
|
|
1493
|
+
*
|
|
1494
|
+
* All markers use `viewBox="0 0 10 10"`, `markerWidth=6`, `markerHeight=6`,
|
|
1495
|
+
* `markerUnits="strokeWidth"`, and `orient="auto-start-reverse"`.
|
|
1496
|
+
*/
|
|
1497
|
+
declare function getMarkerDescriptors(): MarkerDescriptor[];
|
|
1498
|
+
|
|
1499
|
+
/**
|
|
1500
|
+
* SMIL animation renderer — converts SerializedAnimationTimeline
|
|
1501
|
+
* data into inline SVG animation elements.
|
|
1502
|
+
*
|
|
1503
|
+
* Produces:
|
|
1504
|
+
* - `<animate>` for numeric and color properties
|
|
1505
|
+
* - `<animateTransform>` for rotation, skewX, skewY
|
|
1506
|
+
* - `<animateMotion>` for path-based motion
|
|
1507
|
+
*
|
|
1508
|
+
* The output is a map from shape ID → array of SVG element strings
|
|
1509
|
+
* so the main renderer can inject them as children of each shape element.
|
|
1510
|
+
*/
|
|
1511
|
+
|
|
1512
|
+
/**
|
|
1513
|
+
* Render animation tracks to a map of shape ID → SMIL element strings.
|
|
1514
|
+
*
|
|
1515
|
+
* The caller injects these strings as children of the corresponding
|
|
1516
|
+
* SVG shape elements.
|
|
1517
|
+
*
|
|
1518
|
+
* @param timeline - The serialized animation timeline
|
|
1519
|
+
* @returns Map from shape ID to an array of SVG animation element strings
|
|
1520
|
+
*/
|
|
1521
|
+
declare function renderAnimationElements(timeline: SerializedAnimationTimeline): Map<string, string[]>;
|
|
1522
|
+
|
|
1523
|
+
/**
|
|
1524
|
+
* Code generation dispatcher — routes to format-specific generators.
|
|
1525
|
+
*/
|
|
1526
|
+
|
|
1527
|
+
/** Supported code output formats. */
|
|
1528
|
+
type CodeFormat = 'svg' | 'react' | 'vue' | 'd3' | 'css';
|
|
1529
|
+
/** Options for code generation. */
|
|
1530
|
+
interface CodegenOptions {
|
|
1531
|
+
/** Target code format. */
|
|
1532
|
+
format: CodeFormat;
|
|
1533
|
+
/** Component/function name (used by React, Vue, D3). Defaults to 'SvgComponent'. */
|
|
1534
|
+
componentName?: string;
|
|
1535
|
+
/** Whether to include the XML declaration for SVG format. Default false. */
|
|
1536
|
+
xmlDeclaration?: boolean;
|
|
1537
|
+
/** Canvas width. Defaults to first viewbox width or 800. */
|
|
1538
|
+
width?: number;
|
|
1539
|
+
/** Canvas height. Defaults to first viewbox height or 600. */
|
|
1540
|
+
height?: number;
|
|
1541
|
+
/** Whether to use TypeScript syntax (React/D3). Default false. */
|
|
1542
|
+
typescript?: boolean;
|
|
1543
|
+
/** Indent string. Default ' ' (2 spaces). */
|
|
1544
|
+
indent?: string;
|
|
1545
|
+
}
|
|
1546
|
+
/**
|
|
1547
|
+
* Generate code from a snapshot or array of shapes.
|
|
1548
|
+
*
|
|
1549
|
+
* @param input - A HistorySnapshot or an array of SerializedShape
|
|
1550
|
+
* @param options - Code generation options
|
|
1551
|
+
* @returns Generated code as a string
|
|
1552
|
+
*/
|
|
1553
|
+
declare function generateCode(input: HistorySnapshot | SerializedShape[], options: CodegenOptions): string;
|
|
1554
|
+
|
|
1555
|
+
/**
|
|
1556
|
+
* Shared helpers for code generators.
|
|
1557
|
+
*/
|
|
1558
|
+
|
|
1559
|
+
/** Escape special XML characters. */
|
|
1560
|
+
declare function escXml(value: string): string;
|
|
1561
|
+
|
|
1562
|
+
/**
|
|
1563
|
+
* Raw SVG code generator.
|
|
1564
|
+
*
|
|
1565
|
+
* Produces a standalone SVG string using the headless renderer.
|
|
1566
|
+
* This is the simplest format — it re-uses renderToSvg directly.
|
|
1567
|
+
*/
|
|
1568
|
+
|
|
1569
|
+
/**
|
|
1570
|
+
* Generate raw SVG markup from a snapshot.
|
|
1571
|
+
*/
|
|
1572
|
+
declare function generateSvgCode(snapshot: HistorySnapshot, options: CodegenOptions): string;
|
|
1573
|
+
|
|
1574
|
+
/**
|
|
1575
|
+
* React/JSX code generator.
|
|
1576
|
+
*
|
|
1577
|
+
* Produces a functional React component that renders the shapes as JSX.
|
|
1578
|
+
* Converts SVG attributes to JSX-compatible camelCase (stroke-width → strokeWidth).
|
|
1579
|
+
*/
|
|
1580
|
+
|
|
1581
|
+
/**
|
|
1582
|
+
* Generate a React functional component from a snapshot.
|
|
1583
|
+
*/
|
|
1584
|
+
declare function generateReactCode(snapshot: HistorySnapshot, options: CodegenOptions): string;
|
|
1585
|
+
|
|
1586
|
+
/**
|
|
1587
|
+
* Vue SFC code generator.
|
|
1588
|
+
*
|
|
1589
|
+
* Produces a Vue Single File Component (SFC) with a <template> containing
|
|
1590
|
+
* the SVG and a <script setup> block.
|
|
1591
|
+
*/
|
|
1592
|
+
|
|
1593
|
+
/**
|
|
1594
|
+
* Generate a Vue SFC from a snapshot.
|
|
1595
|
+
*/
|
|
1596
|
+
declare function generateVueCode(snapshot: HistorySnapshot, options: CodegenOptions): string;
|
|
1597
|
+
|
|
1598
|
+
/**
|
|
1599
|
+
* D3.js code generator.
|
|
1600
|
+
*
|
|
1601
|
+
* Produces a JavaScript/TypeScript function that uses D3 selections to
|
|
1602
|
+
* programmatically build the SVG DOM.
|
|
1603
|
+
*/
|
|
1604
|
+
|
|
1605
|
+
/**
|
|
1606
|
+
* Generate D3.js code from a snapshot.
|
|
1607
|
+
*/
|
|
1608
|
+
declare function generateD3Code(snapshot: HistorySnapshot, options: CodegenOptions): string;
|
|
1609
|
+
|
|
1610
|
+
/**
|
|
1611
|
+
* CSS code generator.
|
|
1612
|
+
*
|
|
1613
|
+
* Produces SVG with inline classes plus a companion CSS block.
|
|
1614
|
+
* Extracts fill, stroke, opacity, and transform styles into CSS classes.
|
|
1615
|
+
*/
|
|
1616
|
+
|
|
1617
|
+
/**
|
|
1618
|
+
* Generate CSS + SVG markup from a snapshot.
|
|
1619
|
+
*
|
|
1620
|
+
* Output format:
|
|
1621
|
+
* ```
|
|
1622
|
+
* <style>
|
|
1623
|
+
* .circle-1 { fill: #ff0000; stroke: #000; }
|
|
1624
|
+
* </style>
|
|
1625
|
+
* <svg ...>
|
|
1626
|
+
* <circle class="circle-1" cx="100" cy="100" r="50"/>
|
|
1627
|
+
* </svg>
|
|
1628
|
+
* ```
|
|
1629
|
+
*/
|
|
1630
|
+
declare function generateCssCode(snapshot: HistorySnapshot, options: CodegenOptions): string;
|
|
1631
|
+
|
|
1632
|
+
/**
|
|
1633
|
+
* Style builder helpers — fluent constructors for gradients and patterns.
|
|
1634
|
+
*
|
|
1635
|
+
* @example
|
|
1636
|
+
* ```ts
|
|
1637
|
+
* import { linearGradient, radialGradient, pattern } from '@svgsketch/core';
|
|
1638
|
+
*
|
|
1639
|
+
* const sunset = linearGradient(0, 0, 0, 1)
|
|
1640
|
+
* .stop(0, '#ff6b6b')
|
|
1641
|
+
* .stop(0.5, '#ffa726')
|
|
1642
|
+
* .stop(1, '#ffee58');
|
|
1643
|
+
*
|
|
1644
|
+
* const glow = radialGradient()
|
|
1645
|
+
* .center(0.5, 0.5)
|
|
1646
|
+
* .radius(0.5)
|
|
1647
|
+
* .stop(0, '#ffffff')
|
|
1648
|
+
* .stop(1, '#000000');
|
|
1649
|
+
*
|
|
1650
|
+
* const stripes = pattern('stripes', '#333', '#fff');
|
|
1651
|
+
* ```
|
|
1652
|
+
*/
|
|
1653
|
+
|
|
1654
|
+
declare class LinearGradientBuilder {
|
|
1655
|
+
private _x1;
|
|
1656
|
+
private _y1;
|
|
1657
|
+
private _x2;
|
|
1658
|
+
private _y2;
|
|
1659
|
+
private _stops;
|
|
1660
|
+
private _spreadMethod;
|
|
1661
|
+
private _opacity;
|
|
1662
|
+
private _id;
|
|
1663
|
+
constructor(x1?: number, y1?: number, x2?: number, y2?: number);
|
|
1664
|
+
/** Add a color stop. Offset is 0–1. */
|
|
1665
|
+
stop(offset: number, color: string, opacity?: number): this;
|
|
1666
|
+
/** Set the gradient direction. Values are 0–1 fractions. */
|
|
1667
|
+
direction(x1: number, y1: number, x2: number, y2: number): this;
|
|
1668
|
+
/** Set the spread method. */
|
|
1669
|
+
spread(method: GradientSpreadMethod): this;
|
|
1670
|
+
/** Set the overall gradient opacity. */
|
|
1671
|
+
opacity(value: number): this;
|
|
1672
|
+
/** Build the gradient definition object. */
|
|
1673
|
+
build(): LinearGradient;
|
|
1674
|
+
}
|
|
1675
|
+
declare class RadialGradientBuilder {
|
|
1676
|
+
private _cx;
|
|
1677
|
+
private _cy;
|
|
1678
|
+
private _fx;
|
|
1679
|
+
private _fy;
|
|
1680
|
+
private _r;
|
|
1681
|
+
private _ry;
|
|
1682
|
+
private _rotation;
|
|
1683
|
+
private _stops;
|
|
1684
|
+
private _spreadMethod;
|
|
1685
|
+
private _opacity;
|
|
1686
|
+
private _id;
|
|
1687
|
+
constructor();
|
|
1688
|
+
/** Set the center point (0–1). */
|
|
1689
|
+
center(cx: number, cy: number): this;
|
|
1690
|
+
/** Set the focal point (0–1). */
|
|
1691
|
+
focus(fx: number, fy: number): this;
|
|
1692
|
+
/** Set the radius (0–1). */
|
|
1693
|
+
radius(r: number, ry?: number): this;
|
|
1694
|
+
/** Set the rotation in degrees. */
|
|
1695
|
+
rotation(degrees: number): this;
|
|
1696
|
+
/** Add a color stop. Offset is 0–1. */
|
|
1697
|
+
stop(offset: number, color: string, opacity?: number): this;
|
|
1698
|
+
/** Set the spread method. */
|
|
1699
|
+
spread(method: GradientSpreadMethod): this;
|
|
1700
|
+
/** Set the overall gradient opacity. */
|
|
1701
|
+
opacity(value: number): this;
|
|
1702
|
+
/** Build the gradient definition object. */
|
|
1703
|
+
build(): RadialGradient;
|
|
1704
|
+
}
|
|
1705
|
+
declare class PatternBuilder {
|
|
1706
|
+
private _patternType;
|
|
1707
|
+
private _color;
|
|
1708
|
+
private _backgroundColor;
|
|
1709
|
+
private _scale;
|
|
1710
|
+
private _rotation;
|
|
1711
|
+
private _opacity;
|
|
1712
|
+
private _patternParams?;
|
|
1713
|
+
private _id;
|
|
1714
|
+
private _svgContent?;
|
|
1715
|
+
private _width?;
|
|
1716
|
+
private _height?;
|
|
1717
|
+
private _patternUnits?;
|
|
1718
|
+
private _patternContentUnits?;
|
|
1719
|
+
private _patternTransform?;
|
|
1720
|
+
private _viewBox?;
|
|
1721
|
+
private _preserveAspectRatio?;
|
|
1722
|
+
private _x?;
|
|
1723
|
+
private _y?;
|
|
1724
|
+
private _customPatternId?;
|
|
1725
|
+
constructor(patternType?: PatternType, color?: string, backgroundColor?: string);
|
|
1726
|
+
/** Set the pattern scale. */
|
|
1727
|
+
scale(value: number): this;
|
|
1728
|
+
/** Set the pattern rotation in degrees. */
|
|
1729
|
+
rotation(degrees: number): this;
|
|
1730
|
+
/** Set the overall pattern opacity. */
|
|
1731
|
+
opacity(value: number): this;
|
|
1732
|
+
/** Set per-pattern tuneable parameters (strokeWidth, dotRadius, amplitude). */
|
|
1733
|
+
params(value: PatternParams): this;
|
|
1734
|
+
/** Set custom SVG content for the pattern tile (bypasses preset generation). */
|
|
1735
|
+
svgContent(content: string): this;
|
|
1736
|
+
/** Set the pattern tile size. */
|
|
1737
|
+
size(width: number, height: number): this;
|
|
1738
|
+
/** Set the coordinate system for pattern bounds. */
|
|
1739
|
+
patternUnits(value: 'userSpaceOnUse' | 'objectBoundingBox'): this;
|
|
1740
|
+
/** Set the coordinate system for pattern tile contents. */
|
|
1741
|
+
patternContentUnits(value: 'userSpaceOnUse' | 'objectBoundingBox'): this;
|
|
1742
|
+
/** Set the pattern transform string (e.g. `"rotate(45) scale(2)"`). */
|
|
1743
|
+
patternTransform(value: string): this;
|
|
1744
|
+
/** Set the viewBox for the pattern tile coordinate system. */
|
|
1745
|
+
viewBox(value: string): this;
|
|
1746
|
+
/** Set the preserveAspectRatio attribute. */
|
|
1747
|
+
preserveAspectRatio(value: string): this;
|
|
1748
|
+
/** Set the tile origin offset. */
|
|
1749
|
+
position(x: number, y: number): this;
|
|
1750
|
+
/** Link this fill to a document-level custom pattern definition. */
|
|
1751
|
+
customPatternId(id: string): this;
|
|
1752
|
+
/** Build the pattern fill object. */
|
|
1753
|
+
build(): PatternFill;
|
|
1754
|
+
}
|
|
1755
|
+
/**
|
|
1756
|
+
* Create a linear gradient builder.
|
|
1757
|
+
*
|
|
1758
|
+
* @param x1 - Start X (0–1). Default 0.
|
|
1759
|
+
* @param y1 - Start Y (0–1). Default 0.
|
|
1760
|
+
* @param x2 - End X (0–1). Default 1.
|
|
1761
|
+
* @param y2 - End Y (0–1). Default 0.
|
|
1762
|
+
*/
|
|
1763
|
+
declare function linearGradient(x1?: number, y1?: number, x2?: number, y2?: number): LinearGradientBuilder;
|
|
1764
|
+
/**
|
|
1765
|
+
* Create a radial gradient builder.
|
|
1766
|
+
*/
|
|
1767
|
+
declare function radialGradient(): RadialGradientBuilder;
|
|
1768
|
+
/**
|
|
1769
|
+
* Create a pattern fill builder.
|
|
1770
|
+
*
|
|
1771
|
+
* @param patternType - Pattern type (e.g. 'stripes', 'dots', 'grid').
|
|
1772
|
+
* @param color - Foreground color. Default '#000000'.
|
|
1773
|
+
* @param backgroundColor - Background color. Default '#ffffff'.
|
|
1774
|
+
*/
|
|
1775
|
+
declare function pattern(patternType?: PatternType, color?: string, backgroundColor?: string): PatternBuilder;
|
|
1776
|
+
|
|
1777
|
+
/**
|
|
1778
|
+
* Shape builder classes — fluent API for constructing shapes.
|
|
1779
|
+
*
|
|
1780
|
+
* Each class corresponds to one of the 17 supported shape types.
|
|
1781
|
+
* All builders extend `ShapeBuilder` which provides common styling
|
|
1782
|
+
* and transform methods that return `this` for chaining.
|
|
1783
|
+
*
|
|
1784
|
+
* @example
|
|
1785
|
+
* ```ts
|
|
1786
|
+
* import { Circle, Rectangle, Star } from '@svgsketch/core';
|
|
1787
|
+
*
|
|
1788
|
+
* const c = new Circle(100, 200, 50)
|
|
1789
|
+
* .fill('#3498db')
|
|
1790
|
+
* .stroke('#2980b9', 3)
|
|
1791
|
+
* .opacity(0.9);
|
|
1792
|
+
*
|
|
1793
|
+
* const r = new Rectangle(10, 20, 200, 100)
|
|
1794
|
+
* .fill('#e74c3c')
|
|
1795
|
+
* .cornerRadius(12);
|
|
1796
|
+
*
|
|
1797
|
+
* const s = new Star(300, 300, 80)
|
|
1798
|
+
* .arms(6)
|
|
1799
|
+
* .innerRadius(40)
|
|
1800
|
+
* .fill('#f1c40f');
|
|
1801
|
+
* ```
|
|
1802
|
+
*/
|
|
1803
|
+
|
|
1804
|
+
type LineStyle = 'solid' | 'dashed' | 'dotted' | 'custom';
|
|
1805
|
+
type EndpointStyle = 'none' | 'arrow' | 'open-arrow' | 'circle' | 'diamond' | 'square';
|
|
1806
|
+
type FontWeight = 'normal' | 'bold' | 'lighter' | 'bolder' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900';
|
|
1807
|
+
type FontStyle = 'normal' | 'italic' | 'oblique';
|
|
1808
|
+
type TextTransform = 'none' | 'uppercase' | 'lowercase' | 'capitalize';
|
|
1809
|
+
/**
|
|
1810
|
+
* Abstract shape builder with shared styling, transform, and metadata methods.
|
|
1811
|
+
* All methods return `this` for chaining.
|
|
1812
|
+
*/
|
|
1813
|
+
declare abstract class ShapeBuilder<T extends ShapeBuilder<T>> {
|
|
1814
|
+
protected _id: string;
|
|
1815
|
+
protected _type: SerializedShape['type'];
|
|
1816
|
+
protected _state: Record<string, unknown>;
|
|
1817
|
+
constructor(type: SerializedShape['type'], id?: string);
|
|
1818
|
+
/** Set the shape ID. */
|
|
1819
|
+
id(value: string): T;
|
|
1820
|
+
/** Lock the shape (prevent editing). */
|
|
1821
|
+
locked(value?: boolean): T;
|
|
1822
|
+
/** Set visibility. */
|
|
1823
|
+
visible(value?: boolean): T;
|
|
1824
|
+
/** Set a solid fill color. */
|
|
1825
|
+
fill(color: string, opacity?: number): T;
|
|
1826
|
+
/** Set fill to none (transparent). */
|
|
1827
|
+
noFill(): T;
|
|
1828
|
+
/** Set a gradient fill (linear or radial). */
|
|
1829
|
+
fillGradient(gradient: LinearGradientBuilder | RadialGradientBuilder | LinearGradient | RadialGradient): T;
|
|
1830
|
+
/** Set a pattern fill. */
|
|
1831
|
+
fillPattern(patternOrBuilder: PatternBuilder | PatternFill): T;
|
|
1832
|
+
/** Set the fill opacity (0–1). */
|
|
1833
|
+
fillOpacity(value: number): T;
|
|
1834
|
+
/** Set the fill rule. */
|
|
1835
|
+
fillRule(rule: 'nonzero' | 'evenodd'): T;
|
|
1836
|
+
/** Set the stroke color and optional width. */
|
|
1837
|
+
stroke(color: string, width?: number): T;
|
|
1838
|
+
/** Set stroke to none. */
|
|
1839
|
+
noStroke(): T;
|
|
1840
|
+
/** Set the stroke width. */
|
|
1841
|
+
strokeWidth(value: number): T;
|
|
1842
|
+
/** Set the stroke opacity (0–1). */
|
|
1843
|
+
strokeOpacity(value: number): T;
|
|
1844
|
+
/** Set a gradient stroke. */
|
|
1845
|
+
strokeGradient(gradient: LinearGradientBuilder | RadialGradientBuilder | LinearGradient | RadialGradient): T;
|
|
1846
|
+
/** Set a pattern stroke. */
|
|
1847
|
+
strokePattern(patternOrBuilder: PatternBuilder | PatternFill): T;
|
|
1848
|
+
/** Set the stroke line join style. */
|
|
1849
|
+
strokeLinejoin(value: 'miter' | 'round' | 'bevel'): T;
|
|
1850
|
+
/** Set the stroke line cap style. */
|
|
1851
|
+
strokeLinecap(value: 'butt' | 'round' | 'square'): T;
|
|
1852
|
+
/** Set the stroke miter limit. */
|
|
1853
|
+
strokeMiterlimit(value: number): T;
|
|
1854
|
+
/** Set the stroke dash offset. */
|
|
1855
|
+
dashOffset(value: number): T;
|
|
1856
|
+
/** Set a raw SVG stroke-dasharray string for complex dash patterns. */
|
|
1857
|
+
strokeDasharray(value: string): T;
|
|
1858
|
+
/** Set the line/dash style. */
|
|
1859
|
+
dash(style: LineStyle, dashLength?: number, gapLength?: number): T;
|
|
1860
|
+
/** Set the overall opacity (0–1). */
|
|
1861
|
+
opacity(value: number): T;
|
|
1862
|
+
/** Set the rotation in degrees. */
|
|
1863
|
+
rotate(degrees: number): T;
|
|
1864
|
+
/** Set the skew. */
|
|
1865
|
+
skew(x: number, y: number): T;
|
|
1866
|
+
/** Set the scale. */
|
|
1867
|
+
scale(x: number, y?: number): T;
|
|
1868
|
+
/** Set a custom pivot point for transforms. */
|
|
1869
|
+
pivot(x: number, y: number): T;
|
|
1870
|
+
/** Add one or more filters to the shape. */
|
|
1871
|
+
filter(...filters: ShapeFilter[]): T;
|
|
1872
|
+
/** Add a drop shadow filter. */
|
|
1873
|
+
dropShadow(options?: {
|
|
1874
|
+
offsetX?: number;
|
|
1875
|
+
offsetY?: number;
|
|
1876
|
+
blurRadius?: number;
|
|
1877
|
+
spread?: number;
|
|
1878
|
+
color?: string;
|
|
1879
|
+
opacity?: number;
|
|
1880
|
+
}): T;
|
|
1881
|
+
/** Add an inner shadow filter. */
|
|
1882
|
+
innerShadow(options?: {
|
|
1883
|
+
offsetX?: number;
|
|
1884
|
+
offsetY?: number;
|
|
1885
|
+
blurRadius?: number;
|
|
1886
|
+
choke?: number;
|
|
1887
|
+
color?: string;
|
|
1888
|
+
opacity?: number;
|
|
1889
|
+
}): T;
|
|
1890
|
+
/** Add a Gaussian blur filter. */
|
|
1891
|
+
blur(radiusOrX?: number, radiusY?: number, options?: {
|
|
1892
|
+
quality?: BlurQuality;
|
|
1893
|
+
}): T;
|
|
1894
|
+
/** Add an outer glow filter. */
|
|
1895
|
+
glow(options?: {
|
|
1896
|
+
color?: string;
|
|
1897
|
+
radius?: number;
|
|
1898
|
+
intensity?: number;
|
|
1899
|
+
}): T;
|
|
1900
|
+
/** Add an inner glow filter. */
|
|
1901
|
+
innerGlow(options?: {
|
|
1902
|
+
color?: string;
|
|
1903
|
+
radius?: number;
|
|
1904
|
+
intensity?: number;
|
|
1905
|
+
}): T;
|
|
1906
|
+
/** Add a grayscale filter. */
|
|
1907
|
+
grayscale(amount?: number): T;
|
|
1908
|
+
/** Add a sepia filter. */
|
|
1909
|
+
sepia(amount?: number): T;
|
|
1910
|
+
/** Add an outline filter. */
|
|
1911
|
+
outline(options?: {
|
|
1912
|
+
width?: number;
|
|
1913
|
+
color?: string;
|
|
1914
|
+
opacity?: number;
|
|
1915
|
+
position?: OutlinePosition;
|
|
1916
|
+
}): T;
|
|
1917
|
+
/** Add a motion blur filter. */
|
|
1918
|
+
motionBlur(options?: {
|
|
1919
|
+
distance?: number;
|
|
1920
|
+
angle?: number;
|
|
1921
|
+
quality?: BlurQuality;
|
|
1922
|
+
}): T;
|
|
1923
|
+
/** Add a point light filter. */
|
|
1924
|
+
pointLight(options?: {
|
|
1925
|
+
x?: number;
|
|
1926
|
+
y?: number;
|
|
1927
|
+
z?: number;
|
|
1928
|
+
color?: string;
|
|
1929
|
+
surfaceScale?: number;
|
|
1930
|
+
diffuseConstant?: number;
|
|
1931
|
+
specularConstant?: number;
|
|
1932
|
+
specularExponent?: number;
|
|
1933
|
+
}): T;
|
|
1934
|
+
/** Add a spot light filter. */
|
|
1935
|
+
spotLight(options?: {
|
|
1936
|
+
x?: number;
|
|
1937
|
+
y?: number;
|
|
1938
|
+
z?: number;
|
|
1939
|
+
pointsAtX?: number;
|
|
1940
|
+
pointsAtY?: number;
|
|
1941
|
+
pointsAtZ?: number;
|
|
1942
|
+
coneAngle?: number;
|
|
1943
|
+
color?: string;
|
|
1944
|
+
surfaceScale?: number;
|
|
1945
|
+
specularConstant?: number;
|
|
1946
|
+
specularExponent?: number;
|
|
1947
|
+
}): T;
|
|
1948
|
+
/** Add a sharpen filter. */
|
|
1949
|
+
sharpen(amount?: number): T;
|
|
1950
|
+
/** Add a pixelate filter. */
|
|
1951
|
+
pixelate(blockSize?: number): T;
|
|
1952
|
+
/** Add a warp filter. */
|
|
1953
|
+
warp(options?: {
|
|
1954
|
+
scale?: number;
|
|
1955
|
+
frequency?: number;
|
|
1956
|
+
octaves?: number;
|
|
1957
|
+
warpType?: WarpType;
|
|
1958
|
+
}): T;
|
|
1959
|
+
/** Add a morphology filter (dilate or erode). */
|
|
1960
|
+
morphology(options?: {
|
|
1961
|
+
operator?: MorphologyOperator;
|
|
1962
|
+
radiusX?: number;
|
|
1963
|
+
radiusY?: number;
|
|
1964
|
+
linked?: boolean;
|
|
1965
|
+
}): T;
|
|
1966
|
+
/** Add a contouring filter (discrete or table mode). */
|
|
1967
|
+
contouring(options?: {
|
|
1968
|
+
mode?: 'discrete' | 'table';
|
|
1969
|
+
levels?: number;
|
|
1970
|
+
contrast?: number;
|
|
1971
|
+
}): T;
|
|
1972
|
+
/** Add a round edges filter. */
|
|
1973
|
+
roundEdges(radius?: number): T;
|
|
1974
|
+
/** Add a channel painter filter. */
|
|
1975
|
+
channelPainter(options?: {
|
|
1976
|
+
red?: number;
|
|
1977
|
+
green?: number;
|
|
1978
|
+
blue?: number;
|
|
1979
|
+
}): T;
|
|
1980
|
+
/** Add a brightness filter. */
|
|
1981
|
+
brightness(amount?: number): T;
|
|
1982
|
+
/** Add a contrast filter. */
|
|
1983
|
+
contrast(amount?: number): T;
|
|
1984
|
+
/** Add an opacity filter. */
|
|
1985
|
+
filterOpacity(amount?: number): T;
|
|
1986
|
+
/** Add an invert filter. */
|
|
1987
|
+
invert(amount?: number): T;
|
|
1988
|
+
/** Add a hue-rotate filter. */
|
|
1989
|
+
hueRotate(angle?: number): T;
|
|
1990
|
+
/** Add a saturate filter. */
|
|
1991
|
+
saturate(amount?: number): T;
|
|
1992
|
+
/** Add a black-and-white filter. */
|
|
1993
|
+
blackAndWhite(threshold?: number): T;
|
|
1994
|
+
/** Add a duotone filter. */
|
|
1995
|
+
duotone(options?: {
|
|
1996
|
+
shadowColor?: string;
|
|
1997
|
+
highlightColor?: string;
|
|
1998
|
+
}): T;
|
|
1999
|
+
/** Add an x-ray filter. */
|
|
2000
|
+
xray(intensity?: number): T;
|
|
2001
|
+
/** Add a noise filter. */
|
|
2002
|
+
noise(options?: {
|
|
2003
|
+
amount?: number;
|
|
2004
|
+
scale?: number;
|
|
2005
|
+
}): T;
|
|
2006
|
+
/** Add an emboss filter. */
|
|
2007
|
+
emboss(options?: {
|
|
2008
|
+
strength?: number;
|
|
2009
|
+
angle?: number;
|
|
2010
|
+
}): T;
|
|
2011
|
+
/** Add a film grain filter. */
|
|
2012
|
+
filmGrain(options?: {
|
|
2013
|
+
amount?: number;
|
|
2014
|
+
size?: number;
|
|
2015
|
+
}): T;
|
|
2016
|
+
/** Add a watercolor filter. */
|
|
2017
|
+
watercolor(options?: {
|
|
2018
|
+
wetness?: number;
|
|
2019
|
+
turbulence?: number;
|
|
2020
|
+
}): T;
|
|
2021
|
+
/** Add a gouache filter. */
|
|
2022
|
+
gouache(options?: {
|
|
2023
|
+
thickness?: number;
|
|
2024
|
+
texture?: number;
|
|
2025
|
+
}): T;
|
|
2026
|
+
/** Add an ink blot filter. */
|
|
2027
|
+
inkBlot(options?: {
|
|
2028
|
+
spread?: number;
|
|
2029
|
+
edges?: number;
|
|
2030
|
+
}): T;
|
|
2031
|
+
/** Add a crumpled plastic filter. */
|
|
2032
|
+
crumpledPlastic(options?: {
|
|
2033
|
+
wrinkles?: number;
|
|
2034
|
+
shine?: number;
|
|
2035
|
+
}): T;
|
|
2036
|
+
/** Add a riddled filter. */
|
|
2037
|
+
riddled(options?: {
|
|
2038
|
+
density?: number;
|
|
2039
|
+
size?: number;
|
|
2040
|
+
}): T;
|
|
2041
|
+
/** Set a CSS basic-shape clip-path value (e.g. `circle(50%)`, `inset(10px)`, `polygon(…)`). */
|
|
2042
|
+
cssClipPath(value: string): T;
|
|
2043
|
+
/** Set CSS mask sub-properties (`mask-image`, `mask-mode`, etc.). */
|
|
2044
|
+
cssMaskProperties(props: Record<string, string>): T;
|
|
2045
|
+
/** Set shape metadata (name, title, description, etc). */
|
|
2046
|
+
metadata(meta: Partial<ShapeMetadata>): T;
|
|
2047
|
+
/** Assign this shape to a group. */
|
|
2048
|
+
group(groupId: string): T;
|
|
2049
|
+
/** Build the SerializedShape object. */
|
|
2050
|
+
build(): SerializedShape;
|
|
2051
|
+
}
|
|
2052
|
+
declare class Circle extends ShapeBuilder<Circle> {
|
|
2053
|
+
constructor(x: number, y: number, radius: number);
|
|
2054
|
+
/** Set the center position and radius. */
|
|
2055
|
+
position(x: number, y: number): Circle;
|
|
2056
|
+
/** Set the radius. */
|
|
2057
|
+
radius(r: number): Circle;
|
|
2058
|
+
}
|
|
2059
|
+
declare class Ellipse extends ShapeBuilder<Ellipse> {
|
|
2060
|
+
constructor(cx: number, cy: number, rx: number, ry: number);
|
|
2061
|
+
position(cx: number, cy: number): Ellipse;
|
|
2062
|
+
radii(rx: number, ry: number): Ellipse;
|
|
2063
|
+
}
|
|
2064
|
+
declare class Rectangle extends ShapeBuilder<Rectangle> {
|
|
2065
|
+
constructor(x: number, y: number, width: number, height: number);
|
|
2066
|
+
position(x: number, y: number): Rectangle;
|
|
2067
|
+
size(width: number, height: number): Rectangle;
|
|
2068
|
+
/** Set the corner radius for rounded rectangles. */
|
|
2069
|
+
cornerRadius(r: number): Rectangle;
|
|
2070
|
+
}
|
|
2071
|
+
declare class Square extends ShapeBuilder<Square> {
|
|
2072
|
+
constructor(x: number, y: number, size: number);
|
|
2073
|
+
position(x: number, y: number): Square;
|
|
2074
|
+
size(value: number): Square;
|
|
2075
|
+
/** Set the corner radius for rounded squares. */
|
|
2076
|
+
cornerRadius(r: number): Square;
|
|
2077
|
+
}
|
|
2078
|
+
declare class Line extends ShapeBuilder<Line> {
|
|
2079
|
+
constructor(x1: number, y1: number, x2: number, y2: number);
|
|
2080
|
+
/** Set the start and end points. */
|
|
2081
|
+
from(x: number, y: number): Line;
|
|
2082
|
+
to(x: number, y: number): Line;
|
|
2083
|
+
/** Set the start endpoint marker style. */
|
|
2084
|
+
markerStart(style: EndpointStyle): Line;
|
|
2085
|
+
/** Set the end endpoint marker style. */
|
|
2086
|
+
markerEnd(style: EndpointStyle): Line;
|
|
2087
|
+
/** Convenience: set both markers. */
|
|
2088
|
+
markers(start: EndpointStyle, end: EndpointStyle): Line;
|
|
2089
|
+
}
|
|
2090
|
+
declare class Text extends ShapeBuilder<Text> {
|
|
2091
|
+
constructor(x: number, y: number, text: string);
|
|
2092
|
+
position(x: number, y: number): Text;
|
|
2093
|
+
/** Set the text content. */
|
|
2094
|
+
content(text: string): Text;
|
|
2095
|
+
/** Set the font size. */
|
|
2096
|
+
fontSize(size: number): Text;
|
|
2097
|
+
/** Set the font family. */
|
|
2098
|
+
fontFamily(family: string): Text;
|
|
2099
|
+
/** Set the font weight. */
|
|
2100
|
+
fontWeight(weight: FontWeight): Text;
|
|
2101
|
+
/** Set the font style (italic, normal, etc). */
|
|
2102
|
+
fontStyle(style: FontStyle): Text;
|
|
2103
|
+
/** Set the text anchor (start, middle, end). */
|
|
2104
|
+
anchor(value: 'start' | 'middle' | 'end'): Text;
|
|
2105
|
+
/** Set letter spacing. */
|
|
2106
|
+
letterSpacing(value: number): Text;
|
|
2107
|
+
/** Set line height. */
|
|
2108
|
+
lineHeight(value: number): Text;
|
|
2109
|
+
/** Set text decoration. */
|
|
2110
|
+
decoration(options: {
|
|
2111
|
+
underline?: boolean;
|
|
2112
|
+
strikethrough?: boolean;
|
|
2113
|
+
overline?: boolean;
|
|
2114
|
+
}): Text;
|
|
2115
|
+
/** Set text transform (uppercase, lowercase, capitalize). */
|
|
2116
|
+
transform(value: TextTransform): Text;
|
|
2117
|
+
/**
|
|
2118
|
+
* Place this text along a path defined by cubic-Bézier control points.
|
|
2119
|
+
*
|
|
2120
|
+
* Each point has `{ x, y }` and may include `handleIn` / `handleOut`
|
|
2121
|
+
* for bezier curve handles.
|
|
2122
|
+
*
|
|
2123
|
+
* @param points - Array of path points (at least 2)
|
|
2124
|
+
* @param startOffset - Percentage offset along the path (0–100). Default: 0
|
|
2125
|
+
*/
|
|
2126
|
+
textPath(points: Array<{
|
|
2127
|
+
x: number;
|
|
2128
|
+
y: number;
|
|
2129
|
+
handleIn?: Point;
|
|
2130
|
+
handleOut?: Point;
|
|
2131
|
+
}>, startOffset?: number): Text;
|
|
2132
|
+
/** Set the start offset along the text path (0–100 %). */
|
|
2133
|
+
textPathOffset(percent: number): Text;
|
|
2134
|
+
/** Set the text path side ('left' or 'right'). */
|
|
2135
|
+
textPathSide(side: 'left' | 'right'): Text;
|
|
2136
|
+
/** Set the text direction ('ltr' or 'rtl'). */
|
|
2137
|
+
direction(value: 'ltr' | 'rtl'): Text;
|
|
2138
|
+
/** Set the unicode-bidi mode. */
|
|
2139
|
+
unicodeBidi(value: 'normal' | 'embed' | 'bidi-override' | 'isolate' | 'isolate-override' | 'plaintext'): Text;
|
|
2140
|
+
/** Set the dominant baseline alignment. */
|
|
2141
|
+
dominantBaseline(value: string): Text;
|
|
2142
|
+
/** Set the writing mode. */
|
|
2143
|
+
writingMode(value: 'horizontal-tb' | 'vertical-rl' | 'vertical-lr'): Text;
|
|
2144
|
+
/** Set the word spacing. */
|
|
2145
|
+
wordSpacing(value: number): Text;
|
|
2146
|
+
/** Set the baseline shift. */
|
|
2147
|
+
baselineShift(value: string): Text;
|
|
2148
|
+
/** Set the inline size for text wrapping. */
|
|
2149
|
+
inlineSize(value: number): Text;
|
|
2150
|
+
/** Set the overflow wrap behavior. */
|
|
2151
|
+
overflowWrap(value: 'normal' | 'break-word' | 'anywhere'): Text;
|
|
2152
|
+
/** Set the white-space handling. */
|
|
2153
|
+
whiteSpace(value: 'normal' | 'nowrap' | 'pre' | 'pre-wrap' | 'pre-line' | 'break-spaces'): Text;
|
|
2154
|
+
/** Set variable font axis settings. */
|
|
2155
|
+
fontVariationSettings(settings: Record<string, number>): Text;
|
|
2156
|
+
/** Set per-character positional offsets (dx, dy, rotate). */
|
|
2157
|
+
charOffsets(offsets: {
|
|
2158
|
+
x: number;
|
|
2159
|
+
y: number;
|
|
2160
|
+
rotate: number;
|
|
2161
|
+
}[]): Text;
|
|
2162
|
+
/** Set the shape-inside reference for text wrapping inside a shape. */
|
|
2163
|
+
shapeInsideRef(ref: string): Text;
|
|
2164
|
+
/** Set padding for shape-inside text wrapping. */
|
|
2165
|
+
shapePadding(value: number): Text;
|
|
2166
|
+
/** Set rich text data for per-segment styling. */
|
|
2167
|
+
richTextData(data: RichTextData): Text;
|
|
2168
|
+
}
|
|
2169
|
+
declare abstract class PolygonShapeBuilder<T extends PolygonShapeBuilder<T>> extends ShapeBuilder<T> {
|
|
2170
|
+
constructor(type: SerializedShape['type'], cx: number, cy: number, radius: number);
|
|
2171
|
+
position(cx: number, cy: number): T;
|
|
2172
|
+
radius(r: number): T;
|
|
2173
|
+
/** Rotate the shape's geometry (not the SVG transform). */
|
|
2174
|
+
shiftAngle(degrees: number): T;
|
|
2175
|
+
/** Round the polygon corners. */
|
|
2176
|
+
cornerRadius(r: number): T;
|
|
2177
|
+
}
|
|
2178
|
+
declare class Triangle extends PolygonShapeBuilder<Triangle> {
|
|
2179
|
+
constructor(cx: number, cy: number, radius: number);
|
|
2180
|
+
}
|
|
2181
|
+
declare class NGon extends PolygonShapeBuilder<NGon> {
|
|
2182
|
+
constructor(cx: number, cy: number, radius: number, sides?: number);
|
|
2183
|
+
/** Set the number of sides. */
|
|
2184
|
+
sides(n: number): NGon;
|
|
2185
|
+
}
|
|
2186
|
+
declare class Star extends PolygonShapeBuilder<Star> {
|
|
2187
|
+
constructor(cx: number, cy: number, radius: number);
|
|
2188
|
+
/** Set the number of star arms/points. */
|
|
2189
|
+
arms(n: number): Star;
|
|
2190
|
+
/** Set the inner radius as a percent of the outer radius (0–100). */
|
|
2191
|
+
innerRadius(percent: number): Star;
|
|
2192
|
+
}
|
|
2193
|
+
declare class Cross extends PolygonShapeBuilder<Cross> {
|
|
2194
|
+
constructor(cx: number, cy: number, radius: number);
|
|
2195
|
+
/** Set the arm width as a percent of the total width (0–100). */
|
|
2196
|
+
armWidth(percent: number): Cross;
|
|
2197
|
+
}
|
|
2198
|
+
declare class Ring extends PolygonShapeBuilder<Ring> {
|
|
2199
|
+
constructor(cx: number, cy: number, radius: number);
|
|
2200
|
+
/** Set the inner radius (hole size) as a percent (0–100). */
|
|
2201
|
+
innerRadius(percent: number): Ring;
|
|
2202
|
+
}
|
|
2203
|
+
declare class Spiral extends PolygonShapeBuilder<Spiral> {
|
|
2204
|
+
constructor(cx: number, cy: number, radius: number);
|
|
2205
|
+
/** Set the number of turns. */
|
|
2206
|
+
turns(n: number): Spiral;
|
|
2207
|
+
/** Set the stroke thickness as a percent (0–100). */
|
|
2208
|
+
thickness(percent: number): Spiral;
|
|
2209
|
+
/** Set the spiral direction: 1 = clockwise, -1 = counter-clockwise. */
|
|
2210
|
+
direction(d: 1 | -1): Spiral;
|
|
2211
|
+
}
|
|
2212
|
+
declare class Gear extends PolygonShapeBuilder<Gear> {
|
|
2213
|
+
constructor(cx: number, cy: number, radius: number);
|
|
2214
|
+
/** Set the number of teeth. */
|
|
2215
|
+
teeth(n: number): Gear;
|
|
2216
|
+
/** Set the tooth depth as a percent (0–100). */
|
|
2217
|
+
toothDepth(percent: number): Gear;
|
|
2218
|
+
/** Set the center hole size as a percent (0–100). 0 = no hole. */
|
|
2219
|
+
holeRadius(percent: number): Gear;
|
|
2220
|
+
}
|
|
2221
|
+
declare class Arrow extends PolygonShapeBuilder<Arrow> {
|
|
2222
|
+
constructor(cx: number, cy: number, radius: number);
|
|
2223
|
+
/** Set the arrow head width as a percent (0–100). */
|
|
2224
|
+
headWidth(percent: number): Arrow;
|
|
2225
|
+
/** Set the arrow head length as a percent (0–100). */
|
|
2226
|
+
headLength(percent: number): Arrow;
|
|
2227
|
+
/** Set the arrow shaft width as a percent (0–100). */
|
|
2228
|
+
shaftWidth(percent: number): Arrow;
|
|
2229
|
+
}
|
|
2230
|
+
declare class Spline extends ShapeBuilder<Spline> {
|
|
2231
|
+
constructor(points?: (Point | SplinePoint)[]);
|
|
2232
|
+
/** Set the spline points. */
|
|
2233
|
+
points(pts: (Point | SplinePoint)[]): Spline;
|
|
2234
|
+
/** Add a point to the spline. */
|
|
2235
|
+
addPoint(x: number, y: number): Spline;
|
|
2236
|
+
/** Set the curve type. */
|
|
2237
|
+
curveType(type: SplineCurveType): Spline;
|
|
2238
|
+
/** Set whether the spline is closed. */
|
|
2239
|
+
closed(value?: boolean): Spline;
|
|
2240
|
+
/** Set the tension for Catmull-Rom curves (0–1). */
|
|
2241
|
+
tension(value: number): Spline;
|
|
2242
|
+
/** Set arc params for ARC curve type. */
|
|
2243
|
+
arcParams(params: ArcParams$1[]): Spline;
|
|
2244
|
+
/** Set the start endpoint marker. */
|
|
2245
|
+
markerStart(style: EndpointStyle): Spline;
|
|
2246
|
+
/** Set the end endpoint marker. */
|
|
2247
|
+
markerEnd(style: EndpointStyle): Spline;
|
|
2248
|
+
/** Convenience: set both markers. */
|
|
2249
|
+
markers(start: EndpointStyle, end: EndpointStyle): Spline;
|
|
2250
|
+
}
|
|
2251
|
+
declare class Polyline extends ShapeBuilder<Polyline> {
|
|
2252
|
+
constructor(points?: Point[]);
|
|
2253
|
+
/** Set the polyline points. */
|
|
2254
|
+
points(pts: Point[]): Polyline;
|
|
2255
|
+
/** Add a point. */
|
|
2256
|
+
addPoint(x: number, y: number): Polyline;
|
|
2257
|
+
/** Set whether the polyline is closed (becomes a polygon). */
|
|
2258
|
+
closed(value?: boolean): Polyline;
|
|
2259
|
+
/** Set the start endpoint marker. */
|
|
2260
|
+
markerStart(style: EndpointStyle): Polyline;
|
|
2261
|
+
/** Set the end endpoint marker. */
|
|
2262
|
+
markerEnd(style: EndpointStyle): Polyline;
|
|
2263
|
+
/** Convenience: set both markers. */
|
|
2264
|
+
markers(start: EndpointStyle, end: EndpointStyle): Polyline;
|
|
2265
|
+
}
|
|
2266
|
+
declare class ImageShape extends ShapeBuilder<ImageShape> {
|
|
2267
|
+
constructor(x: number, y: number, width: number, height: number, href: string);
|
|
2268
|
+
position(x: number, y: number): ImageShape;
|
|
2269
|
+
size(width: number, height: number): ImageShape;
|
|
2270
|
+
/** Set the image source URL or data URI. */
|
|
2271
|
+
src(href: string): ImageShape;
|
|
2272
|
+
/** Toggle preserveAspectRatio. */
|
|
2273
|
+
preserveAspectRatio(value: boolean): ImageShape;
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2276
|
+
/**
|
|
2277
|
+
* Animation SDK — Fluent builder API for creating animation timelines.
|
|
2278
|
+
*
|
|
2279
|
+
* Provides `Keyframe`, `Track`, and `Timeline` builder classes that
|
|
2280
|
+
* produce `SerializedAnimationTimeline` data for persistence and
|
|
2281
|
+
* SMIL SVG rendering.
|
|
2282
|
+
*
|
|
2283
|
+
* @example
|
|
2284
|
+
* ```ts
|
|
2285
|
+
* import { Document, Circle, Timeline, Track, EasingType } from '@svgsketch/core';
|
|
2286
|
+
*
|
|
2287
|
+
* const doc = new Document({ width: 400, height: 400 });
|
|
2288
|
+
* const circle = new Circle(100, 200, 50).fill('#3498db').id('ball');
|
|
2289
|
+
* doc.add(circle);
|
|
2290
|
+
*
|
|
2291
|
+
* doc.setTimeline(
|
|
2292
|
+
* new Timeline(3)
|
|
2293
|
+
* .loop()
|
|
2294
|
+
* .addTrack(
|
|
2295
|
+
* new Track('ball', 'cx')
|
|
2296
|
+
* .keyframe(0, 100, EasingType.EASE_IN_OUT)
|
|
2297
|
+
* .keyframe(1.5, 300, EasingType.EASE_OUT)
|
|
2298
|
+
* .keyframe(3, 100)
|
|
2299
|
+
* )
|
|
2300
|
+
* );
|
|
2301
|
+
*
|
|
2302
|
+
* const svg = doc.toSVG(); // includes SMIL <animate> elements
|
|
2303
|
+
* ```
|
|
2304
|
+
*/
|
|
2305
|
+
|
|
2306
|
+
/**
|
|
2307
|
+
* Fluent builder for an animation track.
|
|
2308
|
+
*
|
|
2309
|
+
* A track animates a single property of a single shape over time.
|
|
2310
|
+
*/
|
|
2311
|
+
declare class Track {
|
|
2312
|
+
private _track;
|
|
2313
|
+
/**
|
|
2314
|
+
* @param shapeId - The ID of the shape to animate.
|
|
2315
|
+
* @param property - The property to animate (e.g. 'cx', 'opacity', 'rotation', 'fillColor', 'pathMotion').
|
|
2316
|
+
*/
|
|
2317
|
+
constructor(shapeId: string, property: string);
|
|
2318
|
+
/** Override the auto-generated track ID. */
|
|
2319
|
+
id(value: string): Track;
|
|
2320
|
+
/**
|
|
2321
|
+
* Add a keyframe at the given time.
|
|
2322
|
+
*
|
|
2323
|
+
* @param time - Time in seconds from the start of the track.
|
|
2324
|
+
* @param value - The property value at this time (number or color string).
|
|
2325
|
+
* @param easing - Easing curve leading *into* this keyframe.
|
|
2326
|
+
* Defaults to LINEAR.
|
|
2327
|
+
*/
|
|
2328
|
+
keyframe(time: number, value: number | string, easing?: EasingType): Track;
|
|
2329
|
+
/** Add multiple keyframes at once. */
|
|
2330
|
+
keyframes(...kfs: AnimationKeyframe[]): Track;
|
|
2331
|
+
/** Disable this track (excluded from playback/export). */
|
|
2332
|
+
disabled(): Track;
|
|
2333
|
+
/** Lock this track from editing. */
|
|
2334
|
+
locked(): Track;
|
|
2335
|
+
/** Set an SVG path for motion-path animation. */
|
|
2336
|
+
motionPath(path: string): Track;
|
|
2337
|
+
/**
|
|
2338
|
+
* Set the begin trigger for this track.
|
|
2339
|
+
*
|
|
2340
|
+
* @example
|
|
2341
|
+
* ```ts
|
|
2342
|
+
* track.beginTrigger('event', 'click') // start on click
|
|
2343
|
+
* track.beginTrigger('time', '2') // start at 2 seconds
|
|
2344
|
+
* ```
|
|
2345
|
+
*/
|
|
2346
|
+
beginTrigger(type: AnimationTrigger['type'], value: string): Track;
|
|
2347
|
+
/** Set the end trigger for this track. */
|
|
2348
|
+
endTrigger(type: AnimationTrigger['type'], value: string): Track;
|
|
2349
|
+
/** Set the cycle duration in seconds. */
|
|
2350
|
+
cycleDuration(seconds: number): Track;
|
|
2351
|
+
/** Set how many times the track repeats. */
|
|
2352
|
+
cycleRepeats(count: number): Track;
|
|
2353
|
+
/** Repeat the track indefinitely. */
|
|
2354
|
+
infinite(): Track;
|
|
2355
|
+
/** Set the cycle behavior (restart or alternate). */
|
|
2356
|
+
cycle(behavior: CycleBehavior): Track;
|
|
2357
|
+
/**
|
|
2358
|
+
* Set the center point for transform animations (rotation, skew).
|
|
2359
|
+
*
|
|
2360
|
+
* For rotation this determines the point the shape orbits around.
|
|
2361
|
+
* In SMIL the values are emitted as `"angle cx cy"` format.
|
|
2362
|
+
*
|
|
2363
|
+
* @param x - X coordinate of the rotation center.
|
|
2364
|
+
* @param y - Y coordinate of the rotation center.
|
|
2365
|
+
*/
|
|
2366
|
+
transformOrigin(x: number, y: number): Track;
|
|
2367
|
+
/**
|
|
2368
|
+
* Set rotation behavior for motion-path animation.
|
|
2369
|
+
*
|
|
2370
|
+
* @param value - `'auto'` to follow path direction, `'auto-reverse'` for reversed,
|
|
2371
|
+
* or a fixed angle in degrees.
|
|
2372
|
+
*/
|
|
2373
|
+
motionRotate(value: 'auto' | 'auto-reverse' | number): Track;
|
|
2374
|
+
/**
|
|
2375
|
+
* Set whether this track's values add to or replace the base value.
|
|
2376
|
+
*
|
|
2377
|
+
* @param value - `'sum'` to add to base, `'replace'` to override.
|
|
2378
|
+
*/
|
|
2379
|
+
additive(value: 'sum' | 'replace'): Track;
|
|
2380
|
+
/** Build the raw AnimationTrack data. */
|
|
2381
|
+
build(): AnimationTrack;
|
|
2382
|
+
}
|
|
2383
|
+
/**
|
|
2384
|
+
* Fluent builder for an animation timeline.
|
|
2385
|
+
*
|
|
2386
|
+
* A timeline aggregates multiple tracks and defines global playback options.
|
|
2387
|
+
*/
|
|
2388
|
+
declare class Timeline {
|
|
2389
|
+
private _duration;
|
|
2390
|
+
private _loop;
|
|
2391
|
+
private _playbackSpeed;
|
|
2392
|
+
private _tracks;
|
|
2393
|
+
/**
|
|
2394
|
+
* @param duration - Total timeline duration in seconds.
|
|
2395
|
+
*/
|
|
2396
|
+
constructor(duration: number);
|
|
2397
|
+
/** Enable looping. */
|
|
2398
|
+
loop(value?: boolean): Timeline;
|
|
2399
|
+
/** Set the playback speed multiplier (e.g. 0.5 = half speed, 2 = double). */
|
|
2400
|
+
speed(value: number): Timeline;
|
|
2401
|
+
/** Set the timeline duration in seconds. */
|
|
2402
|
+
duration(value: number): Timeline;
|
|
2403
|
+
/** Add a track to the timeline. */
|
|
2404
|
+
addTrack(track: Track): Timeline;
|
|
2405
|
+
/** Add multiple tracks at once. */
|
|
2406
|
+
addTracks(...tracks: Track[]): Timeline;
|
|
2407
|
+
/**
|
|
2408
|
+
* Build the AnimationTimeline data used by the runtime.
|
|
2409
|
+
*/
|
|
2410
|
+
buildTimeline(): AnimationTimeline;
|
|
2411
|
+
/**
|
|
2412
|
+
* Build the serialized form suitable for persistence in .svgs files.
|
|
2413
|
+
*/
|
|
2414
|
+
build(): SerializedAnimationTimeline;
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
/**
|
|
2418
|
+
* Document builder — fluent API for assembling SVGSketch documents.
|
|
2419
|
+
*
|
|
2420
|
+
* Wraps `createDocument`, `createViewbox`, `stringifyDocument`,
|
|
2421
|
+
* `parseDocument`, and `renderToSvg` into a single ergonomic class.
|
|
2422
|
+
*
|
|
2423
|
+
* @example
|
|
2424
|
+
* ```ts
|
|
2425
|
+
* import { Document, Circle, Rectangle } from '@svgsketch/core';
|
|
2426
|
+
*
|
|
2427
|
+
* const doc = new Document({ width: 800, height: 600 })
|
|
2428
|
+
* .title('My Drawing')
|
|
2429
|
+
* .add(new Circle(100, 200, 50).fill('#3498db'))
|
|
2430
|
+
* .add(new Rectangle(10, 20, 200, 100).fill('#e74c3c'));
|
|
2431
|
+
*
|
|
2432
|
+
* const svg = doc.toSVG();
|
|
2433
|
+
* const json = doc.toJSON();
|
|
2434
|
+
* ```
|
|
2435
|
+
*/
|
|
2436
|
+
|
|
2437
|
+
/** Options accepted by the Document constructor. */
|
|
2438
|
+
interface DocumentOptions {
|
|
2439
|
+
/** Canvas width. Default: 800 */
|
|
2440
|
+
width?: number;
|
|
2441
|
+
/** Canvas height. Default: 600 */
|
|
2442
|
+
height?: number;
|
|
2443
|
+
/** Viewbox ID. Auto-generated if omitted. */
|
|
2444
|
+
viewboxId?: string;
|
|
2445
|
+
}
|
|
2446
|
+
declare class Document {
|
|
2447
|
+
private _snapshot;
|
|
2448
|
+
constructor(options?: DocumentOptions);
|
|
2449
|
+
/**
|
|
2450
|
+
* Create a Document from an existing HistorySnapshot.
|
|
2451
|
+
*/
|
|
2452
|
+
static fromSnapshot(snapshot: HistorySnapshot): Document;
|
|
2453
|
+
/**
|
|
2454
|
+
* Parse a `.svgs` JSON string into a Document.
|
|
2455
|
+
*
|
|
2456
|
+
* @param json - The JSON string (content of a .svgs file)
|
|
2457
|
+
* @param options - Parse options (validate, migrate)
|
|
2458
|
+
*/
|
|
2459
|
+
static fromJSON(json: string, options?: ParseOptions): Document;
|
|
2460
|
+
/**
|
|
2461
|
+
* Add a shape (builder or raw SerializedShape).
|
|
2462
|
+
* Returns `this` for chaining.
|
|
2463
|
+
*/
|
|
2464
|
+
add(shape: ShapeBuilder<any> | SerializedShape): Document;
|
|
2465
|
+
/**
|
|
2466
|
+
* Add multiple shapes at once.
|
|
2467
|
+
* Returns `this` for chaining.
|
|
2468
|
+
*/
|
|
2469
|
+
addAll(...shapes: (ShapeBuilder<any> | SerializedShape)[]): Document;
|
|
2470
|
+
/**
|
|
2471
|
+
* Remove a shape by ID.
|
|
2472
|
+
* @returns `true` if a shape was removed, `false` if no shape matched the ID.
|
|
2473
|
+
*/
|
|
2474
|
+
remove(id: string): boolean;
|
|
2475
|
+
/**
|
|
2476
|
+
* Get all shapes in the document.
|
|
2477
|
+
*/
|
|
2478
|
+
get shapes(): readonly SerializedShape[];
|
|
2479
|
+
/**
|
|
2480
|
+
* Find a shape by ID.
|
|
2481
|
+
*/
|
|
2482
|
+
findShape(id: string): SerializedShape | undefined;
|
|
2483
|
+
/**
|
|
2484
|
+
* Set the canvas size.
|
|
2485
|
+
*/
|
|
2486
|
+
size(width: number, height: number): Document;
|
|
2487
|
+
/**
|
|
2488
|
+
* Get the canvas width.
|
|
2489
|
+
*/
|
|
2490
|
+
get width(): number;
|
|
2491
|
+
/**
|
|
2492
|
+
* Get the canvas height.
|
|
2493
|
+
*/
|
|
2494
|
+
get height(): number;
|
|
2495
|
+
/** Set the document title. */
|
|
2496
|
+
title(value: string): Document;
|
|
2497
|
+
/** Set the document description. */
|
|
2498
|
+
description(value: string): Document;
|
|
2499
|
+
/** Set the document author. */
|
|
2500
|
+
author(value: string): Document;
|
|
2501
|
+
/** Set document keywords. */
|
|
2502
|
+
keywords(...kws: string[]): Document;
|
|
2503
|
+
/** Set the document license. */
|
|
2504
|
+
license(name: LicenseType, url?: string): Document;
|
|
2505
|
+
/** Set the document language (e.g., 'en', 'fr'). */
|
|
2506
|
+
language(lang: string): Document;
|
|
2507
|
+
/** Set or merge custom metadata. */
|
|
2508
|
+
customMetadata(data: Record<string, string>): Document;
|
|
2509
|
+
/** Get the full metadata. */
|
|
2510
|
+
get meta(): DocumentMetadata | undefined;
|
|
2511
|
+
/**
|
|
2512
|
+
* Define a reusable symbol from a set of shapes.
|
|
2513
|
+
*
|
|
2514
|
+
* @param name - Human-readable name for the symbol.
|
|
2515
|
+
* @param shapes - The shapes that make up the symbol content.
|
|
2516
|
+
* @param options - Optional viewBox, thumbnail, and groups.
|
|
2517
|
+
* @returns The symbol definition ID.
|
|
2518
|
+
*/
|
|
2519
|
+
defineSymbol(name: string, shapes: (ShapeBuilder<any> | SerializedShape)[], options?: {
|
|
2520
|
+
viewBox?: string;
|
|
2521
|
+
thumbnail?: string;
|
|
2522
|
+
groups?: SerializedGroup[];
|
|
2523
|
+
}): string;
|
|
2524
|
+
/**
|
|
2525
|
+
* Place a symbol instance on the canvas.
|
|
2526
|
+
*
|
|
2527
|
+
* @param symbolId - The ID of the symbol definition.
|
|
2528
|
+
* @param x - X position.
|
|
2529
|
+
* @param y - Y position.
|
|
2530
|
+
* @param width - Instance width (optional).
|
|
2531
|
+
* @param height - Instance height (optional).
|
|
2532
|
+
*/
|
|
2533
|
+
placeSymbolInstance(symbolId: string, x: number, y: number, width?: number, height?: number): Document;
|
|
2534
|
+
/** Remove a symbol definition by ID. */
|
|
2535
|
+
removeSymbol(id: string): boolean;
|
|
2536
|
+
/** Get all symbol definitions. */
|
|
2537
|
+
get symbols(): readonly SerializedSymbolDef[];
|
|
2538
|
+
/**
|
|
2539
|
+
* Add a clip group.
|
|
2540
|
+
*
|
|
2541
|
+
* @param clipShapeIds - IDs of shapes forming the clip definition.
|
|
2542
|
+
* @param contentShapeIds - IDs of shapes to be clipped.
|
|
2543
|
+
* @param options - Optional clip-path spec attributes.
|
|
2544
|
+
* @returns The clip group ID.
|
|
2545
|
+
*/
|
|
2546
|
+
addClipGroup(clipShapeIds: string[], contentShapeIds: string[], options?: {
|
|
2547
|
+
clipPathUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
|
|
2548
|
+
rawDefinition?: string;
|
|
2549
|
+
}): string;
|
|
2550
|
+
/**
|
|
2551
|
+
* Add a mask group.
|
|
2552
|
+
*
|
|
2553
|
+
* @param maskShapeIds - IDs of shapes forming the mask definition.
|
|
2554
|
+
* @param contentShapeIds - IDs of shapes to be masked.
|
|
2555
|
+
* @param options - Optional mask spec attributes.
|
|
2556
|
+
* @returns The mask group ID.
|
|
2557
|
+
*/
|
|
2558
|
+
addMaskGroup(maskShapeIds: string[], contentShapeIds: string[], options?: {
|
|
2559
|
+
maskUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
|
|
2560
|
+
maskContentUnits?: 'userSpaceOnUse' | 'objectBoundingBox';
|
|
2561
|
+
maskBounds?: {
|
|
2562
|
+
x: string;
|
|
2563
|
+
y: string;
|
|
2564
|
+
width: string;
|
|
2565
|
+
height: string;
|
|
2566
|
+
};
|
|
2567
|
+
maskType?: 'luminance' | 'alpha';
|
|
2568
|
+
rawDefinition?: string;
|
|
2569
|
+
}): string;
|
|
2570
|
+
/** Remove a clip or mask group by ID. */
|
|
2571
|
+
removeClipMaskGroup(id: string): boolean;
|
|
2572
|
+
/**
|
|
2573
|
+
* Add a guide line.
|
|
2574
|
+
*
|
|
2575
|
+
* @param orientation - 'horizontal' or 'vertical'.
|
|
2576
|
+
* @param position - Position in canvas coordinates.
|
|
2577
|
+
* @param options - Optional color and opacity.
|
|
2578
|
+
* @returns The guide ID.
|
|
2579
|
+
*/
|
|
2580
|
+
addGuide(orientation: 'horizontal' | 'vertical', position: number, options?: {
|
|
2581
|
+
color?: string;
|
|
2582
|
+
opacity?: number;
|
|
2583
|
+
}): string;
|
|
2584
|
+
/** Remove a guide by ID. */
|
|
2585
|
+
removeGuide(id: string): boolean;
|
|
2586
|
+
/** Remove all guides. */
|
|
2587
|
+
clearGuides(): Document;
|
|
2588
|
+
/** Get all guides. */
|
|
2589
|
+
get guides(): readonly Guide[];
|
|
2590
|
+
/**
|
|
2591
|
+
* Add a measurement annotation.
|
|
2592
|
+
*
|
|
2593
|
+
* @param type - 'distance' (2 points) or 'angle' (3 points).
|
|
2594
|
+
* @param points - The measurement points.
|
|
2595
|
+
* @param options - Optional visibility, snap divisions, color, opacity.
|
|
2596
|
+
* @returns The measurement ID.
|
|
2597
|
+
*/
|
|
2598
|
+
addMeasurement(type: 'distance' | 'angle', points: Point[], options?: {
|
|
2599
|
+
visible?: boolean;
|
|
2600
|
+
snapDivisions?: number;
|
|
2601
|
+
color?: string;
|
|
2602
|
+
opacity?: number;
|
|
2603
|
+
}): string;
|
|
2604
|
+
/** Remove a measurement by ID. */
|
|
2605
|
+
removeMeasurement(id: string): boolean;
|
|
2606
|
+
/** Get all measurements. */
|
|
2607
|
+
get measurements(): readonly Measurement[];
|
|
2608
|
+
/**
|
|
2609
|
+
* Add a custom pattern definition to the document library.
|
|
2610
|
+
*
|
|
2611
|
+
* @param name - Display name for the pattern.
|
|
2612
|
+
* @param svgContent - Inner SVG markup for the pattern tile.
|
|
2613
|
+
* @param width - Tile width.
|
|
2614
|
+
* @param height - Tile height.
|
|
2615
|
+
* @returns The custom pattern ID.
|
|
2616
|
+
*/
|
|
2617
|
+
addCustomPattern(name: string, svgContent: string, width: number, height: number): string;
|
|
2618
|
+
/** Remove a custom pattern definition by ID. */
|
|
2619
|
+
removeCustomPattern(id: string): boolean;
|
|
2620
|
+
/** Get all custom pattern definitions. */
|
|
2621
|
+
get customPatterns(): readonly CustomPatternDef[];
|
|
2622
|
+
/**
|
|
2623
|
+
* Add a group definition.
|
|
2624
|
+
*
|
|
2625
|
+
* @param groupId - Optional custom group ID.
|
|
2626
|
+
* @param parentGroupId - Optional parent group ID for nesting.
|
|
2627
|
+
* @returns The group ID.
|
|
2628
|
+
*/
|
|
2629
|
+
addGroup(groupId?: string, parentGroupId?: string): string;
|
|
2630
|
+
/** Remove a group definition. Shapes in the group become ungrouped. */
|
|
2631
|
+
removeGroup(groupId: string): boolean;
|
|
2632
|
+
/** Move a shape into a group. */
|
|
2633
|
+
moveToGroup(shapeId: string, groupId: string): Document;
|
|
2634
|
+
/** Remove a shape from its group. */
|
|
2635
|
+
removeFromGroup(shapeId: string): Document;
|
|
2636
|
+
/** Move a shape to the front of the shapes array (top of z-order). */
|
|
2637
|
+
bringToFront(shapeId: string): Document;
|
|
2638
|
+
/** Move a shape to the back of the shapes array (bottom of z-order). */
|
|
2639
|
+
sendToBack(shapeId: string): Document;
|
|
2640
|
+
/** Move a shape to a specific position in the z-order. */
|
|
2641
|
+
reorder(shapeId: string, position: number): Document;
|
|
2642
|
+
/**
|
|
2643
|
+
* Define a template variable with a default value.
|
|
2644
|
+
*
|
|
2645
|
+
* Variables can be referenced in shape properties as `{{name}}` and
|
|
2646
|
+
* will be substituted at render time.
|
|
2647
|
+
*
|
|
2648
|
+
* @example
|
|
2649
|
+
* ```ts
|
|
2650
|
+
* const doc = new Document()
|
|
2651
|
+
* .defineVariable('primaryColor', 'color', '#3498db', { label: 'Primary Color' })
|
|
2652
|
+
* .defineVariable('title', 'string', 'Hello World')
|
|
2653
|
+
* .defineVariable('radius', 'number', '50')
|
|
2654
|
+
* .add(new Circle(100, 100, '{{radius}}').fill('{{primaryColor}}'));
|
|
2655
|
+
*
|
|
2656
|
+
* // Render with defaults
|
|
2657
|
+
* const svg1 = doc.toSVG();
|
|
2658
|
+
*
|
|
2659
|
+
* // Render with overrides
|
|
2660
|
+
* const svg2 = doc.toSVG({ variables: { primaryColor: '#e74c3c', radius: '80' } });
|
|
2661
|
+
* ```
|
|
2662
|
+
*/
|
|
2663
|
+
defineVariable(name: string, type: TemplateVariableType, defaultValue: string, options?: {
|
|
2664
|
+
label?: string;
|
|
2665
|
+
description?: string;
|
|
2666
|
+
}): Document;
|
|
2667
|
+
/**
|
|
2668
|
+
* Remove a template variable definition.
|
|
2669
|
+
*/
|
|
2670
|
+
removeVariable(name: string): Document;
|
|
2671
|
+
/**
|
|
2672
|
+
* Get all defined template variables.
|
|
2673
|
+
*/
|
|
2674
|
+
get variables(): readonly TemplateVariable[];
|
|
2675
|
+
/**
|
|
2676
|
+
* Discover all `{{var}}` references in the document,
|
|
2677
|
+
* including any that aren't formally defined.
|
|
2678
|
+
*/
|
|
2679
|
+
inspectVariables(): {
|
|
2680
|
+
defined: TemplateVariable[];
|
|
2681
|
+
undeclared: string[];
|
|
2682
|
+
};
|
|
2683
|
+
/**
|
|
2684
|
+
* Set the animation timeline for the document.
|
|
2685
|
+
*
|
|
2686
|
+
* Accepts a `Timeline` builder or raw `SerializedAnimationTimeline` data.
|
|
2687
|
+
* When the document is rendered with `.toSVG()`, SMIL animation
|
|
2688
|
+
* elements (`<animate>`, `<animateTransform>`, `<animateMotion>`)
|
|
2689
|
+
* are automatically injected into the output.
|
|
2690
|
+
*
|
|
2691
|
+
* @example
|
|
2692
|
+
* ```ts
|
|
2693
|
+
* doc.setTimeline(
|
|
2694
|
+
* new Timeline(3)
|
|
2695
|
+
* .loop()
|
|
2696
|
+
* .addTrack(new Track('circle-1', 'cx').keyframe(0, 50).keyframe(3, 350))
|
|
2697
|
+
* );
|
|
2698
|
+
* ```
|
|
2699
|
+
*/
|
|
2700
|
+
setTimeline(timeline: Timeline | SerializedAnimationTimeline): Document;
|
|
2701
|
+
/**
|
|
2702
|
+
* Remove the animation timeline from the document.
|
|
2703
|
+
*/
|
|
2704
|
+
clearTimeline(): Document;
|
|
2705
|
+
/**
|
|
2706
|
+
* Get the animation timeline, if one is set.
|
|
2707
|
+
*/
|
|
2708
|
+
get timeline(): SerializedAnimationTimeline | undefined;
|
|
2709
|
+
/**
|
|
2710
|
+
* Render the document to an SVG string.
|
|
2711
|
+
*
|
|
2712
|
+
* If the document contains template variables, they are substituted
|
|
2713
|
+
* before rendering using defaults or the provided overrides.
|
|
2714
|
+
*
|
|
2715
|
+
* @param options - Render options (width, height, viewBox, variables, etc.)
|
|
2716
|
+
*/
|
|
2717
|
+
toSVG(options?: RenderOptions & {
|
|
2718
|
+
variables?: VariableMap;
|
|
2719
|
+
}): string;
|
|
2720
|
+
/**
|
|
2721
|
+
* Serialize the document to a `.svgs` JSON string.
|
|
2722
|
+
*
|
|
2723
|
+
* Template variable placeholders are preserved (not substituted).
|
|
2724
|
+
*
|
|
2725
|
+
* @param options - Stringify options (indent, validate, etc.)
|
|
2726
|
+
*/
|
|
2727
|
+
toJSON(options?: StringifyOptions): string;
|
|
2728
|
+
/**
|
|
2729
|
+
* Get the raw HistorySnapshot (a deep copy).
|
|
2730
|
+
*/
|
|
2731
|
+
toSnapshot(): HistorySnapshot;
|
|
2732
|
+
/**
|
|
2733
|
+
* Generate code from the document in the specified format.
|
|
2734
|
+
*
|
|
2735
|
+
* Supported formats:
|
|
2736
|
+
* - `'svg'` — Raw SVG markup
|
|
2737
|
+
* - `'react'` — React functional component (JSX)
|
|
2738
|
+
* - `'vue'` — Vue Single File Component (SFC)
|
|
2739
|
+
* - `'d3'` — D3.js code using selections
|
|
2740
|
+
* - `'css'` — CSS classes + SVG markup
|
|
2741
|
+
*
|
|
2742
|
+
* @param format - Target code format
|
|
2743
|
+
* @param options - Additional code generation options
|
|
2744
|
+
*
|
|
2745
|
+
* @example
|
|
2746
|
+
* ```ts
|
|
2747
|
+
* const reactCode = doc.toCode('react', { componentName: 'MyIcon' });
|
|
2748
|
+
* const vueCode = doc.toCode('vue', { typescript: true });
|
|
2749
|
+
* const d3Code = doc.toCode('d3', { componentName: 'buildChart' });
|
|
2750
|
+
* ```
|
|
2751
|
+
*/
|
|
2752
|
+
toCode(format: CodeFormat, options?: Omit<CodegenOptions, 'format'>): string;
|
|
2753
|
+
private _ensureMetadata;
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2756
|
+
export { type AnimatablePropertyDescriptor, type AnimationKeyframe, type AnimationTimeline, type AnimationTrack, type AnimationTrigger, type AnimationTriggerType, type ArcParams$1 as ArcParams, type AriaRole, Arrow, type BaseFilter, type BlackAndWhiteFilter, type BlurQuality, type BrightnessFilter, CURRENT_SCHEMA_VERSION, type ChannelPainterFilter, Circle, type CodeFormat, type CodegenOptions, type ContouringDiscreteFilter, type ContouringTableFilter, type ContrastFilter, type CreateDocumentOptions, type CreateShapeOptions, Cross, type CrumpledPlasticFilter, type CustomPatternDef, type CycleBehavior, Document, type DocumentMetadata, type DocumentOptions, type DropShadowFilter, type DuotoneFilter, EASING_CURVES, EVENT_TRIGGER_OPTIONS, EasingType, Ellipse, type EmbossFilter, type ExtractedVariables, type FillType, type FilmGrainFilter, type FilterType, type GaussianBlurFilter, Gear, type GlowFilter, type GouacheFilter, type GradientDefinition, type GradientSpreadMethod, type GradientStop, type GrayscaleFilter, type Guide, type HistorySnapshot, type HueRotateFilter, ImageShape, type InkBlotFilter, type InnerGlowFilter, type InnerShadowFilter, type InvertFilter, type LicenseType, Line, type LinearGradient, LinearGradientBuilder, type LinkTarget, MARKER_HEIGHT, MARKER_VIEWBOX, MARKER_WIDTH, type MarkerDescriptor, type Measurement, type MorphologyFilter, type MorphologyOperator, type MotionBlurFilter, NGon, type NoiseFilter, type OpacityFilter, type OutlineFilter, type OutlinePosition, type ParseOptions, PatternBuilder, type PatternElement, type PatternFill, type PatternParams, type PatternSvgContentResult, type PatternType, type PixelateFilter, type Point, type PointLightFilter, Polyline, type RadialGradient, RadialGradientBuilder, Rectangle, type RenderOptions, type RichTextData, type RichTextLine, type RichTextSegment, type RichTextSegmentStyle, type RiddledFilter, Ring, type RoundEdgesFilter, type SaturateFilter, type SegmentCurveType, type SepiaFilter, type SerializedAnimationTimeline, type SerializedClipMaskGroup, type SerializedGroup, type SerializedShape, type SerializedSymbolDef, type SerializedViewbox, ShapeBuilder, type ShapeFilter, type ShapeMetadata, type SharpenFilter, Spiral, Spline, SplineCurveType, type SplinePoint, SplinePointType, type SpotLightFilter, Square, Star, type StringifyOptions, type StrokeType, type TemplateVariable, type TemplateVariableType, Text, Timeline, Track, Triangle, type ValidationError, type ValidationResult, type VariableMap, type Viewbox, type WarpFilter, type WarpType, type WatercolorFilter, type XrayFilter, computeArrowVertices, computeCrossVertices, computeDashArray, computeGearPath, computeGearVertices, computePolygonVertices, computeRectanglePath, computeRingPath, computeSpiralPath, computeSplinePath, computeStarVertices, createDocument, createShape, createViewbox, escXml, extractVariables, filterAttr, generateCode, generateCssCode, generateD3Code, generateId, generatePatternSvgContent, generateReactCode, generateSvgCode, generateVueCode, getEasingCubicBezier, getMarkerDescriptors, getPatternElements, linearGradient, migrateSnapshot, parseDocument, parseVariableArgs, pattern, radialGradient, renderAnimationElements, renderCircle, renderEllipse, renderFilterDefs, renderFilterPrimitivesForType, renderImage, renderLine, renderPolygonShape, renderPolyline, renderRectangle, renderShape, renderSpline, renderText, renderToSvg, stringifyDocument, substituteString, substituteVariables, validateSnapshot, verticesToPath };
|