@flowscape-ui/core-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +300 -0
- package/dist/index.cjs +7347 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1430 -0
- package/dist/index.d.ts +1430 -0
- package/dist/index.js +7314 -0
- package/dist/index.js.map +1 -0
- package/package.json +87 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1430 @@
|
|
|
1
|
+
import Konva from 'konva';
|
|
2
|
+
import * as konva_lib_types from 'konva/lib/types';
|
|
3
|
+
|
|
4
|
+
interface BaseNodeOptions {
|
|
5
|
+
id?: string;
|
|
6
|
+
x?: number;
|
|
7
|
+
y?: number;
|
|
8
|
+
width?: number;
|
|
9
|
+
height?: number;
|
|
10
|
+
}
|
|
11
|
+
declare abstract class BaseNode<T extends Konva.Node = Konva.Node> {
|
|
12
|
+
protected konvaNode: T;
|
|
13
|
+
readonly id: string;
|
|
14
|
+
constructor(node: T, options?: BaseNodeOptions);
|
|
15
|
+
getNode(): T;
|
|
16
|
+
setPosition({ x, y }: {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
}): void;
|
|
20
|
+
getPosition(): konva_lib_types.Vector2d;
|
|
21
|
+
remove(): void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface ShapeNodeOptions extends BaseNodeOptions {
|
|
25
|
+
fill?: string;
|
|
26
|
+
stroke?: string;
|
|
27
|
+
strokeWidth?: number;
|
|
28
|
+
cornerRadius?: number | number[];
|
|
29
|
+
}
|
|
30
|
+
declare class ShapeNode extends BaseNode<Konva.Rect> {
|
|
31
|
+
constructor(options: ShapeNodeOptions);
|
|
32
|
+
setFill(color: string): this;
|
|
33
|
+
setStroke(color: string): this;
|
|
34
|
+
setStrokeWidth(width: number): this;
|
|
35
|
+
setCornerRadius(radius: number | number[]): this;
|
|
36
|
+
setSize({ width, height }: {
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
}): this;
|
|
40
|
+
getFill(): string | undefined;
|
|
41
|
+
getStroke(): string | undefined;
|
|
42
|
+
getStrokeWidth(): number;
|
|
43
|
+
getCornerRadius(): number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type Listener<TArgs extends unknown[]> = (...args: TArgs) => void;
|
|
47
|
+
declare class EventBus<TEvents extends {
|
|
48
|
+
[K in keyof TEvents]: unknown[];
|
|
49
|
+
} = Record<string, unknown[]>> {
|
|
50
|
+
private _listeners;
|
|
51
|
+
constructor();
|
|
52
|
+
get listeners(): Map<string, Listener<TEvents[keyof TEvents & string]>[]>;
|
|
53
|
+
on<K extends keyof TEvents & string>(event: K, callback: Listener<TEvents[K]>): void;
|
|
54
|
+
off<K extends keyof TEvents & string>(event: K, callback: Listener<TEvents[K]>): void;
|
|
55
|
+
once<K extends keyof TEvents & string>(event: K, callback: Listener<TEvents[K]>): void;
|
|
56
|
+
emit<K extends keyof TEvents & string>(event: K, ...args: TEvents[K]): void;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Типизированные события CoreEngine
|
|
61
|
+
* Все события строго типизированы для лучшего DX
|
|
62
|
+
*/
|
|
63
|
+
interface CoreEvents {
|
|
64
|
+
/** Нода была создана и добавлена в мир */
|
|
65
|
+
'node:created': [node: BaseNode];
|
|
66
|
+
/** Нода была удалена из мира */
|
|
67
|
+
'node:removed': [node: BaseNode];
|
|
68
|
+
/** Нода была выделена */
|
|
69
|
+
'node:selected': [node: BaseNode];
|
|
70
|
+
/** Выделение ноды было снято */
|
|
71
|
+
'node:deselected': [node: BaseNode];
|
|
72
|
+
/** Нода была изменена (position, size, rotation, etc.) */
|
|
73
|
+
'node:transformed': [
|
|
74
|
+
node: BaseNode,
|
|
75
|
+
changes: {
|
|
76
|
+
x?: number;
|
|
77
|
+
y?: number;
|
|
78
|
+
width?: number;
|
|
79
|
+
height?: number;
|
|
80
|
+
rotation?: number;
|
|
81
|
+
scaleX?: number;
|
|
82
|
+
scaleY?: number;
|
|
83
|
+
}
|
|
84
|
+
];
|
|
85
|
+
/** Z-index ноды был изменён */
|
|
86
|
+
'node:zIndexChanged': [node: BaseNode, oldIndex: number, newIndex: number];
|
|
87
|
+
/** Группа была создана */
|
|
88
|
+
'group:created': [group: BaseNode, nodes: BaseNode[]];
|
|
89
|
+
/** Группа была разгруппирована */
|
|
90
|
+
'group:ungrouped': [group: BaseNode, nodes: BaseNode[]];
|
|
91
|
+
/** Множественное выделение создано */
|
|
92
|
+
'selection:multi:created': [nodes: BaseNode[]];
|
|
93
|
+
/** Множественное выделение уничтожено */
|
|
94
|
+
'selection:multi:destroyed': [];
|
|
95
|
+
/** Выделение полностью снято */
|
|
96
|
+
'selection:cleared': [];
|
|
97
|
+
/** Ноды были скопированы в буфер обмена */
|
|
98
|
+
'clipboard:copy': [nodes: BaseNode[]];
|
|
99
|
+
/** Ноды были вырезаны в буфер обмена */
|
|
100
|
+
'clipboard:cut': [nodes: BaseNode[]];
|
|
101
|
+
/** Ноды были вставлены из буфера обмена */
|
|
102
|
+
'clipboard:paste': [nodes: BaseNode[]];
|
|
103
|
+
/** Зум был изменён программно */
|
|
104
|
+
'camera:setZoom': [{
|
|
105
|
+
scale: number;
|
|
106
|
+
}];
|
|
107
|
+
/** Зум был изменён пользователем (колесо мыши) */
|
|
108
|
+
'camera:zoom': [{
|
|
109
|
+
scale: number;
|
|
110
|
+
position: {
|
|
111
|
+
x: number;
|
|
112
|
+
y: number;
|
|
113
|
+
};
|
|
114
|
+
}];
|
|
115
|
+
/** Камера была сброшена */
|
|
116
|
+
'camera:reset': [];
|
|
117
|
+
/** Шаг зума был изменён */
|
|
118
|
+
'camera:zoomStep': [{
|
|
119
|
+
zoomStep: number;
|
|
120
|
+
}];
|
|
121
|
+
/** Шаг панорамирования был изменён */
|
|
122
|
+
'camera:panStep': [{
|
|
123
|
+
panStep: number;
|
|
124
|
+
}];
|
|
125
|
+
/** Камера была перемещена (панорамирование) */
|
|
126
|
+
'camera:pan': [{
|
|
127
|
+
dx: number;
|
|
128
|
+
dy: number;
|
|
129
|
+
position: {
|
|
130
|
+
x: number;
|
|
131
|
+
y: number;
|
|
132
|
+
};
|
|
133
|
+
}];
|
|
134
|
+
/** Плагин был добавлен */
|
|
135
|
+
'plugin:added': [pluginName: string];
|
|
136
|
+
/** Плагин был удалён */
|
|
137
|
+
'plugin:removed': [pluginName: string];
|
|
138
|
+
/** Stage был изменён (resize) */
|
|
139
|
+
'stage:resized': [{
|
|
140
|
+
width: number;
|
|
141
|
+
height: number;
|
|
142
|
+
}];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
interface TextNodeOptions extends BaseNodeOptions {
|
|
146
|
+
text?: string;
|
|
147
|
+
fontSize?: number;
|
|
148
|
+
fontFamily?: string;
|
|
149
|
+
fontStyle?: string;
|
|
150
|
+
fill?: string;
|
|
151
|
+
align?: 'left' | 'center' | 'right';
|
|
152
|
+
padding?: number;
|
|
153
|
+
}
|
|
154
|
+
declare class TextNode extends BaseNode<Konva.Text> {
|
|
155
|
+
constructor(options?: TextNodeOptions);
|
|
156
|
+
getText(): string;
|
|
157
|
+
getFontSize(): number;
|
|
158
|
+
getFontFamily(): string;
|
|
159
|
+
getFontStyle(): string;
|
|
160
|
+
getFill(): string | undefined;
|
|
161
|
+
getAlign(): 'left' | 'center' | 'right';
|
|
162
|
+
getPadding(): number;
|
|
163
|
+
getSize(): {
|
|
164
|
+
width: number;
|
|
165
|
+
height: number;
|
|
166
|
+
};
|
|
167
|
+
setText(text: string): this;
|
|
168
|
+
setFontSize(size: number): this;
|
|
169
|
+
setFontFamily(family: string): this;
|
|
170
|
+
setFontStyle(style: string): this;
|
|
171
|
+
setFill(color: string): this;
|
|
172
|
+
setAlign(align: 'left' | 'center' | 'right'): this;
|
|
173
|
+
setPadding(padding: number): this;
|
|
174
|
+
setSize({ width, height }: {
|
|
175
|
+
width: number;
|
|
176
|
+
height: number;
|
|
177
|
+
}): this;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
type ImageSource = HTMLImageElement;
|
|
181
|
+
interface ImageNodeOptions extends BaseNodeOptions {
|
|
182
|
+
image?: ImageSource;
|
|
183
|
+
src?: string;
|
|
184
|
+
width?: number;
|
|
185
|
+
height?: number;
|
|
186
|
+
}
|
|
187
|
+
declare class ImageNode extends BaseNode<Konva.Image> {
|
|
188
|
+
constructor(options?: ImageNodeOptions);
|
|
189
|
+
getSize(): {
|
|
190
|
+
width: number;
|
|
191
|
+
height: number;
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Async loads image from URL and sets it to Konva.Image.
|
|
195
|
+
* Returns this for chaining.
|
|
196
|
+
*/
|
|
197
|
+
setSrc(url: string, crossOrigin?: '' | 'anonymous' | 'use-credentials' | undefined): Promise<this>;
|
|
198
|
+
/**
|
|
199
|
+
* Set already loaded image source (HTMLImageElement)
|
|
200
|
+
*/
|
|
201
|
+
setImage(image: ImageSource): this;
|
|
202
|
+
setSize({ width, height }: {
|
|
203
|
+
width: number;
|
|
204
|
+
height: number;
|
|
205
|
+
}): this;
|
|
206
|
+
private _loadHTMLImage;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
interface CircleNodeOptions extends BaseNodeOptions {
|
|
210
|
+
radius?: number;
|
|
211
|
+
fill?: string;
|
|
212
|
+
stroke?: string;
|
|
213
|
+
strokeWidth?: number;
|
|
214
|
+
}
|
|
215
|
+
declare class CircleNode extends BaseNode<Konva.Circle> {
|
|
216
|
+
constructor(options?: CircleNodeOptions);
|
|
217
|
+
getRadius(): number;
|
|
218
|
+
getFill(): string | undefined;
|
|
219
|
+
getStroke(): string | undefined;
|
|
220
|
+
getStrokeWidth(): number;
|
|
221
|
+
setRadius(radius: number): this;
|
|
222
|
+
setFill(color: string): this;
|
|
223
|
+
setStroke(color: string): this;
|
|
224
|
+
setStrokeWidth(width: number): this;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
interface EllipseNodeOptions extends BaseNodeOptions {
|
|
228
|
+
radiusX?: number;
|
|
229
|
+
radiusY?: number;
|
|
230
|
+
fill?: string;
|
|
231
|
+
stroke?: string;
|
|
232
|
+
strokeWidth?: number;
|
|
233
|
+
}
|
|
234
|
+
declare class EllipseNode extends BaseNode<Konva.Ellipse> {
|
|
235
|
+
constructor(options?: EllipseNodeOptions);
|
|
236
|
+
getRadiusX(): number;
|
|
237
|
+
getRadiusY(): number;
|
|
238
|
+
getFill(): string | undefined;
|
|
239
|
+
getStroke(): string | undefined;
|
|
240
|
+
getStrokeWidth(): number;
|
|
241
|
+
setRadiusX(value: number): this;
|
|
242
|
+
setRadiusY(value: number): this;
|
|
243
|
+
setFill(color: string): this;
|
|
244
|
+
setStroke(color: string): this;
|
|
245
|
+
setStrokeWidth(width: number): this;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
interface ArcNodeOptions extends BaseNodeOptions {
|
|
249
|
+
innerRadius?: number;
|
|
250
|
+
outerRadius?: number;
|
|
251
|
+
angle?: number;
|
|
252
|
+
rotation?: number;
|
|
253
|
+
clockwise?: boolean;
|
|
254
|
+
fill?: string;
|
|
255
|
+
stroke?: string;
|
|
256
|
+
strokeWidth?: number;
|
|
257
|
+
}
|
|
258
|
+
declare class ArcNode extends BaseNode<Konva.Arc> {
|
|
259
|
+
constructor(options?: ArcNodeOptions);
|
|
260
|
+
getInnerRadius(): number;
|
|
261
|
+
getOuterRadius(): number;
|
|
262
|
+
getAngle(): number;
|
|
263
|
+
isClockwise(): boolean;
|
|
264
|
+
setInnerRadius(v: number): this;
|
|
265
|
+
setOuterRadius(v: number): this;
|
|
266
|
+
setAngle(v: number): this;
|
|
267
|
+
setRotationDeg(v: number): this;
|
|
268
|
+
setClockwise(v: boolean): this;
|
|
269
|
+
setFill(color: string): this;
|
|
270
|
+
setStroke(color: string): this;
|
|
271
|
+
setStrokeWidth(width: number): this;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
interface ArrowNodeOptions extends BaseNodeOptions {
|
|
275
|
+
points?: number[];
|
|
276
|
+
tension?: number;
|
|
277
|
+
pointerLength?: number;
|
|
278
|
+
pointerWidth?: number;
|
|
279
|
+
pointerAtBeginning?: boolean;
|
|
280
|
+
pointerAtEnding?: boolean;
|
|
281
|
+
fill?: string;
|
|
282
|
+
stroke?: string;
|
|
283
|
+
strokeWidth?: number;
|
|
284
|
+
}
|
|
285
|
+
declare class ArrowNode extends BaseNode<Konva.Arrow> {
|
|
286
|
+
constructor(options?: ArrowNodeOptions);
|
|
287
|
+
getPoints(): number[];
|
|
288
|
+
getTension(): number;
|
|
289
|
+
getPointerLength(): number;
|
|
290
|
+
getPointerWidth(): number;
|
|
291
|
+
getPointerAtBeginning(): boolean;
|
|
292
|
+
getPointerAtEnding(): boolean;
|
|
293
|
+
setPoints(v: number[]): this;
|
|
294
|
+
setTension(v: number): this;
|
|
295
|
+
setPointerLength(v: number): this;
|
|
296
|
+
setPointerWidth(v: number): this;
|
|
297
|
+
setPointerAtBeginning(v: boolean): this;
|
|
298
|
+
setPointerAtEnding(v: boolean): this;
|
|
299
|
+
setFill(color: string): this;
|
|
300
|
+
setStroke(color: string): this;
|
|
301
|
+
setStrokeWidth(width: number): this;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
interface RegularPolygonNodeOptions extends BaseNodeOptions {
|
|
305
|
+
sides?: number;
|
|
306
|
+
radius?: number;
|
|
307
|
+
fill?: string;
|
|
308
|
+
stroke?: string;
|
|
309
|
+
strokeWidth?: number;
|
|
310
|
+
}
|
|
311
|
+
declare class RegularPolygonNode extends BaseNode<Konva.RegularPolygon> {
|
|
312
|
+
constructor(options?: RegularPolygonNodeOptions);
|
|
313
|
+
getSides(): number;
|
|
314
|
+
getRadius(): number;
|
|
315
|
+
getFill(): string | undefined;
|
|
316
|
+
getStroke(): string | undefined;
|
|
317
|
+
getStrokeWidth(): number;
|
|
318
|
+
setSides(v: number): this;
|
|
319
|
+
setRadius(v: number): this;
|
|
320
|
+
setFill(color: string): this;
|
|
321
|
+
setStroke(color: string): this;
|
|
322
|
+
setStrokeWidth(width: number): this;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
interface StarNodeOptions extends BaseNodeOptions {
|
|
326
|
+
numPoints?: number;
|
|
327
|
+
innerRadius?: number;
|
|
328
|
+
outerRadius?: number;
|
|
329
|
+
fill?: string;
|
|
330
|
+
stroke?: string;
|
|
331
|
+
strokeWidth?: number;
|
|
332
|
+
}
|
|
333
|
+
declare class StarNode extends BaseNode<Konva.Star> {
|
|
334
|
+
constructor(options?: StarNodeOptions);
|
|
335
|
+
getNumPoints(): number;
|
|
336
|
+
getInnerRadius(): number;
|
|
337
|
+
getOuterRadius(): number;
|
|
338
|
+
getFill(): string | undefined;
|
|
339
|
+
getStroke(): string | undefined;
|
|
340
|
+
getStrokeWidth(): number;
|
|
341
|
+
setNumPoints(v: number): this;
|
|
342
|
+
setInnerRadius(v: number): this;
|
|
343
|
+
setOuterRadius(v: number): this;
|
|
344
|
+
setFill(color: string): this;
|
|
345
|
+
setStroke(color: string): this;
|
|
346
|
+
setStrokeWidth(width: number): this;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
interface RingNodeOptions extends BaseNodeOptions {
|
|
350
|
+
innerRadius?: number;
|
|
351
|
+
outerRadius?: number;
|
|
352
|
+
fill?: string;
|
|
353
|
+
stroke?: string;
|
|
354
|
+
strokeWidth?: number;
|
|
355
|
+
}
|
|
356
|
+
declare class RingNode extends BaseNode<Konva.Ring> {
|
|
357
|
+
constructor(options?: RingNodeOptions);
|
|
358
|
+
getInnerRadius(): number;
|
|
359
|
+
getOuterRadius(): number;
|
|
360
|
+
getFill(): string | undefined;
|
|
361
|
+
getStroke(): string | undefined;
|
|
362
|
+
getStrokeWidth(): number;
|
|
363
|
+
setInnerRadius(v: number): this;
|
|
364
|
+
setOuterRadius(v: number): this;
|
|
365
|
+
setFill(color: string): this;
|
|
366
|
+
setStroke(color: string): this;
|
|
367
|
+
setStrokeWidth(width: number): this;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
interface GroupNodeOptions extends BaseNodeOptions {
|
|
371
|
+
draggable?: boolean;
|
|
372
|
+
listening?: boolean;
|
|
373
|
+
clip?: {
|
|
374
|
+
x: number;
|
|
375
|
+
y: number;
|
|
376
|
+
width: number;
|
|
377
|
+
height: number;
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
declare class GroupNode extends BaseNode<Konva.Group> {
|
|
381
|
+
constructor(options?: GroupNodeOptions);
|
|
382
|
+
addChild(child: Konva.Node | BaseNode): this;
|
|
383
|
+
removeChild(child: Konva.Node | BaseNode): this;
|
|
384
|
+
removeAllChildren(): this;
|
|
385
|
+
getChildren(): Konva.Node[];
|
|
386
|
+
findByName(name: string): Konva.Node[];
|
|
387
|
+
setDraggable(v: boolean): this;
|
|
388
|
+
isDraggable(): boolean;
|
|
389
|
+
setListening(v: boolean): this;
|
|
390
|
+
isListening(): boolean;
|
|
391
|
+
setClip(rect: {
|
|
392
|
+
x: number;
|
|
393
|
+
y: number;
|
|
394
|
+
width: number;
|
|
395
|
+
height: number;
|
|
396
|
+
}): this;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
declare class NodeManager {
|
|
400
|
+
private _layer;
|
|
401
|
+
private _world;
|
|
402
|
+
private _nodes;
|
|
403
|
+
private _stage;
|
|
404
|
+
private _eventBus;
|
|
405
|
+
private _batchDrawScheduled;
|
|
406
|
+
private _listCache;
|
|
407
|
+
private _listCacheInvalidated;
|
|
408
|
+
constructor(stage: Konva.Stage, eventBus: EventBus<CoreEvents>);
|
|
409
|
+
get layer(): Konva.Layer;
|
|
410
|
+
get world(): Konva.Group;
|
|
411
|
+
get stage(): Konva.Stage;
|
|
412
|
+
get eventBus(): EventBus<CoreEvents>;
|
|
413
|
+
addShape(options: ShapeNodeOptions): ShapeNode;
|
|
414
|
+
addText(options: TextNodeOptions): TextNode;
|
|
415
|
+
addImage(options: ImageNodeOptions): ImageNode;
|
|
416
|
+
addCircle(options: CircleNodeOptions): CircleNode;
|
|
417
|
+
addEllipse(options: EllipseNodeOptions): EllipseNode;
|
|
418
|
+
addArc(options: ArcNodeOptions): ArcNode;
|
|
419
|
+
addStar(options: StarNodeOptions): StarNode;
|
|
420
|
+
addArrow(options: ArrowNodeOptions): ArrowNode;
|
|
421
|
+
addRing(options: RingNodeOptions): RingNode;
|
|
422
|
+
addRegularPolygon(options: RegularPolygonNodeOptions): RegularPolygonNode;
|
|
423
|
+
addGroup(options: GroupNodeOptions): GroupNode;
|
|
424
|
+
remove(node: BaseNode): void;
|
|
425
|
+
findById(id: string): BaseNode | undefined;
|
|
426
|
+
list(): BaseNode[];
|
|
427
|
+
/**
|
|
428
|
+
* Deferred redraw (throttling)
|
|
429
|
+
* CRITICAL OPTIMIZATION: group multiple node additions
|
|
430
|
+
*/
|
|
431
|
+
private _scheduleBatchDraw;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
interface CameraManagerOptions {
|
|
435
|
+
stage: Konva.Stage;
|
|
436
|
+
eventBus: EventBus<CoreEvents>;
|
|
437
|
+
target?: Konva.Node;
|
|
438
|
+
initialScale?: number;
|
|
439
|
+
minScale?: number;
|
|
440
|
+
maxScale?: number;
|
|
441
|
+
draggable?: boolean;
|
|
442
|
+
zoomStep?: number;
|
|
443
|
+
panStep?: number;
|
|
444
|
+
}
|
|
445
|
+
declare class CameraManager {
|
|
446
|
+
private _stage;
|
|
447
|
+
private _eventBus;
|
|
448
|
+
private _target;
|
|
449
|
+
private _scale;
|
|
450
|
+
private _minScale;
|
|
451
|
+
private _maxScale;
|
|
452
|
+
private _zoomStep;
|
|
453
|
+
private _panStep;
|
|
454
|
+
private _wheelScheduled;
|
|
455
|
+
private _pendingWheelEvent;
|
|
456
|
+
constructor(options: CameraManagerOptions);
|
|
457
|
+
private _initWheelZoom;
|
|
458
|
+
private _handleWheel;
|
|
459
|
+
get zoomStep(): number;
|
|
460
|
+
get panStep(): number;
|
|
461
|
+
setZoom(zoom: number): void;
|
|
462
|
+
zoomIn(step?: number): void;
|
|
463
|
+
zoomOut(step?: number): void;
|
|
464
|
+
reset(): void;
|
|
465
|
+
setDraggable(enabled: boolean): void;
|
|
466
|
+
setZoomStep(step: number): void;
|
|
467
|
+
setPanStep(step: number): void;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
interface LODLevel {
|
|
471
|
+
minScale: number;
|
|
472
|
+
maxScale: number;
|
|
473
|
+
simplify: boolean;
|
|
474
|
+
disableStroke?: boolean;
|
|
475
|
+
disableShadow?: boolean;
|
|
476
|
+
disablePerfectDraw?: boolean;
|
|
477
|
+
}
|
|
478
|
+
interface LODOptions {
|
|
479
|
+
enabled?: boolean;
|
|
480
|
+
levels?: LODLevel[];
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* LODManager - manager for level of detail
|
|
484
|
+
*
|
|
485
|
+
* This is an ADDITIONAL optimization on top of Konva framework.
|
|
486
|
+
* Konva does not provide automatic LOD, so this implementation is necessary.
|
|
487
|
+
*
|
|
488
|
+
* When far away (small scale), it simplifies node rendering:
|
|
489
|
+
* - Disables stroke via strokeEnabled(false)
|
|
490
|
+
* - Disables shadow via shadowEnabled(false)
|
|
491
|
+
* - Disables perfect draw via perfectDrawEnabled(false)
|
|
492
|
+
*
|
|
493
|
+
* All methods use built-in Konva API, recommended in the official documentation:
|
|
494
|
+
* https://konvajs.org/docs/performance/All_Performance_Tips.html
|
|
495
|
+
*
|
|
496
|
+
* Performance boost: 20-30% when many nodes are rendered at small scales.
|
|
497
|
+
*/
|
|
498
|
+
declare class LODManager {
|
|
499
|
+
private _enabled;
|
|
500
|
+
private _levels;
|
|
501
|
+
private _currentScale;
|
|
502
|
+
private _appliedNodes;
|
|
503
|
+
constructor(options?: LODOptions);
|
|
504
|
+
/**
|
|
505
|
+
* Level of detail for current scale
|
|
506
|
+
*/
|
|
507
|
+
private _getLODLevel;
|
|
508
|
+
/**
|
|
509
|
+
* Apply LOD to node based on current scale
|
|
510
|
+
*/
|
|
511
|
+
applyLOD(node: BaseNode, scale: number): void;
|
|
512
|
+
/**
|
|
513
|
+
* Restore original settings for node
|
|
514
|
+
*/
|
|
515
|
+
private _restoreNode;
|
|
516
|
+
/**
|
|
517
|
+
* Apply LOD to all nodes
|
|
518
|
+
*/
|
|
519
|
+
applyToAll(nodes: BaseNode[], scale: number): void;
|
|
520
|
+
/**
|
|
521
|
+
* Restore all nodes to full detail
|
|
522
|
+
*/
|
|
523
|
+
restoreAll(nodes: BaseNode[]): void;
|
|
524
|
+
/**
|
|
525
|
+
* Enable LOD
|
|
526
|
+
*/
|
|
527
|
+
enable(): void;
|
|
528
|
+
/**
|
|
529
|
+
* Disable LOD and restore all nodes
|
|
530
|
+
*/
|
|
531
|
+
disable(nodes: BaseNode[]): void;
|
|
532
|
+
/**
|
|
533
|
+
* Check if LOD is enabled
|
|
534
|
+
*/
|
|
535
|
+
get enabled(): boolean;
|
|
536
|
+
/**
|
|
537
|
+
* Get current scale
|
|
538
|
+
*/
|
|
539
|
+
get currentScale(): number;
|
|
540
|
+
/**
|
|
541
|
+
* Get LOD stats
|
|
542
|
+
*/
|
|
543
|
+
getStats(): {
|
|
544
|
+
enabled: boolean;
|
|
545
|
+
currentScale: number;
|
|
546
|
+
appliedNodes: number;
|
|
547
|
+
currentLevel: LODLevel | null;
|
|
548
|
+
};
|
|
549
|
+
/**
|
|
550
|
+
* Set custom LOD levels
|
|
551
|
+
*/
|
|
552
|
+
setLevels(levels: LODLevel[]): void;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
interface VirtualizationStats {
|
|
556
|
+
total: number;
|
|
557
|
+
visible: number;
|
|
558
|
+
hidden: number;
|
|
559
|
+
cullingRate: number;
|
|
560
|
+
}
|
|
561
|
+
interface VirtualizationOptions {
|
|
562
|
+
enabled?: boolean;
|
|
563
|
+
bufferZone?: number;
|
|
564
|
+
throttleMs?: number;
|
|
565
|
+
lod?: LODOptions;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* VirtualizationManager - manages node visibility for performance optimization
|
|
569
|
+
*
|
|
570
|
+
* IMPORTANT: This is an ADDITIONAL optimization on top of Konva framework.
|
|
571
|
+
* Konva does not provide automatic viewport virtualization, so this implementation is necessary.
|
|
572
|
+
*
|
|
573
|
+
* Main idea: render only nodes that are within the viewport (visible area).
|
|
574
|
+
* This provides a significant performance boost when dealing with many nodes.
|
|
575
|
+
*
|
|
576
|
+
* Optimizations (uses built-in Konva APIs):
|
|
577
|
+
* 1. visible: false - node is not rendered (Konva recommendation)
|
|
578
|
+
* 2. listening: false - node does not handle events (Konva recommendation)
|
|
579
|
+
* 3. Buffer zone - render slightly more than viewport for smoothness
|
|
580
|
+
* 4. Throttling - limits update frequency
|
|
581
|
+
* 5. getClientRect() - Konva automatically caches results internally
|
|
582
|
+
*
|
|
583
|
+
* Konva documentation: https://konvajs.org/docs/performance/All_Performance_Tips.html
|
|
584
|
+
*/
|
|
585
|
+
declare class VirtualizationManager {
|
|
586
|
+
private _stage;
|
|
587
|
+
private _world;
|
|
588
|
+
private _nodeManager;
|
|
589
|
+
private _enabled;
|
|
590
|
+
private _bufferZone;
|
|
591
|
+
private _throttle;
|
|
592
|
+
private _viewport;
|
|
593
|
+
private _visibleNodes;
|
|
594
|
+
private _hiddenNodes;
|
|
595
|
+
private _updateScheduled;
|
|
596
|
+
private _lod;
|
|
597
|
+
constructor(_stage: Konva.Stage, _world: Konva.Group, _nodeManager: NodeManager, options?: VirtualizationOptions);
|
|
598
|
+
/**
|
|
599
|
+
* Updates viewport based on current position and scale of world
|
|
600
|
+
*/
|
|
601
|
+
private _updateViewport;
|
|
602
|
+
/**
|
|
603
|
+
* Gets node bounding box in world coordinates (relative to world)
|
|
604
|
+
*
|
|
605
|
+
* OPTIMIZATION: Konva automatically caches getClientRect() results internally,
|
|
606
|
+
* so additional TTL-cache is not needed. Konva invalidates its cache on transformations,
|
|
607
|
+
* which is more reliable than our TTL-approach.
|
|
608
|
+
*/
|
|
609
|
+
private _getNodeBBox;
|
|
610
|
+
/**
|
|
611
|
+
* Checks if node is within viewport
|
|
612
|
+
*/
|
|
613
|
+
private _isNodeVisible;
|
|
614
|
+
/**
|
|
615
|
+
* Updates visibility of all nodes
|
|
616
|
+
*/
|
|
617
|
+
updateVisibility(): void;
|
|
618
|
+
/**
|
|
619
|
+
* Sets up event listeners
|
|
620
|
+
*/
|
|
621
|
+
private _setupListeners;
|
|
622
|
+
/**
|
|
623
|
+
* Schedules update for the next frame
|
|
624
|
+
*/
|
|
625
|
+
private _scheduleUpdate;
|
|
626
|
+
/**
|
|
627
|
+
* Enables virtualization
|
|
628
|
+
*/
|
|
629
|
+
enable(): void;
|
|
630
|
+
/**
|
|
631
|
+
* Disables virtualization (shows all nodes)
|
|
632
|
+
*/
|
|
633
|
+
disable(): void;
|
|
634
|
+
/**
|
|
635
|
+
* Returns virtualization statistics
|
|
636
|
+
*/
|
|
637
|
+
getStats(): VirtualizationStats;
|
|
638
|
+
/**
|
|
639
|
+
* Sets buffer zone size
|
|
640
|
+
*/
|
|
641
|
+
setBufferZone(pixels: number): void;
|
|
642
|
+
/**
|
|
643
|
+
* Sets throttle for updates
|
|
644
|
+
*/
|
|
645
|
+
setThrottle(ms: number): void;
|
|
646
|
+
/**
|
|
647
|
+
* Checks if virtualization is enabled
|
|
648
|
+
*/
|
|
649
|
+
get enabled(): boolean;
|
|
650
|
+
/**
|
|
651
|
+
* Returns current viewport
|
|
652
|
+
*/
|
|
653
|
+
get viewport(): {
|
|
654
|
+
x: number;
|
|
655
|
+
y: number;
|
|
656
|
+
width: number;
|
|
657
|
+
height: number;
|
|
658
|
+
};
|
|
659
|
+
/**
|
|
660
|
+
* Forcefully updates visibility (ignores throttle)
|
|
661
|
+
*/
|
|
662
|
+
forceUpdate(): void;
|
|
663
|
+
/**
|
|
664
|
+
* Returns LOD Manager (if enabled)
|
|
665
|
+
*/
|
|
666
|
+
get lod(): LODManager | null;
|
|
667
|
+
/**
|
|
668
|
+
* Destroys manager and releases resources
|
|
669
|
+
*/
|
|
670
|
+
destroy(): void;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
declare abstract class Plugin {
|
|
674
|
+
protected abstract onAttach(core: CoreEngine): void;
|
|
675
|
+
protected abstract onDetach(core: CoreEngine): void;
|
|
676
|
+
attach(core: CoreEngine): void;
|
|
677
|
+
detach(core: CoreEngine): void;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
declare class Plugins {
|
|
681
|
+
private _core;
|
|
682
|
+
private _items;
|
|
683
|
+
constructor(core: CoreEngine, initial?: Plugin[]);
|
|
684
|
+
addPlugins(plugins: Plugin[]): Plugin[];
|
|
685
|
+
removePlugins(plugins: Plugin[]): Plugin[];
|
|
686
|
+
removeAllPlugins(): Plugin[];
|
|
687
|
+
list(): Plugin[];
|
|
688
|
+
get(name: string): Plugin | undefined;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
interface CoreEngineOptions {
|
|
692
|
+
container: HTMLDivElement;
|
|
693
|
+
width?: number;
|
|
694
|
+
height?: number;
|
|
695
|
+
autoResize?: boolean;
|
|
696
|
+
backgroundColor?: string;
|
|
697
|
+
draggable?: boolean;
|
|
698
|
+
plugins?: Plugin[];
|
|
699
|
+
minScale?: number;
|
|
700
|
+
maxScale?: number;
|
|
701
|
+
virtualization?: {
|
|
702
|
+
enabled?: boolean;
|
|
703
|
+
bufferZone?: number;
|
|
704
|
+
throttleMs?: number;
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
declare class CoreEngine {
|
|
708
|
+
private _stage;
|
|
709
|
+
private _eventBus;
|
|
710
|
+
private _initialWidth;
|
|
711
|
+
private _initialHeight;
|
|
712
|
+
private _autoResize;
|
|
713
|
+
private _backgroundColor;
|
|
714
|
+
private _draggable;
|
|
715
|
+
private _minScale;
|
|
716
|
+
private _maxScale;
|
|
717
|
+
private _gridLayer;
|
|
718
|
+
readonly container: HTMLDivElement;
|
|
719
|
+
readonly nodes: NodeManager;
|
|
720
|
+
readonly camera: CameraManager;
|
|
721
|
+
readonly virtualization: VirtualizationManager;
|
|
722
|
+
readonly plugins: Plugins;
|
|
723
|
+
constructor(options: CoreEngineOptions);
|
|
724
|
+
get eventBus(): EventBus<CoreEvents>;
|
|
725
|
+
get stage(): Konva.Stage;
|
|
726
|
+
get gridLayer(): Konva.Layer;
|
|
727
|
+
get draggable(): boolean;
|
|
728
|
+
get autoResize(): boolean;
|
|
729
|
+
get backgroundColor(): string;
|
|
730
|
+
get initialWidth(): number;
|
|
731
|
+
get initialHeight(): number;
|
|
732
|
+
get minScale(): number;
|
|
733
|
+
get maxScale(): number;
|
|
734
|
+
setSize({ width, height }: {
|
|
735
|
+
width: number;
|
|
736
|
+
height: number;
|
|
737
|
+
}): void;
|
|
738
|
+
setBackgroundColor(color: string): void;
|
|
739
|
+
setDraggable(draggable: boolean): void;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
interface LogoOptions {
|
|
743
|
+
src: string;
|
|
744
|
+
width: number;
|
|
745
|
+
height: number;
|
|
746
|
+
opacity?: number;
|
|
747
|
+
}
|
|
748
|
+
declare class LogoPlugin extends Plugin {
|
|
749
|
+
private _core?;
|
|
750
|
+
private _layer?;
|
|
751
|
+
private _image?;
|
|
752
|
+
private _src;
|
|
753
|
+
private _width;
|
|
754
|
+
private _height;
|
|
755
|
+
private _opacity;
|
|
756
|
+
constructor(options: LogoOptions);
|
|
757
|
+
protected onAttach(core: CoreEngine): void;
|
|
758
|
+
protected onDetach(core: CoreEngine): void;
|
|
759
|
+
setOpacity(opacity: number): void;
|
|
760
|
+
setSize({ width, height }: {
|
|
761
|
+
width: number;
|
|
762
|
+
height: number;
|
|
763
|
+
}): void;
|
|
764
|
+
setSource(src: string): void;
|
|
765
|
+
private _setImage;
|
|
766
|
+
private _loadImageFromString;
|
|
767
|
+
private _layout;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
interface CameraHotkeysOptions {
|
|
771
|
+
target?: Window | Document | HTMLElement | EventTarget;
|
|
772
|
+
zoomStep?: number;
|
|
773
|
+
panStep?: number;
|
|
774
|
+
ignoreEditableTargets?: boolean;
|
|
775
|
+
enableArrows?: boolean;
|
|
776
|
+
enablePanning?: boolean;
|
|
777
|
+
allowMiddleButtonPan?: boolean;
|
|
778
|
+
allowRightButtonPan?: boolean;
|
|
779
|
+
disableContextMenu?: boolean;
|
|
780
|
+
}
|
|
781
|
+
declare class CameraHotkeysPlugin extends Plugin {
|
|
782
|
+
private _core?;
|
|
783
|
+
private _options;
|
|
784
|
+
private _attached;
|
|
785
|
+
private _panning;
|
|
786
|
+
private _last;
|
|
787
|
+
private _prevCursor;
|
|
788
|
+
private _prevStageDraggable?;
|
|
789
|
+
constructor(options?: CameraHotkeysOptions);
|
|
790
|
+
setOptions(patch: Partial<CameraHotkeysOptions>): void;
|
|
791
|
+
protected onAttach(core: CoreEngine): void;
|
|
792
|
+
protected onDetach(core: CoreEngine): void;
|
|
793
|
+
private _onWheelDOM;
|
|
794
|
+
private _onMouseDownKonva;
|
|
795
|
+
private _onMouseMoveKonva;
|
|
796
|
+
private _onMouseUpKonva;
|
|
797
|
+
private _onMouseLeaveKonva;
|
|
798
|
+
private _onContextMenuDOM;
|
|
799
|
+
private _handleKeyDown;
|
|
800
|
+
private _isEditableTarget;
|
|
801
|
+
private _isTouchpadWheel;
|
|
802
|
+
private _pan;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
interface MultiGroupControllerDeps {
|
|
806
|
+
ensureTempMulti: (nodes: BaseNode[]) => void;
|
|
807
|
+
destroyTempMulti: () => void;
|
|
808
|
+
commitTempMultiToGroup: () => void;
|
|
809
|
+
isActive: () => boolean;
|
|
810
|
+
forceUpdate: () => void;
|
|
811
|
+
onWorldChanged?: () => void;
|
|
812
|
+
isInsideTempByTarget?: (target: Konva.Node) => boolean;
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* MultiGroupController — thin controller encapsulating work with temporary multi-group.
|
|
816
|
+
* Actual logic lives in passed dependencies (SelectionPlugin),
|
|
817
|
+
* thanks to which we don't duplicate code for frames/overlays and behavior.
|
|
818
|
+
*/
|
|
819
|
+
declare class MultiGroupController {
|
|
820
|
+
private deps;
|
|
821
|
+
constructor(deps: MultiGroupControllerDeps);
|
|
822
|
+
ensure(nodes: BaseNode[]): void;
|
|
823
|
+
destroy(): void;
|
|
824
|
+
commitToPermanentGroup(): void;
|
|
825
|
+
isActive(): boolean;
|
|
826
|
+
forceUpdateOverlays(): void;
|
|
827
|
+
onWorldChanged(): void;
|
|
828
|
+
isInsideTempByTarget(target: Konva.Node): boolean;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
interface SelectionPluginOptions {
|
|
832
|
+
dragEnabled?: boolean;
|
|
833
|
+
enableTransformer?: boolean;
|
|
834
|
+
deselectOnEmptyClick?: boolean;
|
|
835
|
+
selectablePredicate?: (node: Konva.Node) => boolean;
|
|
836
|
+
autoPanEnabled?: boolean;
|
|
837
|
+
autoPanEdgePx?: number;
|
|
838
|
+
autoPanMaxSpeedPx?: number;
|
|
839
|
+
}
|
|
840
|
+
/**
|
|
841
|
+
* Universal selection and dragging plugin for nodes compatible with BaseNode.
|
|
842
|
+
*
|
|
843
|
+
* Default behavior:
|
|
844
|
+
* - Click on node in NodeManager layer selects the node
|
|
845
|
+
* - Selected node becomes draggable (dragEnabled)
|
|
846
|
+
* - Click on empty area deselects (deselectOnEmptyClick)
|
|
847
|
+
* - Optionally enable Konva.Transformer (enableTransformer)
|
|
848
|
+
*/
|
|
849
|
+
declare class SelectionPlugin extends Plugin {
|
|
850
|
+
private _core?;
|
|
851
|
+
private _options;
|
|
852
|
+
private _selected;
|
|
853
|
+
private _prevDraggable;
|
|
854
|
+
private _transformer;
|
|
855
|
+
private _transformerWasVisibleBeforeDrag;
|
|
856
|
+
private _cornerHandlesWereVisibleBeforeDrag;
|
|
857
|
+
private _sizeLabelWasVisibleBeforeDrag;
|
|
858
|
+
private _rotateHandlesWereVisibleBeforeDrag;
|
|
859
|
+
private _cornerHandlesGroup;
|
|
860
|
+
private _cornerHandles;
|
|
861
|
+
private _cornerHandlesSuppressed;
|
|
862
|
+
private _transformOppositeCorner;
|
|
863
|
+
private _sizeLabel;
|
|
864
|
+
private _radiusLabel;
|
|
865
|
+
private _rotateHandlesGroup;
|
|
866
|
+
private _rotateHandles;
|
|
867
|
+
private _rotateDragState;
|
|
868
|
+
private _rotateCenterAbsStart;
|
|
869
|
+
private _prevStageDraggableBeforeRotate;
|
|
870
|
+
private _worldSyncRafId;
|
|
871
|
+
private _onCameraZoomEvent;
|
|
872
|
+
private _hoverTr;
|
|
873
|
+
private _isPointerDown;
|
|
874
|
+
private _autoPanRafId;
|
|
875
|
+
private _autoPanActive;
|
|
876
|
+
private _autoPanEdgePx;
|
|
877
|
+
private _autoPanMaxSpeedPx;
|
|
878
|
+
private _draggingNode;
|
|
879
|
+
private _ratioKeyPressed;
|
|
880
|
+
private _onGlobalKeyDown;
|
|
881
|
+
private _onGlobalKeyUp;
|
|
882
|
+
private _tempMultiSet;
|
|
883
|
+
private _tempMultiGroup;
|
|
884
|
+
private _tempMultiTr;
|
|
885
|
+
private _tempOverlay;
|
|
886
|
+
private _tempRotateHandlesGroup;
|
|
887
|
+
private _tempRotateHandles;
|
|
888
|
+
private _tempPlacement;
|
|
889
|
+
getMultiGroupController(): MultiGroupController;
|
|
890
|
+
private _tempMultiSizeLabel;
|
|
891
|
+
private _tempMultiHitRect;
|
|
892
|
+
private _multiCtrl;
|
|
893
|
+
private _startAutoPanLoop;
|
|
894
|
+
private _stopAutoPanLoop;
|
|
895
|
+
/**
|
|
896
|
+
* Deferred redraw (throttling)
|
|
897
|
+
* Groups multiple batchDraw calls into one
|
|
898
|
+
*/
|
|
899
|
+
private _scheduleBatchDraw;
|
|
900
|
+
private _parentGroupDuringChildEdit;
|
|
901
|
+
private _parentGroupPrevDraggable;
|
|
902
|
+
private _dragMoveScheduled;
|
|
903
|
+
private _batchDrawScheduled;
|
|
904
|
+
private _hoverThrottle;
|
|
905
|
+
private _uiUpdateDebounce;
|
|
906
|
+
constructor(options?: SelectionPluginOptions);
|
|
907
|
+
setOptions(patch: Partial<SelectionPluginOptions>): void;
|
|
908
|
+
protected onAttach(core: CoreEngine): void;
|
|
909
|
+
protected onDetach(core: CoreEngine): void;
|
|
910
|
+
private _onMouseDown;
|
|
911
|
+
private _select;
|
|
912
|
+
private _clearSelection;
|
|
913
|
+
private _ensureTempMulti;
|
|
914
|
+
private _destroyTempMulti;
|
|
915
|
+
private _updateTempRotateHandlesPosition;
|
|
916
|
+
private _updateTempMultiSizeLabel;
|
|
917
|
+
private _updateTempMultiHitRect;
|
|
918
|
+
private _commitTempMultiToGroup;
|
|
919
|
+
private _tryUngroupSelectedGroup;
|
|
920
|
+
private _ensureHoverTr;
|
|
921
|
+
private _destroyHoverTr;
|
|
922
|
+
private _onHoverMoveThrottled;
|
|
923
|
+
private _onHoverMove;
|
|
924
|
+
private _onHoverDown;
|
|
925
|
+
private _onHoverUp;
|
|
926
|
+
private _onHoverLeave;
|
|
927
|
+
private _refreshTransformer;
|
|
928
|
+
private _restyleSideAnchors;
|
|
929
|
+
private _setupRotateHandles;
|
|
930
|
+
private _destroyRotateHandles;
|
|
931
|
+
private _getNodeCenterAbs;
|
|
932
|
+
private _updateRotateHandlesPosition;
|
|
933
|
+
private _setupSizeLabel;
|
|
934
|
+
private _scheduleUIUpdate;
|
|
935
|
+
private _updateSizeLabel;
|
|
936
|
+
private _destroySizeLabel;
|
|
937
|
+
private _isCornerRadiusSupported;
|
|
938
|
+
private _getCornerRadiusArray;
|
|
939
|
+
private _setCornerRadiusArray;
|
|
940
|
+
private _setupCornerRadiusHandles;
|
|
941
|
+
private _destroyCornerRadiusHandles;
|
|
942
|
+
private _bakeRectScale;
|
|
943
|
+
private _updateCornerRadiusHandlesPosition;
|
|
944
|
+
private _updateCornerRadiusHandlesVisibility;
|
|
945
|
+
private _ensureRadiusLabel;
|
|
946
|
+
private _updateRadiusLabelAt;
|
|
947
|
+
private _showRadiusLabelForCorner;
|
|
948
|
+
private _hideRadiusLabel;
|
|
949
|
+
private _destroyRadiusLabel;
|
|
950
|
+
private _findBaseNodeByTarget;
|
|
951
|
+
private _onNodeRemoved;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
interface GridPluginOptions {
|
|
955
|
+
stepX?: number;
|
|
956
|
+
stepY?: number;
|
|
957
|
+
color?: string;
|
|
958
|
+
lineWidth?: number;
|
|
959
|
+
visible?: boolean;
|
|
960
|
+
minScaleToShow?: number | null;
|
|
961
|
+
enableSnap?: boolean;
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* GridPlugin — draws a grid and implements snap to grid on drag/resize.
|
|
965
|
+
* Architecture is identical to other plugins: onAttach/onDetach, own layer with Konva.Shape.
|
|
966
|
+
*
|
|
967
|
+
* Important points of the current architecture:
|
|
968
|
+
* - Panning/scale is performed by Stage transformations.
|
|
969
|
+
* - Nodes are placed on the NodeManager layer (core.nodes.layer), also Transformers are added to it.
|
|
970
|
+
*/
|
|
971
|
+
declare class GridPlugin extends Plugin {
|
|
972
|
+
private _core?;
|
|
973
|
+
private _layer;
|
|
974
|
+
private _shape;
|
|
975
|
+
private _stepX;
|
|
976
|
+
private _stepY;
|
|
977
|
+
private _color;
|
|
978
|
+
private _lineWidth;
|
|
979
|
+
private _visible;
|
|
980
|
+
private _minScaleToShow;
|
|
981
|
+
private _enableSnap;
|
|
982
|
+
private _dragMoveHandler;
|
|
983
|
+
private _nodesAddHandler;
|
|
984
|
+
private _nodesRemoveHandler;
|
|
985
|
+
private _redrawScheduled;
|
|
986
|
+
private _transformersCache;
|
|
987
|
+
private _cacheInvalidated;
|
|
988
|
+
constructor(options?: GridPluginOptions);
|
|
989
|
+
protected onAttach(core: CoreEngine): void;
|
|
990
|
+
/**
|
|
991
|
+
* Deferred redraw (throttling)
|
|
992
|
+
*/
|
|
993
|
+
private _scheduleRedraw;
|
|
994
|
+
protected onDetach(core: CoreEngine): void;
|
|
995
|
+
setVisible(visible: boolean): void;
|
|
996
|
+
get stepX(): number;
|
|
997
|
+
get stepY(): number;
|
|
998
|
+
get minScaleToShow(): number | null;
|
|
999
|
+
setStep(stepX: number, stepY: number): void;
|
|
1000
|
+
setMinScaleToShow(value: number | null): void;
|
|
1001
|
+
setSnap(enabled: boolean): void;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
interface RulerPluginOptions {
|
|
1005
|
+
thicknessPx?: number;
|
|
1006
|
+
fontFamily?: string;
|
|
1007
|
+
fontSizePx?: number;
|
|
1008
|
+
color?: string;
|
|
1009
|
+
bgColor?: string;
|
|
1010
|
+
borderColor?: string;
|
|
1011
|
+
enabled?: boolean;
|
|
1012
|
+
}
|
|
1013
|
+
declare class RulerPlugin extends Plugin {
|
|
1014
|
+
private _core?;
|
|
1015
|
+
private _options;
|
|
1016
|
+
private _layer;
|
|
1017
|
+
private _hGroup?;
|
|
1018
|
+
private _vGroup?;
|
|
1019
|
+
private _hBg?;
|
|
1020
|
+
private _vBg?;
|
|
1021
|
+
private _hTicksShape?;
|
|
1022
|
+
private _vTicksShape?;
|
|
1023
|
+
private _hBorder?;
|
|
1024
|
+
private _vBorder?;
|
|
1025
|
+
private _redrawScheduled;
|
|
1026
|
+
private _lastRedrawTime;
|
|
1027
|
+
private _redrawThrottleMs;
|
|
1028
|
+
private _panThrottleMs;
|
|
1029
|
+
private _cachedActiveGuide;
|
|
1030
|
+
private _cacheInvalidated;
|
|
1031
|
+
private _stepsCache;
|
|
1032
|
+
constructor(options?: RulerPluginOptions);
|
|
1033
|
+
/**
|
|
1034
|
+
* Calculate optimal step for ruler ticks
|
|
1035
|
+
* Uses nice numbers: 1, 2, 5, 10, 20, 50, 100 and so on
|
|
1036
|
+
*/
|
|
1037
|
+
private _calculateNiceStep;
|
|
1038
|
+
/**
|
|
1039
|
+
* Format number for display on ruler
|
|
1040
|
+
* Always returns an integer without decimal places
|
|
1041
|
+
*/
|
|
1042
|
+
private _formatNumber;
|
|
1043
|
+
/**
|
|
1044
|
+
* Calculate and cache parameters for ticks for current scale
|
|
1045
|
+
*/
|
|
1046
|
+
private _getStepsConfig;
|
|
1047
|
+
protected onAttach(core: CoreEngine): void;
|
|
1048
|
+
protected onDetach(core: CoreEngine): void;
|
|
1049
|
+
/**
|
|
1050
|
+
* Get active guide from RulerGuidesPlugin (with caching)
|
|
1051
|
+
*/
|
|
1052
|
+
private _getActiveGuideInfo;
|
|
1053
|
+
/**
|
|
1054
|
+
* Invalidate active guide cache
|
|
1055
|
+
*/
|
|
1056
|
+
private _invalidateGuideCache;
|
|
1057
|
+
/**
|
|
1058
|
+
* Universal ruler drawing (horizontal or vertical)
|
|
1059
|
+
* @param ctx - canvas context
|
|
1060
|
+
* @param axis - ruler axis ('h' for horizontal, 'v' for vertical)
|
|
1061
|
+
* @param activeGuide - cached active guide info
|
|
1062
|
+
*/
|
|
1063
|
+
private _drawRuler;
|
|
1064
|
+
/**
|
|
1065
|
+
* Draw horizontal ruler
|
|
1066
|
+
* @param activeGuide - cached active guide info
|
|
1067
|
+
*/
|
|
1068
|
+
private _drawHorizontalRuler;
|
|
1069
|
+
/**
|
|
1070
|
+
* Draw vertical ruler
|
|
1071
|
+
* @param activeGuide - cached active guide info
|
|
1072
|
+
*/
|
|
1073
|
+
private _drawVerticalRuler;
|
|
1074
|
+
/**
|
|
1075
|
+
* Full ruler redraw
|
|
1076
|
+
*/
|
|
1077
|
+
private _redraw;
|
|
1078
|
+
/**
|
|
1079
|
+
* Deferred redraw with improved throttling
|
|
1080
|
+
* Groups fast zoom/pan events for optimization
|
|
1081
|
+
* @param isPanning - true for panning (more aggressive throttling)
|
|
1082
|
+
*/
|
|
1083
|
+
private _scheduleRedraw;
|
|
1084
|
+
show(): void;
|
|
1085
|
+
hide(): void;
|
|
1086
|
+
/**
|
|
1087
|
+
* Toggle ruler visibility
|
|
1088
|
+
*/
|
|
1089
|
+
toggle(): void;
|
|
1090
|
+
/**
|
|
1091
|
+
* Check if ruler is visible
|
|
1092
|
+
*/
|
|
1093
|
+
isVisible(): boolean;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
interface RulerGuidesPluginOptions {
|
|
1097
|
+
guideColor?: string;
|
|
1098
|
+
activeColor?: string;
|
|
1099
|
+
rulerThicknessPx?: number;
|
|
1100
|
+
snapToGrid?: boolean;
|
|
1101
|
+
gridStep?: number;
|
|
1102
|
+
}
|
|
1103
|
+
declare class RulerGuidesPlugin extends Plugin {
|
|
1104
|
+
private _core?;
|
|
1105
|
+
private _options;
|
|
1106
|
+
private _guidesLayer;
|
|
1107
|
+
private _guides;
|
|
1108
|
+
private _activeGuide;
|
|
1109
|
+
private _draggingGuide;
|
|
1110
|
+
private _rulerLayerCache;
|
|
1111
|
+
private _updateScheduled;
|
|
1112
|
+
private _dragMoveScheduled;
|
|
1113
|
+
private _batchDrawScheduled;
|
|
1114
|
+
constructor(options?: RulerGuidesPluginOptions);
|
|
1115
|
+
protected onAttach(core: CoreEngine): void;
|
|
1116
|
+
protected onDetach(core: CoreEngine): void;
|
|
1117
|
+
/**
|
|
1118
|
+
* Schedules update of guide positions (without throttling for smoothness)
|
|
1119
|
+
*/
|
|
1120
|
+
private _scheduleUpdate;
|
|
1121
|
+
/**
|
|
1122
|
+
* Updates positions of all guides when world transform changes
|
|
1123
|
+
*/
|
|
1124
|
+
private _updateGuidesPositions;
|
|
1125
|
+
/**
|
|
1126
|
+
* Snaps coordinate to grid
|
|
1127
|
+
*/
|
|
1128
|
+
private _snapToGrid;
|
|
1129
|
+
/**
|
|
1130
|
+
* Schedules batchDraw for grouping updates
|
|
1131
|
+
*/
|
|
1132
|
+
private _scheduleBatchDraw;
|
|
1133
|
+
/**
|
|
1134
|
+
* Starts creating a guide line from ruler
|
|
1135
|
+
*/
|
|
1136
|
+
private _startCreateGuide;
|
|
1137
|
+
private _setActiveGuide;
|
|
1138
|
+
/**
|
|
1139
|
+
* Get active guide
|
|
1140
|
+
*/
|
|
1141
|
+
getActiveGuide(): Konva.Line | null;
|
|
1142
|
+
/**
|
|
1143
|
+
* Get active guide info
|
|
1144
|
+
* @returns { type: 'h' | 'v', coord: number } | null
|
|
1145
|
+
*/
|
|
1146
|
+
getActiveGuideInfo(): {
|
|
1147
|
+
type: 'h' | 'v';
|
|
1148
|
+
coord: number;
|
|
1149
|
+
} | null;
|
|
1150
|
+
/**
|
|
1151
|
+
* Remove active guide
|
|
1152
|
+
*/
|
|
1153
|
+
removeActiveGuide(): void;
|
|
1154
|
+
/**
|
|
1155
|
+
* Get all guides
|
|
1156
|
+
*/
|
|
1157
|
+
getGuides(): Konva.Line[];
|
|
1158
|
+
/**
|
|
1159
|
+
* Remove all guides
|
|
1160
|
+
*/
|
|
1161
|
+
clearGuides(): void;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
interface RulerHighlightPluginOptions {
|
|
1165
|
+
highlightColor?: string;
|
|
1166
|
+
highlightOpacity?: number;
|
|
1167
|
+
rulerThicknessPx?: number;
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* RulerHighlightPlugin
|
|
1171
|
+
* Highlights the areas of the coordinate system that are occupied by selected objects
|
|
1172
|
+
* Works only if RulerPlugin and SelectionPlugin are present
|
|
1173
|
+
*/
|
|
1174
|
+
declare class RulerHighlightPlugin extends Plugin {
|
|
1175
|
+
private _core?;
|
|
1176
|
+
private _options;
|
|
1177
|
+
private _highlightLayer;
|
|
1178
|
+
private _hGroup;
|
|
1179
|
+
private _vGroup;
|
|
1180
|
+
private _hHighlights;
|
|
1181
|
+
private _vHighlights;
|
|
1182
|
+
private _updateDebounce;
|
|
1183
|
+
private _transformersCache;
|
|
1184
|
+
private _cacheInvalidated;
|
|
1185
|
+
constructor(options?: RulerHighlightPluginOptions);
|
|
1186
|
+
protected onAttach(core: CoreEngine): void;
|
|
1187
|
+
protected onDetach(core: CoreEngine): void;
|
|
1188
|
+
/**
|
|
1189
|
+
* Schedules an update (debouncing)
|
|
1190
|
+
*/
|
|
1191
|
+
private _scheduleUpdate;
|
|
1192
|
+
/**
|
|
1193
|
+
* Invalidates the cache of transformers
|
|
1194
|
+
*/
|
|
1195
|
+
private _invalidateCache;
|
|
1196
|
+
/**
|
|
1197
|
+
* Updates highlights based on selected objects
|
|
1198
|
+
*/
|
|
1199
|
+
private _updateHighlights;
|
|
1200
|
+
/**
|
|
1201
|
+
* Recursively collects all individual objects (unwraps groups)
|
|
1202
|
+
*/
|
|
1203
|
+
private _collectNodes;
|
|
1204
|
+
/**
|
|
1205
|
+
* Merges overlapping and adjacent segments
|
|
1206
|
+
*/
|
|
1207
|
+
private _mergeSegments;
|
|
1208
|
+
/**
|
|
1209
|
+
* Get list of selected Konva nodes (with group unwrapping)
|
|
1210
|
+
* Optimization: cache transformers
|
|
1211
|
+
*/
|
|
1212
|
+
private _getSelectedKonvaNodes;
|
|
1213
|
+
/**
|
|
1214
|
+
* Public method to force update highlights
|
|
1215
|
+
* Useful to call when selection changes from outside
|
|
1216
|
+
*/
|
|
1217
|
+
update(): void;
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
interface RulerManagerPluginOptions {
|
|
1221
|
+
enabled?: boolean;
|
|
1222
|
+
}
|
|
1223
|
+
/**
|
|
1224
|
+
* RulerManagerPlugin
|
|
1225
|
+
* Manages visibility of ruler and guides on Shift+R
|
|
1226
|
+
*/
|
|
1227
|
+
declare class RulerManagerPlugin extends Plugin {
|
|
1228
|
+
private _core?;
|
|
1229
|
+
private _options;
|
|
1230
|
+
private _visible;
|
|
1231
|
+
constructor(options?: RulerManagerPluginOptions);
|
|
1232
|
+
protected onAttach(core: CoreEngine): void;
|
|
1233
|
+
protected onDetach(_core: CoreEngine): void;
|
|
1234
|
+
/**
|
|
1235
|
+
* Bind keyboard events
|
|
1236
|
+
*/
|
|
1237
|
+
private _bindKeyboardEvents;
|
|
1238
|
+
/**
|
|
1239
|
+
* Unbind keyboard events
|
|
1240
|
+
*/
|
|
1241
|
+
private _unbindKeyboardEvents;
|
|
1242
|
+
/**
|
|
1243
|
+
* Keyboard event handler
|
|
1244
|
+
*/
|
|
1245
|
+
private _handleKeyDown;
|
|
1246
|
+
/**
|
|
1247
|
+
* Toggle visibility of ruler and guides
|
|
1248
|
+
*/
|
|
1249
|
+
toggle(): void;
|
|
1250
|
+
/**
|
|
1251
|
+
* Show ruler and guides
|
|
1252
|
+
*/
|
|
1253
|
+
show(): void;
|
|
1254
|
+
/**
|
|
1255
|
+
* Hide ruler and guides
|
|
1256
|
+
*/
|
|
1257
|
+
hide(): void;
|
|
1258
|
+
/**
|
|
1259
|
+
* Check if ruler is visible
|
|
1260
|
+
*/
|
|
1261
|
+
isVisible(): boolean;
|
|
1262
|
+
/**
|
|
1263
|
+
* Remove active guide line
|
|
1264
|
+
* @returns true if guide was removed, false if no active guide
|
|
1265
|
+
*/
|
|
1266
|
+
deleteActiveGuide(): boolean;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
interface AreaSelectionPluginOptions {
|
|
1270
|
+
rectStroke?: string;
|
|
1271
|
+
rectFill?: string;
|
|
1272
|
+
rectStrokeWidth?: number;
|
|
1273
|
+
rectOpacity?: number;
|
|
1274
|
+
enableKeyboardShortcuts?: boolean;
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* AreaSelectionPlugin
|
|
1278
|
+
* - Drag LKM over empty space draws selection rectangle (marquee) in screen coordinates
|
|
1279
|
+
* - All nodes whose client rectangles intersect the rectangle are temporarily grouped
|
|
1280
|
+
* - Click outside — temporary group is removed, nodes return to their original positions
|
|
1281
|
+
* - Ctrl+G — lock in permanent group (GroupNode through NodeManager)
|
|
1282
|
+
* - Ctrl+Shift+G — unlock selected permanent group
|
|
1283
|
+
*/
|
|
1284
|
+
declare class AreaSelectionPlugin extends Plugin {
|
|
1285
|
+
private _core?;
|
|
1286
|
+
private _layer;
|
|
1287
|
+
private _rect;
|
|
1288
|
+
private _start;
|
|
1289
|
+
private _transformer;
|
|
1290
|
+
private _selecting;
|
|
1291
|
+
private _options;
|
|
1292
|
+
constructor(options?: AreaSelectionPluginOptions);
|
|
1293
|
+
protected onAttach(core: CoreEngine): void;
|
|
1294
|
+
protected onDetach(core: CoreEngine): void;
|
|
1295
|
+
private _finalizeArea;
|
|
1296
|
+
private _clearSelection;
|
|
1297
|
+
private _getSelectionPlugin;
|
|
1298
|
+
private _rectsIntersect;
|
|
1299
|
+
private _findOwningGroupBaseNode;
|
|
1300
|
+
private _isAncestor;
|
|
1301
|
+
private _isPermanentGroupSelected;
|
|
1302
|
+
private _currentGroupNode;
|
|
1303
|
+
private _pointerInsidePermanentGroupBBox;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
interface NodeHotkeysOptions {
|
|
1307
|
+
target?: Window | Document | HTMLElement | EventTarget;
|
|
1308
|
+
ignoreEditableTargets?: boolean;
|
|
1309
|
+
}
|
|
1310
|
+
declare class NodeHotkeysPlugin extends Plugin {
|
|
1311
|
+
private _core?;
|
|
1312
|
+
private _options;
|
|
1313
|
+
private _clipboard;
|
|
1314
|
+
private _selectionPlugin?;
|
|
1315
|
+
constructor(options?: NodeHotkeysOptions);
|
|
1316
|
+
protected onAttach(core: CoreEngine): void;
|
|
1317
|
+
protected onDetach(_core: CoreEngine): void;
|
|
1318
|
+
private _onKeyDown;
|
|
1319
|
+
private _isEditableTarget;
|
|
1320
|
+
private _handleCopy;
|
|
1321
|
+
private _handleCut;
|
|
1322
|
+
private _handlePaste;
|
|
1323
|
+
private _handleDelete;
|
|
1324
|
+
private _getSelectedNodes;
|
|
1325
|
+
private _deleteNodes;
|
|
1326
|
+
private _serializeNode;
|
|
1327
|
+
private _serializeKonvaNode;
|
|
1328
|
+
private _getNodeTypeFromKonva;
|
|
1329
|
+
private _deserializeNode;
|
|
1330
|
+
private _getPastePosition;
|
|
1331
|
+
private _isPointerOnScreen;
|
|
1332
|
+
private _getScreenCenter;
|
|
1333
|
+
private _getClipboardCenter;
|
|
1334
|
+
private _computeSelectionWorldCenter;
|
|
1335
|
+
private _handleMoveUp;
|
|
1336
|
+
private _handleMoveDown;
|
|
1337
|
+
/**
|
|
1338
|
+
* Checks if the node is inside a real group (not the group itself)
|
|
1339
|
+
*/
|
|
1340
|
+
private _isNodeInsidePermanentGroup;
|
|
1341
|
+
/**
|
|
1342
|
+
* Checks if the node is inside a real group
|
|
1343
|
+
* - For group itself — do nothing (moveUp/moveDown already applied to the group)
|
|
1344
|
+
* - For node inside group — FORBIDDEN to change z-index
|
|
1345
|
+
*/
|
|
1346
|
+
private _syncGroupZIndex;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
/**
|
|
1350
|
+
* ThrottleHelper - utility for throttling (limiting the frequency of calls)
|
|
1351
|
+
*
|
|
1352
|
+
* Used to limit the frequency of operation execution to a certain number of times per second.
|
|
1353
|
+
* For example, to limit UI updates to 60 FPS (16ms) or 30 FPS (32ms).
|
|
1354
|
+
*
|
|
1355
|
+
* @example
|
|
1356
|
+
* ```typescript
|
|
1357
|
+
* private _throttle = new ThrottleHelper(16); // 60 FPS
|
|
1358
|
+
*
|
|
1359
|
+
* onMouseMove() {
|
|
1360
|
+
* if (!this._throttle.shouldExecute()) return;
|
|
1361
|
+
* // Execute expensive operation
|
|
1362
|
+
* }
|
|
1363
|
+
* ```
|
|
1364
|
+
*/
|
|
1365
|
+
declare class ThrottleHelper {
|
|
1366
|
+
private _lastTime;
|
|
1367
|
+
private _throttle;
|
|
1368
|
+
/**
|
|
1369
|
+
* @param throttleMs - minimum interval between calls in milliseconds
|
|
1370
|
+
*/
|
|
1371
|
+
constructor(throttleMs?: number);
|
|
1372
|
+
/**
|
|
1373
|
+
* Checks if the operation can be executed
|
|
1374
|
+
* @returns true if enough time has passed since the last call
|
|
1375
|
+
*/
|
|
1376
|
+
shouldExecute(): boolean;
|
|
1377
|
+
/**
|
|
1378
|
+
* Resets the timer (the next call will be executed immediately)
|
|
1379
|
+
*/
|
|
1380
|
+
reset(): void;
|
|
1381
|
+
/**
|
|
1382
|
+
* Changes the throttling interval
|
|
1383
|
+
*/
|
|
1384
|
+
setThrottle(throttleMs: number): void;
|
|
1385
|
+
/**
|
|
1386
|
+
* Returns the current throttling interval
|
|
1387
|
+
*/
|
|
1388
|
+
getThrottle(): number;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
/**
|
|
1392
|
+
* DebounceHelper - utility for debouncing (delayed execution)
|
|
1393
|
+
*
|
|
1394
|
+
* Used to group multiple calls into one through requestAnimationFrame.
|
|
1395
|
+
* Useful for optimizing UI updates - instead of updating on every event,
|
|
1396
|
+
* we update once in the next frame.
|
|
1397
|
+
*
|
|
1398
|
+
* @example
|
|
1399
|
+
* ```typescript
|
|
1400
|
+
* private _debounce = new DebounceHelper();
|
|
1401
|
+
*
|
|
1402
|
+
* onTransform() {
|
|
1403
|
+
* this._debounce.schedule(() => {
|
|
1404
|
+
* this._updateUI();
|
|
1405
|
+
* });
|
|
1406
|
+
* }
|
|
1407
|
+
* ```
|
|
1408
|
+
*/
|
|
1409
|
+
declare class DebounceHelper {
|
|
1410
|
+
private _scheduled;
|
|
1411
|
+
/**
|
|
1412
|
+
* Schedules execution of callback in the next frame
|
|
1413
|
+
* If already scheduled - ignores repeated calls
|
|
1414
|
+
*
|
|
1415
|
+
* @param callback - function to execute
|
|
1416
|
+
*/
|
|
1417
|
+
schedule(callback: () => void): void;
|
|
1418
|
+
/**
|
|
1419
|
+
* Checks if execution is scheduled
|
|
1420
|
+
*/
|
|
1421
|
+
isScheduled(): boolean;
|
|
1422
|
+
/**
|
|
1423
|
+
* Cancels scheduled execution
|
|
1424
|
+
* Note: does not cancel already scheduled requestAnimationFrame,
|
|
1425
|
+
* but prevents callback execution
|
|
1426
|
+
*/
|
|
1427
|
+
cancel(): void;
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
export { ArcNode, AreaSelectionPlugin, ArrowNode, CameraHotkeysPlugin, CameraManager, CircleNode, CoreEngine, DebounceHelper, EllipseNode, EventBus, GridPlugin, GroupNode, ImageNode, LogoPlugin, NodeHotkeysPlugin, NodeManager, Plugins, RegularPolygonNode, RingNode, RulerGuidesPlugin, RulerHighlightPlugin, RulerManagerPlugin, RulerPlugin, SelectionPlugin, ShapeNode, StarNode, TextNode, ThrottleHelper };
|