@linkurious/ogma-annotations 2.1.1 → 2.1.3

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.
@@ -1,1851 +1,271 @@
1
- import { BBox } from 'geojson';
2
- import { default as default_2 } from 'eventemitter3';
3
- import { Feature } from 'geojson';
4
- import { FeatureCollection } from 'geojson';
5
- import { Geometry } from 'geojson';
6
- import { GeometryObject } from 'geojson';
7
- import { LineString } from 'geojson';
8
- import { Node as Node_2 } from '@linkurious/ogma';
9
- import { Ogma } from '@linkurious/ogma';
10
- import { Point as Point_2 } from 'geojson';
11
- import { Point as Point_3 } from '@linkurious/ogma';
12
- import { Polygon as Polygon_2 } from 'geojson';
13
- import { Position } from 'geojson';
14
- import { Size } from '@linkurious/ogma';
15
-
16
- /**
17
- * Adjusts the brightness of a color (hex or rgba) based on its perceived luminance.
18
- * For bright colors, the adjustment is applied as darkening; for dark colors, as lightening.
19
- *
20
- * @param color - Color string in hex (#RRGGBB or #RGB) or rgba format
21
- * @param amount - Adjustment factor between -1 and 1:
22
- * - Positive values (0 to 1): lighten dark colors, darken bright colors
23
- * - Negative values (-1 to 0): darken dark colors, lighten bright colors
24
- * - 0: no change
25
- * - Example: 0.2 applies a 20% adjustment, -0.1 applies a -10% adjustment
26
- * @returns Adjusted color in rgba format
27
- */
28
- export declare function adjustColorBrightness(color: Color, amount: number): RgbaColor;
29
-
30
- /** Union type of all Annotation features */
31
- export declare type Annotation = Arrow | Box | Text_2 | Comment_2 | Polygon;
32
-
33
- /** Collection of Annotations, GeoJSON FeatureCollection */
34
- export declare interface AnnotationCollection extends FeatureCollection {
35
- features: Annotation[];
36
- }
37
-
38
- /**
39
- * Base interface for all annotation features.
40
- * @template G - Geometry type
41
- * @template P - Properties type
42
- */
43
- export declare interface AnnotationFeature<G extends GeometryObject = GeometryObject, P = AnnotationProps> extends Feature<G, P> {
44
- /** Unique identifier for the annotation */
45
- id: Id;
46
- }
47
-
48
- /** Function type to get an Annotation by its id */
49
- export declare type AnnotationGetter = (id: Id) => Annotation | undefined;
50
-
51
- export declare type AnnotationOptions = {
52
- handleSize: number;
53
- placeholder?: string;
54
- };
55
-
56
- /**
57
- * Base properties for all annotations.
58
- */
59
- export declare interface AnnotationProps {
60
- /** Type of annotation */
61
- type: AnnotationType;
62
- /** Optional style configuration */
63
- style?: unknown;
64
- }
65
-
66
- /** Types of annotations supported */
67
- export declare type AnnotationType = "arrow" | "text" | "box" | "comment" | "polygon";
68
-
69
- /**
70
- * Arrow annotation feature. Represents a directed line between two points,
71
- * can connect a textbox to a shape.
72
- */
73
- export declare interface Arrow extends AnnotationFeature<LineString, ArrowProperties> {
74
- }
75
-
76
- export declare interface ArrowProperties extends AnnotationProps {
77
- type: "arrow";
78
- style?: ArrowStyles;
79
- link?: Partial<Record<Side, ExportedLink>>;
80
- }
81
-
82
- /**
83
- * Styles specific to arrow annotations.
84
- */
85
- export declare interface ArrowStyles extends StrokeOptions {
86
- /** Tail extremity style */
87
- tail?: Extremity;
88
- /** Head extremity style */
89
- head?: Extremity;
90
- }
91
-
92
- /**
93
- * Safely cast a string to a Color type with runtime validation
94
- * @throws {Error} if the color format is invalid
95
- */
96
- export declare function asColor(color: string): Color;
97
-
98
- /**
99
- * Safely cast a string to a HexColor type with runtime validation
100
- * @throws {Error} if the color format is invalid
101
- */
102
- export declare function asHexColor(color: string): HexColor;
103
-
104
- /**
105
- * Safely cast a string to an RgbaColor type with runtime validation
106
- * @throws {Error} if the color format is invalid
107
- */
108
- export declare function asRgbaColor(color: string): RgbaColor;
109
-
110
- /**
111
- * Safely cast a string to an RgbColor type with runtime validation
112
- * @throws {Error} if the color format is invalid
113
- */
114
- export declare function asRgbColor(color: string): RgbColor;
115
-
116
- /**
117
- * Bounding box object, with the following properties:
118
- * - [0]: min x
119
- * - [1]: min y
120
- * - [2]: max x
121
- * - [3]: max y
122
- */
123
- export declare type Bounds = [number, number, number, number];
124
-
125
- /**
126
- * Box annotation feature
127
- */
128
- export declare interface Box extends AnnotationFeature<Point_2, BoxProperties> {
129
- }
130
-
131
- /**
132
- * Arrow snapped to a rectangular annotation (text, box, comment).
133
- * nx/ny are center-relative fractions multiplied by width/height:
134
- * left-center = { nx: -0.5, ny: 0 }
135
- * right-center = { nx: 0.5, ny: 0 }
136
- * center = { nx: 0, ny: 0 }
137
- */
138
- export declare type BoxMagnet = {
139
- type: "box";
140
- nx: number;
141
- ny: number;
142
- };
143
-
144
- /** Properties specific to box annotations. */
145
- export declare interface BoxProperties extends AnnotationProps {
146
- type: "box";
147
- /** Width of the box */
148
- width: number;
149
- /** Height of the box */
150
- height: number;
151
- /** Style options for the box */
152
- style?: BoxStyle;
153
- }
154
-
155
- /** Styles specific to box annotations. */
156
- export declare interface BoxStyle extends StrokeOptions {
157
- /** background color: empty for transparent #f00, yellow...*/
158
- background?: Color;
159
- /** padding around the box */
160
- padding?: number;
161
- /** border radius */
162
- borderRadius?: number;
163
- /** if true, the box scales with zoom. Default is true */
164
- scaled?: boolean;
165
- /** box shadow in CSS format, e.g. "0px 4px 6px rgba(0, 0, 0, 0.1)" */
166
- boxShadow?: string;
167
- }
168
-
169
- /**
170
- * Brighten a color for highlight purposes.
171
- * @param color - Color string in hex (#RRGGBB or #RGB) or rgba format
172
- * @returns
173
- */
174
- export declare const brighten: (color: Color) => RgbaColor;
175
-
176
- /**
177
- * Calculate optimal zoom threshold for auto-collapse based on comment dimensions
178
- *
179
- * The threshold is computed so that the comment collapses when its screen-space
180
- * size would be smaller than a minimum readable size.
181
- *
182
- * @param comment - Comment annotation
183
- * @param minReadableWidth - Minimum readable width in pixels (default: 80)
184
- * @returns Zoom threshold below which comment should collapse
185
- *
186
- * @example
187
- * // A 200px wide comment with minReadable=80 will collapse at zoom < 0.4
188
- * // because 200 * 0.4 = 80
189
- */
190
- export declare function calculateCommentZoomThreshold(comment: Comment_2, minReadableWidth?: number): number;
191
-
192
- /**
193
- * Check if arrow endpoint can be detached from its target
194
- *
195
- * Always returns true since arrow endpoints can be freely retargeted,
196
- * even for comment arrows. The comment is typically on the start side.
197
- *
198
- * @param _arrow - The arrow feature (unused, kept for API consistency)
199
- * @returns Always true - arrow ends can be detached
200
- *
201
- * @example
202
- * ```typescript
203
- * if (canDetachArrowEnd(arrow)) {
204
- * // Allow user to drag arrow end point
205
- * }
206
- * ```
207
- */
208
- export declare function canDetachArrowEnd(_arrow: Arrow): boolean;
209
-
210
- /**
211
- * Check if arrow start point can be detached from its source
212
- *
213
- * Returns false for arrows originating FROM comments, since comment arrows
214
- * must always remain attached to the comment on their start side.
215
- *
216
- * @param arrow - The arrow feature
217
- * @returns True if arrow start can be detached
218
- *
219
- * @example
220
- * ```typescript
221
- * if (canDetachArrowStart(arrow)) {
222
- * // Allow user to drag arrow start point
223
- * } else {
224
- * // Keep arrow start locked to comment
225
- * }
226
- * ```
227
- */
228
- export declare function canDetachArrowStart(arrow: Arrow): boolean;
229
-
230
- /** Event related to a single annotation feature */
231
- export declare interface ClickEvent {
232
- /** Annotation ID involved in the event */
233
- id?: Id;
234
- /** Mouse position in pixel coordinates */
235
- position: {
236
- x: number;
237
- y: number;
238
- };
239
- }
240
-
241
- export declare type ClientMouseEvent = {
242
- clientX: number;
243
- clientY: number;
244
- };
245
-
246
- export declare function clientToContainerPosition(evt: ClientMouseEvent, container?: HTMLElement | null): {
247
- x: number;
248
- y: number;
249
- };
250
-
251
- /**
252
- * Any valid color format
253
- */
254
- export declare type Color = HexColor | RgbColor | RgbaColor | "transparent" | "none" | string;
255
-
256
- export declare function colorToRgba(color: Color, alpha: number): RgbaColor;
257
-
258
- /**
259
- * Comment annotation type
260
- * Geometry: Point (center position of comment box/icon)
261
- *
262
- * Note: Arrows are stored separately in Arrow features.
263
- * Arrows reference comments via their link.start or link.end properties.
264
- */
265
- declare interface Comment_2 extends AnnotationFeature<Point_2, CommentProps> {
266
- }
267
- export { Comment_2 as Comment }
268
-
269
- export declare const COMMENT_MODE_COLLAPSED = "collapsed";
270
-
271
- export declare const COMMENT_MODE_EXPANDED = "expanded";
272
-
273
- /**
274
- * Properties for Comment annotations
275
- *
276
- * Comments are specialized annotations that:
277
- * - Always maintain fixed screen-space size
278
- * - Always have at least one arrow pointing TO them
279
- * - Can be collapsed (icon) or expanded (text box)
280
- * - Support multiple arrows pointing to them
281
- */
282
- export declare interface CommentProps extends AnnotationProps {
283
- type: "comment";
284
- /** Text content (similar to text annotation) */
285
- content: string;
286
- /** Display mode: collapsed (icon) or expanded (text box) */
287
- mode: typeof COMMENT_MODE_COLLAPSED | typeof COMMENT_MODE_EXPANDED;
288
- /** Width in expanded mode (pixels) */
289
- width: number;
290
- /** Height (auto-grows with content, pixels) */
291
- height: number;
292
- /** Optional metadata */
293
- author?: string;
294
- timestamp?: Date;
295
- /** Styling */
296
- style?: CommentStyle;
297
- }
298
-
299
- /**
300
- * Style configuration for Comment annotations
301
- */
302
- export declare interface CommentStyle extends TextStyle {
303
- /** Background color for collapsed icon (default: "#FFD700") */
304
- iconColor?: Color;
305
- /** Icon to display when collapsed (default: "💬") */
306
- iconSymbol?: string;
307
- /** Border color for collapsed icon */
308
- iconBorderColor?: Color;
309
- /** Border width for collapsed icon */
310
- iconBorderWidth?: number;
311
- /** Minimum height (default: 60px) */
312
- minHeight?: number;
313
- /** Maximum height before scrolling (default: 480px, undefined = no limit) */
314
- maxHeight?: number;
315
- /** Size when collapsed (default: 32px) */
316
- iconSize?: number;
317
- /** Zoom threshold below which comment auto-collapses (default: 0.5) */
318
- collapseZoomThreshold?: number;
319
- /** Show "send" button in edit mode (default: true) */
320
- showSendButton?: boolean;
321
- /** Auto-grow height with content (default: true) */
322
- autoGrow?: boolean;
323
- /** Show drop shadow on comment box (default: true) */
324
- shadow?: boolean;
325
- /** Expand to full width when selected (default: false) */
326
- expandOnSelect?: boolean;
327
- }
328
-
329
- /**
330
- * Main controller class for managing annotations.
331
- * It manages rendering and editing of annotations.
332
- */
333
- export declare class Control extends default_2<FeatureEvents> {
334
- private ogma;
335
- private store;
336
- private renderers;
337
- private interactions;
338
- private editor;
339
- private links;
340
- private index;
341
- private drawing;
342
- private snapping;
343
- private selectionManager;
344
- private historyManager;
345
- private updateManager;
346
- private commentManager;
347
- constructor(ogma: Ogma, options?: Partial<ControllerOptions>);
348
- private initializeRenderers;
349
- private setupEvents;
350
- private onRotate;
351
- private onZoom;
352
- private onLayout;
353
- /**
354
- * Set the options for the controller
355
- * @param options new Options
356
- * @returns the updated options
357
- */
358
- setOptions(options?: Partial<ControllerOptions>): {
359
- showSendButton: boolean;
360
- showEditButton: boolean;
361
- sendButtonIcon: string;
362
- editButtonIcon: string;
363
- minArrowHeight: number;
364
- maxArrowHeight: number;
365
- detectMargin: number;
366
- magnetRadius: number;
367
- magnetHandleRadius: number;
368
- textPlaceholder: string;
369
- };
370
- /**
371
- * Add an annotation to the controller
372
- * @param annotation The annotation to add
373
- */
374
- add(annotation: Annotation | AnnotationCollection): this;
375
- /**
376
- * Remove an annotation or an array of annotations from the controller
377
- * @param annotation The annotation(s) to remove
378
- */
379
- remove(annotation: Annotation | AnnotationCollection): this;
380
- /**
381
- * Undo the last change
382
- * @returns true if undo was successful, false if no changes to undo
383
- */
384
- undo(): boolean;
385
- /**
386
- * Redo the last undone change
387
- * @returns true if redo was successful, false if no changes to redo
388
- */
389
- redo(): boolean;
390
- /**
391
- * Check if there are changes to undo
392
- * @returns true if undo is possible
393
- */
394
- canUndo(): boolean;
395
- /**
396
- * Check if there are changes to redo
397
- * @returns true if redo is possible
398
- */
399
- canRedo(): boolean;
400
- /**
401
- * Clear the undo/redo history
402
- */
403
- clearHistory(): void;
404
- /**
405
- * Get all annotations in the controller
406
- * @returns A FeatureCollection containing all annotations
407
- */
408
- getAnnotations(): AnnotationCollection;
409
- /**
410
- * Select one or more annotations by id
411
- * @param annotations The id(s) of the annotation(s) to select
412
- * @returns this for chaining
413
- */
414
- select(annotations: Id | Id[]): this;
415
- /**
416
- * Unselect one or more annotations, or all if no ids provided
417
- * @param annotations The id(s) of the annotation(s) to unselect, or undefined to unselect all
418
- * @returns this for chaining
419
- */
420
- unselect(annotations?: Id | Id[]): this;
421
- /**
422
- * Cancel the current drawing operation
423
- * @returns this for chaining
424
- */
425
- cancelDrawing(): this;
426
- /**
427
- * Enable arrow drawing mode - the recommended way to add arrows.
428
- *
429
- * Call this method when the user clicks an "Add Arrow" button. The control will:
430
- * 1. Wait for the next mousedown event
431
- * 2. Create an arrow at that position with the specified style
432
- * 3. Start the interactive drawing process
433
- * 4. Clean up automatically when done
434
- *
435
- * **This is the recommended API for 99% of use cases.** Only use `startArrow()`
436
- * if you need to implement custom mouse handling or positioning logic.
437
- *
438
- * @example
439
- * ```ts
440
- * addArrowButton.addEventListener('click', () => {
441
- * control.enableArrowDrawing({ strokeColor: '#3A03CF', strokeWidth: 2 });
442
- * });
443
- * ```
444
- *
445
- * @param style Arrow style options
446
- * @returns this for chaining
447
- * @see startArrow for low-level programmatic control
448
- */
449
- enableArrowDrawing(style?: Partial<Arrow["properties"]["style"]>): this;
450
- /**
451
- * Enable text drawing mode - the recommended way to add text annotations.
452
- *
453
- * Call this method when the user clicks an "Add Text" button. The control will:
454
- * 1. Wait for the next mousedown event
455
- * 2. Create a text box at that position with the specified style
456
- * 3. Start the interactive drawing/editing process
457
- * 4. Clean up automatically when done
458
- *
459
- * **This is the recommended API for 99% of use cases.** Only use `startText()`
460
- * if you need to implement custom mouse handling or positioning logic.
461
- *
462
- * @example
463
- * ```ts
464
- * addTextButton.addEventListener('click', () => {
465
- * control.enableTextDrawing({ color: '#3A03CF', fontSize: 24 });
466
- * });
467
- * ```
468
- *
469
- * @param style Text style options
470
- * @returns this for chaining
471
- * @see startText for low-level programmatic control
472
- */
473
- enableTextDrawing(style?: Partial<Text_2["properties"]["style"]>): this;
474
- /**
475
- * Enable box drawing mode - the recommended way to add boxes.
476
- *
477
- * Call this method when the user clicks an "Add Box" button. The control will:
478
- * 1. Wait for the next mousedown event
479
- * 2. Create a box at that position with the specified style
480
- * 3. Start the interactive drawing process (drag to size)
481
- * 4. Clean up automatically when done
482
- *
483
- * **This is the recommended API for 99% of use cases.** Only use `startBox()`
484
- * if you need to implement custom mouse handling or positioning logic.
485
- *
486
- * @example
487
- * ```ts
488
- * addBoxButton.addEventListener('click', () => {
489
- * control.enableBoxDrawing({ background: '#EDE6FF', borderRadius: 8 });
490
- * });
491
- * ```
492
- *
493
- * @param style Box style options
494
- * @returns this for chaining
495
- * @see startBox for low-level programmatic control
496
- */
497
- enableBoxDrawing(style?: Partial<Box["properties"]["style"]>): this;
498
- /**
499
- * Enable polygon drawing mode - the recommended way to add polygons.
500
- *
501
- * Call this method when the user clicks an "Add Polygon" button. The control will:
502
- * 1. Wait for the next mousedown event
503
- * 2. Create a polygon starting at that position with the specified style
504
- * 3. Start the interactive drawing process (click points to draw shape)
505
- * 4. Clean up automatically when done
506
- *
507
- * **This is the recommended API for 99% of use cases.** Only use `startPolygon()`
508
- * if you need to implement custom mouse handling or positioning logic.
509
- *
510
- * @example
511
- * ```ts
512
- * addPolygonButton.addEventListener('click', () => {
513
- * control.enablePolygonDrawing({ strokeColor: '#3A03CF', background: 'rgba(58, 3, 207, 0.15)' });
514
- * });
515
- * ```
516
- *
517
- * @param style Polygon style options
518
- * @returns this for chaining
519
- * @see startPolygon for low-level programmatic control
520
- */
521
- enablePolygonDrawing(style?: Partial<Polygon["properties"]["style"]>): this;
522
- /**
523
- * Enable comment drawing mode - the recommended way to add comments.
524
- *
525
- * Call this method when the user clicks an "Add Comment" button. The control will:
526
- * 1. Wait for the next mousedown event
527
- * 2. Create a comment with an arrow pointing to that position
528
- * 3. Smart positioning: automatically finds the best placement for the comment box
529
- * 4. Start the interactive editing process
530
- * 5. Clean up automatically when done
531
- *
532
- * **This is the recommended API for 99% of use cases.** Only use `startComment()`
533
- * if you need to implement custom mouse handling or positioning logic.
534
- *
535
- * @example
536
- * ```ts
537
- * addCommentButton.addEventListener('click', () => {
538
- * control.enableCommentDrawing({
539
- * commentStyle: { color: '#3A03CF', background: '#EDE6FF' },
540
- * arrowStyle: { strokeColor: '#3A03CF', head: 'halo-dot' }
541
- * });
542
- * });
543
- * ```
544
- *
545
- * @param options Drawing options including offsets and styles
546
- * @param options.offsetX Manual X offset for comment placement (overrides smart positioning)
547
- * @param options.offsetY Manual Y offset for comment placement (overrides smart positioning)
548
- * @param options.commentStyle Style options for the comment box
549
- * @param options.arrowStyle Style options for the arrow
550
- * @returns this for chaining
551
- * @see startComment for low-level programmatic control
552
- */
553
- enableCommentDrawing(options?: {
554
- offsetX?: number;
555
- offsetY?: number;
556
- commentStyle?: Partial<CommentProps>;
557
- arrowStyle?: Partial<ArrowProperties>;
558
- }): this;
559
- /**
560
- * Enable sticky note drawing mode - drops a plain, resizable text box
561
- * (empty content, "Quick note…" ghost placeholder, no connector arrow)
562
- * like a Miro sticky note, unlike `enableCommentDrawing`. It's a regular
563
- * `text` annotation, so it's placed the same interactive way as
564
- * `enableBoxDrawing`/`enableTextDrawing`: click for a default-size square,
565
- * or drag to size it - either way it keeps the usual corner/edge drag
566
- * handles to resize it afterward.
567
- *
568
- * Call this method when the user clicks an "Add sticky note" button. The
569
- * control will:
570
- * 1. Wait for the next mousedown event
571
- * 2. Create the note at that position and start the interactive
572
- * corner-drag, already selected
573
- * 3. On release: a plain click (no drag) gets a default square size, a
574
- * drag gets sized to match instead - either way it drops straight
575
- * into editing (the placeholder is just ghost text, so typing
576
- * immediately replaces it)
577
- * 4. Clean up automatically when done
578
- *
579
- * @example
580
- * ```ts
581
- * addStickyNoteButton.addEventListener('click', () => {
582
- * control.enableStickyNoteDrawing({ background: '#FFEB99' });
583
- * });
584
- * ```
585
- *
586
- * @param style Sticky note style options (merged over the sticky note defaults)
587
- * @returns this for chaining
588
- * @see startStickyNote for low-level programmatic control
589
- */
590
- enableStickyNoteDrawing(style?: Partial<Text_2["properties"]["style"]>): this;
591
- /**
592
- * Enable erase mode: every click on an annotation deletes it immediately.
593
- * Stays armed across multiple clicks until `disableEraseMode()` is called,
594
- * or another drawing tool is enabled / `cancelDrawing()` is called.
595
- *
596
- * @returns this for chaining
597
- * @see disableEraseMode to turn erase mode off
598
- */
599
- enableEraseMode(): this;
600
- /** Turn erase mode off. No-op if it isn't active. */
601
- disableEraseMode(): this;
602
- /** Whether erase mode is currently active. */
603
- isEraseModeActive(): boolean;
604
- /**
605
- * Place a pre-created annotation by moving it with the cursor.
606
- * The annotation follows the mouse until the user clicks to place it.
607
- * Press Escape to cancel.
608
- *
609
- * @param annotation The text or box annotation to place
610
- * @returns this for chaining
611
- */
612
- enablePlacement(annotation: Text_2 | Box): this;
613
- /**
614
- * **Advanced API:** Programmatically start drawing a comment at specific coordinates.
615
- *
616
- * This is a low-level method that gives you full control over the drawing process.
617
- * You must handle mouse events and create the comment object yourself.
618
- *
619
- * **For most use cases, use `enableCommentDrawing()` instead** - it handles all
620
- * mouse events and annotation creation automatically.
621
- *
622
- * Use this method only when you need:
623
- * - Custom mouse event handling (e.g., custom cursors, right-click menus)
624
- * - Programmatic placement without user interaction
625
- * - Integration with custom UI frameworks
626
- *
627
- * @example
628
- * ```ts
629
- * // Custom cursor example
630
- * ogma.setOptions({ cursor: { default: 'crosshair' } });
631
- * ogma.events.once('mousedown', (evt) => {
632
- * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
633
- * const comment = createComment(x, y, 'My comment', { color: '#3A03CF' });
634
- * control.startComment(x, y, comment);
635
- * });
636
- * ```
637
- *
638
- * @param x X coordinate to start drawing
639
- * @param y Y coordinate to start drawing
640
- * @param comment The comment annotation to add
641
- * @param options Drawing options including offsets and styles
642
- * @returns this for chaining
643
- * @see enableCommentDrawing for the recommended high-level API
644
- */
645
- startComment(x: number, y: number, comment: Comment_2, options?: {
646
- offsetX?: number;
647
- offsetY?: number;
648
- commentStyle?: Partial<CommentProps>;
649
- arrowStyle?: Partial<ArrowProperties>;
650
- }): this;
651
- /**
652
- * **Advanced API:** Programmatically start drawing a sticky note at
653
- * specific coordinates - same interactive corner-drag as `startBox`.
654
- * You must handle mouse events yourself (or immediately release/complete
655
- * it via the same events `enableStickyNoteDrawing` would).
656
- *
657
- * **For most use cases, use `enableStickyNoteDrawing()` instead.**
658
- *
659
- * @param x X coordinate for the note's top-left corner
660
- * @param y Y coordinate for the note's top-left corner
661
- * @param style Sticky note style options
662
- * @returns this for chaining
663
- * @see enableStickyNoteDrawing for the recommended high-level API
664
- */
665
- startStickyNote(x: number, y: number, style?: Partial<Text_2["properties"]["style"]>): this;
666
- /**
667
- * **Advanced API:** Programmatically start drawing a box at specific coordinates.
668
- *
669
- * This is a low-level method that gives you full control over the drawing process.
670
- * You must handle mouse events and optionally create the box object yourself.
671
- *
672
- * **For most use cases, use `enableBoxDrawing()` instead** - it handles all
673
- * mouse events and annotation creation automatically.
674
- *
675
- * Use this method only when you need:
676
- * - Custom mouse event handling (e.g., custom cursors, right-click menus)
677
- * - Programmatic placement without user interaction
678
- * - Integration with custom UI frameworks
679
- *
680
- * @example
681
- * ```ts
682
- * // Custom cursor example
683
- * ogma.setOptions({ cursor: { default: 'crosshair' } });
684
- * ogma.events.once('mousedown', (evt) => {
685
- * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
686
- * const box = createBox(x, y, 100, 50, { background: '#EDE6FF' });
687
- * control.startBox(x, y, box);
688
- * });
689
- * ```
690
- *
691
- * @param x X coordinate for the box origin
692
- * @param y Y coordinate for the box origin
693
- * @param box The box annotation to add (optional, will be created if not provided)
694
- * @returns this for chaining
695
- * @see enableBoxDrawing for the recommended high-level API
696
- */
697
- startBox(x: number, y: number, box?: Box): this;
698
- /**
699
- * **Advanced API:** Programmatically start drawing an arrow at specific coordinates.
700
- *
701
- * This is a low-level method that gives you full control over the drawing process.
702
- * You must handle mouse events and optionally create the arrow object yourself.
703
- *
704
- * **For most use cases, use `enableArrowDrawing()` instead** - it handles all
705
- * mouse events and annotation creation automatically.
706
- *
707
- * Use this method only when you need:
708
- * - Custom mouse event handling (e.g., custom cursors, right-click menus)
709
- * - Programmatic placement without user interaction
710
- * - Integration with custom UI frameworks
711
- *
712
- * @example
713
- * ```ts
714
- * // Custom cursor example
715
- * ogma.setOptions({ cursor: { default: 'crosshair' } });
716
- * ogma.events.once('mousedown', (evt) => {
717
- * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
718
- * const arrow = createArrow(x, y, x, y, { strokeColor: '#3A03CF' });
719
- * control.startArrow(x, y, arrow);
720
- * });
721
- * ```
722
- *
723
- * @param x X coordinate for the arrow start
724
- * @param y Y coordinate for the arrow start
725
- * @param arrow The arrow annotation to add (optional, will be created if not provided)
726
- * @returns this for chaining
727
- * @see enableArrowDrawing for the recommended high-level API
728
- */
729
- startArrow(x: number, y: number, arrow?: Arrow): this;
730
- /**
731
- * **Advanced API:** Programmatically start drawing a text annotation at specific coordinates.
732
- *
733
- * This is a low-level method that gives you full control over the drawing process.
734
- * You must handle mouse events and optionally create the text object yourself.
735
- *
736
- * **For most use cases, use `enableTextDrawing()` instead** - it handles all
737
- * mouse events and annotation creation automatically.
738
- *
739
- * Use this method only when you need:
740
- * - Custom mouse event handling (e.g., custom cursors, right-click menus)
741
- * - Programmatic placement without user interaction
742
- * - Integration with custom UI frameworks
743
- *
744
- * @example
745
- * ```ts
746
- * // Custom cursor example
747
- * ogma.setOptions({ cursor: { default: 'crosshair' } });
748
- * ogma.events.once('mousedown', (evt) => {
749
- * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
750
- * const text = createText(x, y, 0, 0, 'Hello', { color: '#3A03CF' });
751
- * control.startText(x, y, text);
752
- * });
753
- * ```
754
- *
755
- * @param x X coordinate for the text
756
- * @param y Y coordinate for the text
757
- * @param text The text annotation to add (optional, will be created if not provided)
758
- * @returns this for chaining
759
- * @see enableTextDrawing for the recommended high-level API
760
- */
761
- startText(x: number, y: number, text?: Text_2): this;
762
- /**
763
- * **Advanced API:** Programmatically start drawing a polygon at specific coordinates.
764
- *
765
- * This is a low-level method that gives you full control over the drawing process.
766
- * You must handle mouse events and create the polygon object yourself.
767
- *
768
- * **For most use cases, use `enablePolygonDrawing()` instead** - it handles all
769
- * mouse events and annotation creation automatically.
770
- *
771
- * Use this method only when you need:
772
- * - Custom mouse event handling (e.g., custom cursors, right-click menus)
773
- * - Programmatic placement without user interaction
774
- * - Integration with custom UI frameworks
775
- *
776
- * @example
777
- * ```ts
778
- * // Custom cursor example
779
- * ogma.setOptions({ cursor: { default: 'crosshair' } });
780
- * ogma.events.once('mousedown', (evt) => {
781
- * const { x, y } = ogma.view.screenToGraphCoordinates(evt);
782
- * const polygon = createPolygon([[[x, y]]], { strokeColor: '#3A03CF' });
783
- * control.startPolygon(x, y, polygon);
784
- * });
785
- * ```
786
- *
787
- * @param x X coordinate to start drawing
788
- * @param y Y coordinate to start drawing
789
- * @param polygon The polygon annotation to add
790
- * @returns this for chaining
791
- * @see enablePolygonDrawing for the recommended high-level API
792
- */
793
- startPolygon(x: number, y: number, polygon: Polygon): this;
794
- /**
795
- * Get the currently selected annotations as a collection
796
- * @returns A FeatureCollection of selected annotations
797
- */
798
- getSelectedAnnotations(): AnnotationCollection;
799
- /**
800
- * Get the first selected annotation (for backwards compatibility)
801
- * @returns The currently selected annotation, or null if none selected
802
- */
803
- getSelected(): Annotation | null;
804
- /**
805
- * Get a specific annotation by id
806
- * @param id The id of the annotation to retrieve
807
- * @returns The annotation with the given id, or undefined if not found
808
- */
809
- getAnnotation<T = Annotation>(id: Id): T | undefined;
810
- /**
811
- * Scale an annotation by a given factor around an origin point
812
- * @param id The id of the annotation to scale
813
- * @param scale The scale factor
814
- * @param ox Origin x coordinate
815
- * @param oy Origin y coordinate
816
- * @returns this for chaining
817
- */
818
- setScale(id: Id, scale: number, ox: number, oy: number): this;
819
- /**
820
- * Toggle a comment between collapsed and expanded mode
821
- * @param id The id of the comment to toggle
822
- * @returns this for chaining
823
- */
824
- toggleComment(id: Id): this;
825
- /**
826
- * Destroy the controller and its elements
827
- */
828
- destroy(): void;
829
- /**
830
- * Update the style of the annotation with the given id
831
- * @param id The id of the annotation to update
832
- * @param style The new style
833
- */
834
- updateStyle<A extends Annotation>(id: Id, style: A["properties"]["style"]): this;
835
- /**
836
- * Update an annotation with partial updates
837
- *
838
- * This method allows you to update any properties of an annotation, including
839
- * geometry, properties, and style. Updates are merged with existing data.
840
- *
841
- * @param annotation Partial annotation object with id and properties to update
842
- * @returns this for chaining
843
- *
844
- * @example
845
- * ```ts
846
- * // Update arrow geometry
847
- * controller.update({
848
- * id: arrowId,
849
- * geometry: {
850
- * type: 'LineString',
851
- * coordinates: [[0, 0], [200, 200]]
852
- * }
853
- * });
854
- *
855
- * // Update text content and position
856
- * controller.update({
857
- * id: textId,
858
- * geometry: {
859
- * type: 'Point',
860
- * coordinates: [100, 100]
861
- * },
862
- * properties: {
863
- * content: 'Updated text'
864
- * }
865
- * });
866
- *
867
- * // Update style only (prefer updateStyle for style-only updates)
868
- * controller.update({
869
- * id: boxId,
870
- * properties: {
871
- * style: {
872
- * background: '#ff0000'
873
- * }
874
- * }
875
- * });
876
- * ```
877
- */
878
- update<A extends Annotation>(annotation: DeepPartial<A> & {
879
- id: Id;
880
- }): this;
881
- /**
882
- * Attach an arrow to a node at the specified side
883
- * @param arrowId
884
- * @param targetNode
885
- * @param side
886
- */
887
- link(arrowId: Id, targetNode: Node_2, side: Side): this;
888
- /**
889
- * Attach an arrow to an annotation at the specified side
890
- * @param arrowId
891
- * @param target
892
- * @param side
893
- */
894
- link(arrowId: Id, target: Id, side: Side): this;
895
- isDrawing(): boolean;
896
- }
897
-
898
- /**
899
- * Options for the annotations control
900
- */
901
- export declare type ControllerOptions = {
902
- /**
903
- * The radius in which arrows are attracted
904
- */
905
- magnetRadius: number;
906
- /**
907
- * The margin in which the Texts are detected when looking for magnet points
908
- */
909
- detectMargin: number;
910
- /**
911
- * Display size of the magnet point
912
- */
913
- magnetHandleRadius: number;
914
- /**
915
- * Placeholder for the text input
916
- */
917
- textPlaceholder: string;
918
- /**
919
- * Show send button in text editor
920
- */
921
- showSendButton: boolean;
922
- /**
923
- * Show edit button in text editor
924
- */
925
- showEditButton: boolean;
926
- /**
927
- * SVG icon for the send button in text editor
928
- * Should be a complete SVG string (e.g., '<svg>...</svg>')
929
- */
930
- sendButtonIcon: string;
931
- /**
932
- * SVG icon for the edit button in text editor
933
- * Should be a complete SVG string (e.g., '<svg>...</svg>')
934
- */
935
- editButtonIcon: string;
936
- /**
937
- * Minimum height of the arrow in units
938
- */
939
- minArrowHeight: number;
940
- /**
941
- * Maximum height of the arrow in units
942
- */
943
- maxArrowHeight: number;
944
- };
945
-
946
- export declare const createArrow: (x0?: number, y0?: number, x1?: number, y1?: number, styles?: {
947
- /** Tail extremity style */
948
- tail?: Extremity | undefined;
949
- /** Head extremity style */
950
- head?: Extremity | undefined;
951
- strokeType?: StrokeType | undefined;
952
- strokeColor?: string | undefined;
953
- strokeWidth?: number | undefined;
954
- }) => Arrow;
955
-
956
- export declare const createBox: (x?: number, y?: number, width?: number, height?: number, styles?: Partial<BoxStyle>) => Box;
957
-
958
- /**
959
- * Create a new Comment annotation
960
- *
961
- * @param x - X coordinate of the comment box/icon center
962
- * @param y - Y coordinate of the comment box/icon center
963
- * @param content - Text content
964
- * @param options - Optional configuration
965
- * @returns New Comment feature
966
- *
967
- * @important This creates ONLY the comment box without an arrow. Since comments
968
- * require at least one arrow, you should use {@link createCommentWithArrow}
969
- * instead for programmatic creation. This function is primarily used internally
970
- * by the interactive drawing handlers.
971
- *
972
- * @see createCommentWithArrow for creating comments programmatically
973
- */
974
- export declare function createComment(x: number, y: number, content: string, options?: Partial<CommentProps>): Comment_2;
975
-
976
- /**
977
- * Create a comment with an arrow pointing to a target location
978
- *
979
- * This is the recommended way to create comments programmatically, as it ensures
980
- * that the comment always has at least one arrow (which is required).
981
- *
982
- * @param targetX - X coordinate where the arrow points to
983
- * @param targetY - Y coordinate where the arrow points to
984
- * @param commentX - X coordinate of the comment box center
985
- * @param commentY - Y coordinate of the comment box center
986
- * @param content - Text content of the comment
987
- * @param options - Optional configuration
988
- * @param options.commentStyle - Style options for the comment
989
- * @param options.arrowStyle - Style options for the arrow
990
- * @returns Object containing the comment and arrow features
991
- *
992
- * @example
993
- * ```typescript
994
- * import { createCommentWithArrow } from '@linkurious/ogma-annotations';
995
- *
996
- * // Create a comment pointing to a node at (100, 100)
997
- * const { comment, arrow } = createCommentWithArrow(
998
- * 100, 100, // Target position (where arrow points)
999
- * 300, 50, // Comment position
1000
- * "Important node!", // Comment text
1001
- * {
1002
- * commentStyle: {
1003
- * style: {
1004
- * background: "#FFFACD",
1005
- * color: "#333"
1006
- * }
1007
- * },
1008
- * arrowStyle: {
1009
- * strokeColor: "#3498db",
1010
- * strokeWidth: 2,
1011
- * head: "arrow"
1012
- * }
1013
- * }
1014
- * );
1015
- *
1016
- * // Add both to the controller
1017
- * controller.add(comment);
1018
- * controller.add(arrow);
1019
- *
1020
- * // The arrow is automatically linked to the comment
1021
- * ```
1022
- */
1023
- export declare function createCommentWithArrow(targetX: number, targetY: number, commentX: number, commentY: number, content?: string, options?: {
1024
- commentStyle?: Partial<CommentProps>;
1025
- arrowStyle?: Partial<ArrowStyles>;
1026
- }): {
1027
- comment: Comment_2;
1028
- arrow: Arrow;
1029
- };
1030
-
1031
- /**
1032
- * Create a polygon annotation
1033
- */
1034
- export declare function createPolygon(coordinates: [number, number][][], properties?: Partial<Omit<PolygonProperties, "type">> & {
1035
- id?: Id;
1036
- }): Polygon;
1037
-
1038
- /** @private */
1039
- export declare function createSVGElement<T extends SVGElement>(tag: string): T;
1040
-
1041
- export declare const createText: (x?: number, y?: number, width?: number, height?: number, content?: string, styles?: Partial<TextStyle>) => Text_2;
1042
-
1043
- /** @private */
1044
- export declare type Cursor = "default" | "pointer" | "move" | "grab" | "grabbing" | "auto" | "resize" | "col-resize" | "row-resize" | "all-scroll" | "n-resize" | "e-resize" | "s-resize" | "w-resize" | "ne-resize" | "nw-resize" | "se-resize" | "sw-resize" | "ew-resize" | "ns-resize" | "nesw-resize" | "nwse-resize" | "alias" | "crosshair";
1045
-
1046
- /** @private */
1047
- export declare const cursors: Record<string, Cursor>;
1048
-
1049
- /**
1050
- * Darken a color for highlight purposes.
1051
- * @param color - Color string in hex (#RRGGBB or #RGB) or rgba format
1052
- * @returns
1053
- */
1054
- export declare const darken: (color: Color) => RgbaColor;
1055
-
1056
- export declare const DATA_ATTR = "data-annotation";
1057
-
1058
- /** @private */
1059
- export declare const debounce: <F extends (...args: Parameters<F>) => ReturnType<F>>(func: F, waitFor: number) => (...args: Parameters<F>) => void;
1060
-
1061
- /** @private */
1062
- export declare function debounceTail<T, A extends unknown[]>(fn: (this: T, ...args: A) => void, delay: number): (this: T, ...args: A) => void;
1063
-
1064
- export declare type DeepPartial<T> = {
1065
- [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
1066
- };
1067
-
1068
- export declare const DEFAULT_EDIT_ICON = "<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M12 6.00015H7.33333C6.97971 6.00015 6.64057 6.14063 6.39052 6.39068C6.14048 6.64072 6 6.97986 6 7.33348V16.6668C6 17.0204 6.14048 17.3596 6.39052 17.6096C6.64057 17.8597 6.97971 18.0002 7.33333 18.0002H16.6667C17.0203 18.0002 17.3594 17.8597 17.6095 17.6096C17.8595 17.3596 18 17.0204 18 16.6668V12.0002M16.25 5.75015C16.5152 5.48493 16.8749 5.33594 17.25 5.33594C17.6251 5.33594 17.9848 5.48493 18.25 5.75015C18.5152 6.01537 18.6642 6.37508 18.6642 6.75015C18.6642 7.12522 18.5152 7.48493 18.25 7.75015L12.2413 13.7595C12.083 13.9176 11.8875 14.0334 11.6727 14.0962L9.75733 14.6562C9.69997 14.6729 9.63916 14.6739 9.58127 14.6591C9.52339 14.6442 9.47055 14.6141 9.4283 14.5719C9.38604 14.5296 9.35593 14.4768 9.3411 14.4189C9.32627 14.361 9.32727 14.3002 9.344 14.2428L9.904 12.3275C9.96702 12.1129 10.083 11.9175 10.2413 11.7595L16.25 5.75015Z\" stroke=\"#1A70E5\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>\n";
1069
-
1070
- /** Default send button icon (paper plane) */
1071
- export declare const DEFAULT_SEND_ICON = "<svg viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M22 2L11 13M22 2L15 22L11 13M22 2L2 9L11 13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n</svg>";
1072
-
1073
- /**
1074
- * Default options for creating new Arrow annotations.
1075
- * Contains the default arrow structure with {@link defaultArrowStyle}.
1076
- */
1077
- export declare const defaultArrowOptions: Arrow;
1078
-
1079
- /**
1080
- * Default style configuration for arrow annotations.
1081
- *
1082
- * @example
1083
- * ```typescript
1084
- * {
1085
- * strokeType: "plain",
1086
- * strokeColor: "#202020",
1087
- * strokeWidth: 1,
1088
- * head: "none",
1089
- * tail: "none"
1090
- * }
1091
- * ```
1092
- */
1093
- export declare const defaultArrowStyle: ArrowStyles;
1094
-
1095
- /**
1096
- * Default options for creating new Box annotations.
1097
- * Contains the default box structure with {@link defaultBoxStyle}.
1098
- */
1099
- export declare const defaultBoxOptions: Box;
1100
-
1101
- /**
1102
- * Default style configuration for box annotations.
1103
- *
1104
- * @example
1105
- * ```typescript
1106
- * {
1107
- * background: "#f5f5f5",
1108
- * strokeWidth: 0,
1109
- * borderRadius: 8,
1110
- * padding: 16,
1111
- * strokeType: "plain"
1112
- * }
1113
- * ```
1114
- */
1115
- export declare const defaultBoxStyle: BoxStyle;
1116
-
1117
- /**
1118
- * Default options for creating new Comments.
1119
- * Contains the default comment configuration with {@link defaultCommentStyle}.
1120
- *
1121
- * @example
1122
- * ```typescript
1123
- * {
1124
- * mode: "expanded",
1125
- * width: 200,
1126
- * height: 120,
1127
- * content: "",
1128
- * style: defaultCommentStyle
1129
- * }
1130
- * ```
1131
- */
1132
- export declare const defaultCommentOptions: Partial<CommentProps>;
1133
-
1134
- /**
1135
- * Default style for Comment annotations
1136
- *
1137
- * @example
1138
- * ```typescript
1139
- * {
1140
- * // Box styling
1141
- * background: "#FFFACD", // Light yellow (sticky note color)
1142
- * padding: 8,
1143
- * borderRadius: 4,
1144
- * strokeColor: "#DDD",
1145
- * strokeWidth: 1,
1146
- * strokeType: "plain",
1147
- *
1148
- * // Icon styling (collapsed mode)
1149
- * iconColor: "#FFCB2F", // Gold
1150
- * iconSymbol: "💬",
1151
- * iconBorderColor: "#aaa",
1152
- * iconBorderWidth: 2,
1153
- *
1154
- * // Size properties
1155
- * minHeight: 60,
1156
- * iconSize: 32,
1157
- *
1158
- * // Text styling
1159
- * color: "#333",
1160
- * font: "Arial, sans-serif",
1161
- * fontSize: 12,
1162
- *
1163
- * // Editing UI
1164
- * showSendButton: true,
1165
- * autoGrow: true,
1166
- *
1167
- * // Visual effects
1168
- * shadow: true,
1169
- * expandOnSelect: false,
1170
- *
1171
- * // Fixed size (always screen-aligned)
1172
- * fixedSize: true
1173
- * }
1174
- * ```
1175
- */
1176
- export declare const defaultCommentStyle: CommentStyle;
1177
-
1178
- /**
1179
- * Default polygon properties for creating new Polygon annotations.
1180
- * Contains the default polygon configuration with {@link defaultPolygonStyle}.
1181
- */
1182
- export declare const defaultPolygonProperties: PolygonProperties;
1183
-
1184
- /**
1185
- * Default style configuration for polygon annotations.
1186
- *
1187
- * @example
1188
- * ```typescript
1189
- * {
1190
- * background: "transparent",
1191
- * strokeWidth: 2,
1192
- * borderRadius: 8,
1193
- * padding: 16,
1194
- * strokeType: "plain",
1195
- * strokeColor: "#000000"
1196
- * }
1197
- * ```
1198
- */
1199
- export declare const defaultPolygonStyle: PolygonStyle;
1200
-
1201
- /**
1202
- * Default options for creating new Text annotations.
1203
- * Contains the default text structure with {@link defaultTextStyle}.
1204
- */
1205
- export declare const defaultTextOptions: Text_2;
1206
-
1207
- /**
1208
- * Default style configuration for text annotations.
1209
- *
1210
- * @example
1211
- * ```typescript
1212
- * {
1213
- * font: "sans-serif",
1214
- * fontSize: 18,
1215
- * color: "#505050",
1216
- * background: "#f5f5f5",
1217
- * strokeWidth: 0,
1218
- * borderRadius: 8,
1219
- * padding: 16,
1220
- * strokeType: "plain",
1221
- * fixedSize: false
1222
- * }
1223
- * ```
1224
- */
1225
- export declare const defaultTextStyle: TextStyle;
1226
-
1227
- /**
1228
- * @private
1229
- * @param a Arrow annotation
1230
- * @param point Point to test
1231
- * @param threshold Detection threshold
1232
- * @returns True if the point is on the arrow line within the given threshold
1233
- */
1234
- export declare function detectArrow(a: Arrow, point: Point_3, threshold: number): boolean;
1235
-
1236
- /** @private */
1237
- export declare function detectBox(a: Box, p: Point, sin?: number, cos?: number, threshold?: number): boolean;
1238
-
1239
- /**
1240
- * Detect if a point is within a comment's bounds
1241
- * @private
1242
- * @param comment - Comment to test
1243
- * @param point - Point to test
1244
- * @param threshold - Detection threshold in pixels
1245
- * @param zoom - Current zoom level
1246
- * @returns True if point is within comment bounds
1247
- */
1248
- export declare function detectComment(comment: Comment_2, point: Point, threshold: number | undefined, sin: number, cos: number, zoom?: number): boolean;
1249
-
1250
- /**
1251
- * Point-in-polygon detection using ray casting algorithm
1252
- * @private
1253
- * @param polygon The polygon annotation
1254
- * @param point The point to test
1255
- * @param threshold Detection threshold in pixels
1256
- * @return True if the point is inside the polygon or within the threshold distance from its edges
1257
- */
1258
- export declare function detectPolygon(polygon: Polygon, point: Point, threshold?: number): boolean;
1259
-
1260
- /**
1261
- * Detects whether a point is within a text annotation's bounds.
1262
- * @private
1263
- * @param a Text annotation
1264
- * @param p Point to test
1265
- * @param threshold Detection threshold
1266
- * @param sin Rotation sine
1267
- * @param cos Rotation cosine
1268
- * @param zoom Current zoom level
1269
- * @returns True if the point is within the text bounds, false otherwise
1270
- */
1271
- export declare function detectText(a: Text_2, p: Point, threshold?: number, sin?: number, cos?: number, zoom?: number): boolean;
1272
-
1273
- /** Event related to a single annotation feature */
1274
- declare interface DragEvent_2 {
1275
- /** Annotation ID involved in the event */
1276
- id: Id;
1277
- /** Current mouse position in pixel coordinates during the drag */
1278
- position: {
1279
- x: number;
1280
- y: number;
1281
- };
1282
- }
1283
- export { DragEvent_2 as DragEvent }
1284
-
1285
- /** Arrow snapped at parametric position t (0–1) along an edge path. */
1286
- export declare type EdgeMagnet = {
1287
- type: "edge";
1288
- t: number;
1289
- };
1290
-
1291
- export declare const EVT_ADD = "add";
1292
-
1293
- export declare const EVT_CANCEL_DRAWING = "cancelDrawing";
1294
-
1295
- export declare const EVT_CLICK = "click";
1296
-
1297
- export declare const EVT_COMPLETE_DRAWING = "completeDrawing";
1298
-
1299
- export declare const EVT_DRAG = "dragging";
1300
-
1301
- export declare const EVT_DRAG_END = "dragend";
1302
-
1303
- export declare const EVT_DRAG_START = "dragstart";
1304
-
1305
- export declare const EVT_HISTORY = "history";
1306
-
1307
- export declare const EVT_HOVER = "hover";
1308
-
1309
- export declare const EVT_LINK = "link";
1310
-
1311
- export declare const EVT_REMOVE = "remove";
1312
-
1313
- export declare const EVT_SELECT = "select";
1314
-
1315
- export declare const EVT_UNHOVER = "unhover";
1316
-
1317
- export declare const EVT_UNSELECT = "unselect";
1318
-
1319
- export declare const EVT_UPDATE = "update";
1320
-
1321
- /**
1322
- * Serialized link stored inside arrow.properties.link.
1323
- * Uses plain { x, y } for backward compatibility with saved annotations.
1324
- * Converted to the internal Magnet type by Links.add().
1325
- */
1326
- export declare type ExportedLink = {
1327
- id: Id;
1328
- side: Side;
1329
- type: TargetType;
1330
- magnet?: Point;
1331
- };
1332
-
1333
- /** Extremity types for arrow annotations. */
1334
- export declare type Extremity = "none" | "arrow" | "arrow-plain" | "dot" | "halo-dot";
1335
-
1336
- /** Event related to a single annotation feature */
1337
- export declare interface FeatureEvent {
1338
- /** Annotation ID involved in the event */
1339
- id: Id;
1340
- }
1341
-
1342
- export declare type FeatureEvents = {
1343
- /**
1344
- * Event trigerred when selecting an annotation
1345
- * @param evt The annotation selected
1346
- */
1347
- [EVT_SELECT]: (evt: FeaturesEvent) => void;
1348
- /**
1349
- * Event trigerred when unselecting an annotation
1350
- * @param evt The annotation unselected
1351
- */
1352
- [EVT_UNSELECT]: (evt: FeaturesEvent) => void;
1353
- /**
1354
- * Event trigerred when removing an annotation
1355
- * @param evt The annotation removed
1356
- */
1357
- [EVT_REMOVE]: (evt: FeatureEvent) => void;
1358
- /**
1359
- * Event trigerred when adding an annotation
1360
- * @param evt The annotation added
1361
- */
1362
- [EVT_ADD]: (evt: FeatureEvent) => void;
1363
- /**
1364
- * Event trigerred when canceling drawing mode
1365
- */
1366
- [EVT_CANCEL_DRAWING]: () => void;
1367
- /**
1368
- * Event trigerred when completing a drawing operation
1369
- * @param evt Contains the ID of the completed annotation
1370
- */
1371
- [EVT_COMPLETE_DRAWING]: (evt: FeatureEvent) => void;
1372
- /**
1373
- * Event trigerred when updating an annotation.
1374
- * This fires after any modification including drag operations, style changes, scaling, etc.
1375
- * @param evt The updated annotation with all changes applied
1376
- */
1377
- [EVT_UPDATE]: (evt: Annotation) => void;
1378
- /**
1379
- * Event trigerred when linking an arrow to a node or annotation
1380
- * @param evt Contains the arrow and link details
1381
- */
1382
- [EVT_LINK]: (evt: {
1383
- arrow: Arrow;
1384
- link: Link;
1385
- }) => void;
1386
- /**
1387
- * Event trigerred when history state changes (after undo/redo operations)
1388
- * @param evt Contains boolean flags for undo/redo availability
1389
- */
1390
- [EVT_HISTORY]: (evt: HistoryEvent) => void;
1391
- /**
1392
- * Event triggered when a drag operation starts on an annotation
1393
- */
1394
- [EVT_DRAG_START]: (evt: DragEvent_2) => void;
1395
- /**
1396
- * Event triggered when a drag operation ends on an annotation
1397
- */
1398
- [EVT_DRAG_END]: (evt: DragEvent_2) => void;
1399
- /**
1400
- * Event triggered when a click completes on an annotation (mouseup without drag)
1401
- */
1402
- [EVT_CLICK]: (evt: ClickEvent) => void;
1403
- };
1404
-
1405
- /** Event related to multiple annotation features */
1406
- export declare interface FeaturesEvent {
1407
- /** Annotation IDs involved in the event */
1408
- ids: Id[];
1409
- }
1410
-
1411
- /**
1412
- * Calculate the bounds of a collection of annotations
1413
- * @param annotations
1414
- * @returns Bounds [minX, minY, maxX, maxY]
1415
- */
1416
- export declare function getAnnotationsBounds(annotations: AnnotationCollection): Bounds;
1417
-
1418
- export declare function getArrowEnd(a: Arrow): {
1419
- x: number;
1420
- y: number;
1421
- };
1422
-
1423
- export declare function getArrowEndPoints(a: Arrow): {
1424
- start: {
1425
- x: number;
1426
- y: number;
1427
- };
1428
- end: {
1429
- x: number;
1430
- y: number;
1431
- };
1432
- };
1433
-
1434
- export declare function getArrowSide(a: Arrow, side: Side): {
1435
- x: number;
1436
- y: number;
1437
- };
1438
-
1439
- export declare function getArrowStart(a: Arrow): {
1440
- x: number;
1441
- y: number;
1442
- };
1443
-
1444
- export declare function getAttachmentPointOnNode(start: Point_3, nodeCenter: Point_3, nodeRadius: number): {
1445
- x: number;
1446
- y: number;
1447
- };
1448
-
1449
- declare function getBbox<T extends Annotation>(b: T): BBox;
1450
- export { getBbox }
1451
- export { getBbox as getTextBbox }
1452
-
1453
- export declare function getBoxCenter<T extends Annotation>(t: T): {
1454
- x: number;
1455
- y: number;
1456
- };
1457
-
1458
- declare function getBoxPosition<T extends Annotation>(t: T, fixedSize?: boolean, zoom?: number): {
1459
- x: number;
1460
- y: number;
1461
- };
1462
- export { getBoxPosition }
1463
- export { getBoxPosition as getTextPosition }
1464
-
1465
- declare function getBoxSize<T extends Annotation>(t: T): {
1466
- width: number;
1467
- height: number;
1468
- };
1469
- export { getBoxSize }
1470
- export { getBoxSize as getTextSize }
1471
-
1472
- /** @private */
1473
- export declare function getBrowserWindow(): HTMLElement | undefined;
1474
-
1475
- /**
1476
- * Get the position (center) of a comment
1477
- *
1478
- * @param comment - Comment annotation
1479
- * @returns Center position
1480
- */
1481
- export declare function getCommentPosition(comment: Comment_2): Point;
1482
-
1483
- /**
1484
- * Get the dimensions of a comment based on its mode
1485
- *
1486
- * @param comment - Comment annotation
1487
- * @returns Width and height
1488
- */
1489
- export declare function getCommentSize(comment: Comment_2): Size;
1490
-
1491
- /**
1492
- * Get the effective zoom threshold for a comment
1493
- * Uses explicit threshold if set, otherwise calculates from dimensions
1494
- *
1495
- * @param comment - Comment annotation
1496
- * @returns Effective zoom threshold
1497
- */
1498
- export declare function getCommentZoomThreshold(comment: Comment_2): number;
1499
-
1500
- export declare function getCoordinates(geojson: Feature | FeatureCollection | Geometry): Position[];
1501
-
1502
- export declare const getHandleId: (handle: HTMLDivElement) => number;
1503
-
1504
- /**
1505
- * Get bounding box of a polygon
1506
- */
1507
- export declare function getPolygonBounds(polygon: Polygon): Bounds;
1508
-
1509
- /**
1510
- * Get centroid (geometric center) of a polygon
1511
- */
1512
- export declare function getPolygonCenter(polygon: Polygon): Point;
1513
-
1514
- export declare const handleDetectionThreshold = 5;
1515
-
1516
- export declare const handleRadius = 3;
1517
-
1518
- /**
1519
- * Hex color string in format #RGB or #RRGGBB
1520
- * @example "#fff" | "#ffffff" | "#F0A" | "#FF00AA"
1521
- */
1522
- export declare type HexColor = `#${string}`;
1523
-
1524
- export declare function hexShortToLong(color: HexColor): HexColor;
1525
-
1526
- /**
1527
- * Adds alpha channel to a hex color
1528
- * @param color
1529
- * @param alpha
1530
- * @returns rgba color string
1531
- */
1532
- export declare function hexToRgba(color: HexColor, alpha: number): RgbaColor;
1533
-
1534
- /** History stack change event */
1535
- export declare interface HistoryEvent {
1536
- /** Indicates if undo operation is available */
1537
- canUndo: boolean;
1538
- /** Indicates if redo operation is available */
1539
- canRedo: boolean;
1540
- }
1541
-
1542
- export declare const HL_BRIGHTEN = 0.2;
1543
-
1544
- /** Unique identifier type for annotations */
1545
- export declare type Id = string | number;
1546
-
1547
- /** Helper to check if a feature collection is an annotation collection */
1548
- export declare const isAnnotationCollection: (a: AnnotationFeature<Geometry, AnnotationProps> | FeatureCollection) => a is AnnotationCollection;
1549
-
1550
- export declare const isArrow: (a: AnnotationFeature<Geometry, AnnotationProps>) => a is Arrow;
1551
-
1552
- export declare const isBox: (a: AnnotationFeature<Geometry, AnnotationProps>) => a is Box;
1553
-
1554
- /**
1555
- * Type guard to check if a string is a valid color
1556
- */
1557
- export declare function isColor(color: string): color is Color;
1558
-
1559
- /**
1560
- * Type guard to check if an annotation is a Comment
1561
- */
1562
- export declare const isComment: (a: AnnotationFeature<Geometry, AnnotationProps>) => a is Comment_2;
1563
-
1564
- /**
1565
- * Helper functions for managing comment-arrow relationships
1566
- *
1567
- * These functions provide utilities for:
1568
- * - Checking if an arrow is connected to a comment
1569
- * - Determining if arrow endpoints can be detached from comments
1570
- *
1571
- * Note: The core rule "comments must have at least one arrow" is enforced
1572
- * in store/index.ts removeFeature() method, not here.
1573
- */
1574
- /**
1575
- * Check if an arrow is connected to a comment
1576
- *
1577
- * @param arrow - The arrow feature to check
1578
- * @returns True if the arrow has a comment on either end
1579
- *
1580
- * @example
1581
- * ```typescript
1582
- * if (isCommentArrow(arrow)) {
1583
- * // Handle comment arrow specially
1584
- * }
1585
- * ```
1586
- */
1587
- export declare function isCommentArrow(arrow: Arrow): boolean;
1588
-
1589
- /**
1590
- * Type guard to check if a string is a valid hex color
1591
- */
1592
- export declare function isHexColor(color: string): color is HexColor;
1593
-
1594
- export declare const isPolygon: (a: AnnotationFeature<Geometry, AnnotationProps>) => a is Polygon;
1595
-
1596
- /**
1597
- * Type guard to check if a string is a valid RGBA color
1598
- */
1599
- export declare function isRgbaColor(color: string): color is RgbaColor;
1600
-
1601
- /**
1602
- * Type guard to check if a string is a valid RGB color
1603
- */
1604
- export declare function isRgbColor(color: string): color is RgbColor;
1605
-
1606
- export declare const isText: (a: AnnotationFeature<Geometry, AnnotationProps>) => a is Text_2;
1607
-
1608
- /** @private */
1609
- export declare const LAYERS: {
1610
- SHAPES: number;
1611
- EDITOR: number;
1612
- HANDLES: number;
1613
- };
1614
-
1615
- /** Link between an arrow and a text or node */
1616
- export declare interface Link {
1617
- /** arrow attached to the text or node */
1618
- arrow: Id;
1619
- /** id of the text the arrow is attached to */
1620
- id: Id;
1621
- /** On which end the arrow is tighten to the text */
1622
- side: Side;
1623
- /** id of the text or node the arrow is attached to */
1624
- target: Id;
1625
- /** Text or node */
1626
- targetType: TargetType;
1627
- /** Typed snap point — semantics depend on targetType, see Magnet union. */
1628
- magnet: Magnet;
1629
- }
1630
-
1631
- export declare type Magnet = NodeMagnet | EdgeMagnet | BoxMagnet | PolygonMagnet;
1632
-
1633
- /**
1634
- * Migrates old Polygon-based Box/Text to new Point-based format
1635
- * Called only when annotations are added/loaded
1636
- * @private
1637
- */
1638
- export declare function migrateBoxOrTextIfNeeded<T extends Annotation>(annotation: T): T;
1639
-
1640
- /** Arrow snapped to the center or perimeter of a node. */
1641
- export declare type NodeMagnet = {
1642
- type: "node";
1643
- center: boolean;
1644
- };
1645
-
1646
- export declare const NONE = -1;
1647
-
1648
- export declare function parseColor(color: Color): {
1649
- r: number;
1650
- g: number;
1651
- b: number;
1652
- a: number;
1653
- };
1654
-
1655
- /** 2D coordinate */
1656
- export declare type Point = {
1657
- x: number;
1658
- y: number;
1659
- };
1660
-
1661
- /**
1662
- * Polygon placed on the graph, use it to highlight areas
1663
- */
1664
- export declare interface Polygon extends AnnotationFeature<Polygon_2, PolygonProperties> {
1665
- }
1666
-
1667
- /**
1668
- * Arrow snapped to a polygon annotation.
1669
- * rx/ry are 0–1 fractions of the polygon's bounding box from its top-left corner.
1670
- */
1671
- export declare type PolygonMagnet = {
1672
- type: "polygon";
1673
- rx: number;
1674
- ry: number;
1675
- };
1676
-
1677
- export declare interface PolygonProperties extends AnnotationProps {
1678
- type: "polygon";
1679
- style?: PolygonStyle;
1680
- }
1681
-
1682
- export declare interface PolygonStyle extends BoxStyle {
1683
- }
1684
-
1685
- /**
1686
- * RGBA color string in format rgba(r, g, b, a)
1687
- * @example "rgba(255, 0, 0, 1)" | "rgba(128, 128, 128, 0.5)"
1688
- */
1689
- export declare type RgbaColor = `rgba(${number}, ${number}, ${number}, ${number})` | `rgba(${number},${number},${number},${number})`;
1690
-
1691
- /**
1692
- * RGB color string in format rgb(r, g, b)
1693
- * @example "rgb(255, 0, 0)" | "rgb(128, 128, 128)"
1694
- */
1695
- export declare type RgbColor = `rgb(${number}, ${number}, ${number})` | `rgb(${number},${number},${number})`;
1696
-
1697
- /**
1698
- * Adds alpha channel to an rgb color
1699
- * @param color
1700
- * @param alpha
1701
- * @returns rgba color string
1702
- */
1703
- export declare function rgbToRgba(color: RgbColor, alpha: number): RgbaColor;
1704
-
1705
- export declare function scaleGeometry(geometry: LineString | Polygon_2, scale: number, ox: number, oy: number): LineString | Polygon_2;
1706
-
1707
- /**
1708
- * Scale polygon around an origin point
1709
- */
1710
- export declare function scalePolygon(polygon: Polygon, scale: number, originX: number, originY: number): Polygon;
1711
-
1712
- export declare function setArrowEnd(a: Arrow, x: number, y: number): void;
1713
-
1714
- export declare function setArrowEndPoint(a: Arrow, side: Side, x: number, y: number): void;
1715
-
1716
- export declare function setArrowStart(a: Arrow, x: number, y: number): void;
1717
-
1718
- declare function setBbox(t: Box | Text_2, x: number, y: number, width: number, height: number): void;
1719
- export { setBbox }
1720
- export { setBbox as setTextBbox }
1721
-
1722
- export declare type Side = typeof SIDE_START | typeof SIDE_END;
1723
-
1724
- export declare const SIDE_END: "end";
1725
-
1726
- export declare const SIDE_START: "start";
1727
-
1728
- /**
1729
- * Polyline simplification using a combination of
1730
- * the Radial Distance and
1731
- * the Douglas-Peucker algorithms
1732
- * See https://github.com/mourner/simplify-js for more details
1733
- *
1734
- * @param points Points to simplify
1735
- * @param tolerance Tolerance in pixels
1736
- * @param highestQuality Whether to skip radial distance simplification
1737
- * @returns Simplified points
1738
- */
1739
- export declare function simplifyPolygon(points: Position[], tolerance: number, highestQuality: boolean): Position[];
1740
-
1741
- /** Stroke style for arrow annotations */
1742
- export declare type Stroke = {
1743
- /** Stroke type */
1744
- type: StrokeType;
1745
- /** Stroke color */
1746
- color: Color;
1747
- /** Stroke width */
1748
- width: number;
1749
- };
1750
-
1751
- /** Stroke style options for annotations */
1752
- export declare type StrokeOptions = {
1753
- /** Type of stroke: plain, dashed, or none */
1754
- strokeType?: StrokeType;
1755
- /** Stroke color: #f00, yellow... */
1756
- strokeColor?: Color;
1757
- /** Stroke width */
1758
- strokeWidth?: number;
1759
- };
1760
-
1761
- export declare type StrokeStyle = Stroke;
1762
-
1763
- /** Stroke types available for annotations */
1764
- export declare type StrokeType = "plain" | "dashed" | "none";
1765
-
1766
- /** @private */
1767
- export declare const TARGET_TYPES: {
1768
- TEXT: "text";
1769
- NODE: "node";
1770
- BOX: "box";
1771
- COMMENT: "comment";
1772
- POLYGON: "polygon";
1773
- ANNOTATION: "annotation";
1774
- EDGE: "edge";
1775
- };
1776
-
1777
- export declare type TargetType = (typeof TARGET_TYPES)[keyof typeof TARGET_TYPES];
1778
-
1779
- /**
1780
- * Text annotation feature, represents a text box at a specific position
1781
- */
1782
- declare interface Text_2 extends AnnotationFeature<Point_2, TextProperties> {
1783
- }
1784
- export { Text_2 as Text }
1785
-
1786
- export declare const TEXT_LINE_HEIGHT = 1.2;
1787
-
1788
- export declare interface TextProperties extends Omit<BoxProperties, "type"> {
1789
- type: "text";
1790
- /**text to display*/
1791
- content: string;
1792
- /** Width of the text box */
1793
- width: number;
1794
- /** Height of the text box */
1795
- height: number;
1796
- style?: TextStyle;
1797
- }
1798
-
1799
- export declare interface TextStyle extends BoxStyle {
1800
- /** Helvetica, sans-serif... */
1801
- font?: string;
1802
- /** Font size, in pixels */
1803
- fontSize?: number | string;
1804
- /** text color: #f00, yellow...*/
1805
- color?: Color;
1806
- /** background color: empty for transparent #f00, yellow...*/
1807
- background?: Color;
1808
- /** padding around the text */
1809
- padding?: number;
1810
- /** Text box border radius */
1811
- borderRadius?: number;
1812
- /** When true, text maintains constant size regardless of zoom level */
1813
- fixedSize?: boolean;
1814
- /**
1815
- * Ghost text shown (via the textarea's native `placeholder` attribute)
1816
- * while `content` is empty - disappears the instant the user types, no
1817
- * selection/focus tricks needed. Overrides the global
1818
- * `ControllerOptions.textPlaceholder` for this annotation.
1819
- */
1820
- placeholder?: string;
1821
- }
1822
-
1823
- /** @private */
1824
- export declare const throttle: <T extends unknown[]>(callback: (...args: T) => void, delay?: number, callIfWaiting?: boolean) => (...args: T) => void;
1825
-
1826
- /**
1827
- * Toggle comment mode between collapsed and expanded
1828
- *
1829
- * @param comment - Comment to toggle
1830
- * @returns Updated comment with toggled mode
1831
- */
1832
- export declare function toggleCommentMode(comment: Comment_2): Comment_2;
1833
-
1834
- /**
1835
- * Translate (move) a polygon by dx, dy
1836
- */
1837
- export declare function translatePolygon(polygon: Polygon, dx: number, dy: number): Polygon;
1838
-
1839
- declare function updateBbox<T extends Annotation>(t: T): void;
1840
- export { updateBbox }
1841
- export { updateBbox as updateTextBbox }
1842
-
1843
- /**
1844
- * Update bbox for a polygon
1845
- */
1846
- export declare function updatePolygonBbox(polygon: Polygon): void;
1847
-
1848
- /** @private */
1849
- export declare type Vector = Point;
1850
-
1851
- export { }
1
+ import { P as Polygon, B as Bounds, a as Point, C as Color, R as RgbaColor, b as ClientMouseEvent, A as AnnotationCollection, c as Arrow, S as Side, d as Annotation, H as HexColor, e as RgbColor, f as Box, T as Text, I as Id } from './Control-BiYdzv0K.js';
2
+ export { g as AnnotationFeature, h as AnnotationGetter, i as AnnotationOptions, j as AnnotationProps, k as AnnotationType, l as ArrowProperties, m as ArrowStyles, n as AuthorLineStyle, o as BoxMagnet, p as BoxProperties, q as BoxStyle, r as COMMENT_MODE_COLLAPSED, s as COMMENT_MODE_EXPANDED, t as ClickEvent, u as Comment, v as CommentProps, w as CommentStyle, x as Control, y as ControllerOptions, z as Cursor, D as DATA_ATTR, E as DEFAULT_EDIT_ICON, F as DEFAULT_SEND_ICON, G as DeepPartial, J as DragEvent, K as EVT_ADD, L as EVT_CANCEL_DRAWING, M as EVT_CLICK, N as EVT_COMPLETE_DRAWING, O as EVT_DRAG, Q as EVT_DRAG_END, U as EVT_DRAG_START, V as EVT_HISTORY, W as EVT_HOVER, X as EVT_LINK, Y as EVT_REMOVE, Z as EVT_SELECT, _ as EVT_UNHOVER, $ as EVT_UNSELECT, a0 as EVT_UPDATE, a1 as EdgeMagnet, a2 as ExportedLink, a3 as Extremity, a4 as FeatureEvent, a5 as FeatureEvents, a6 as FeaturesEvent, a7 as HL_BRIGHTEN, a8 as HistoryEvent, a9 as LAYERS, aa as Link, ab as Magnet, ac as NONE, ad as NodeMagnet, ae as PolygonMagnet, af as PolygonProperties, ag as PolygonStyle, ah as SIDE_END, ai as SIDE_START, aj as Stroke, ak as StrokeOptions, al as StrokeStyle, am as StrokeType, an as TARGET_TYPES, ao as TEXT_LINE_HEIGHT, ap as TargetType, aq as TextProperties, ar as TextStyle, as as Vector, at as asColor, au as asHexColor, av as asRgbColor, aw as asRgbaColor, ax as calculateCommentZoomThreshold, ay as createArrow, az as createBox, aA as createComment, aB as createCommentWithArrow, aC as createPolygon, aD as createText, aE as cursors, aF as defaultArrowOptions, aG as defaultArrowStyle, aH as defaultBoxOptions, aI as defaultBoxStyle, aJ as defaultCommentOptions, aK as defaultCommentStyle, aL as defaultPolygonProperties, aM as defaultPolygonStyle, aN as defaultTextOptions, aO as defaultTextStyle, aP as detectArrow, aQ as detectBox, aR as detectComment, aS as detectPolygon, aT as detectText, aU as getCommentPosition, aV as getCommentSize, aW as getCommentZoomThreshold, aX as handleDetectionThreshold, aY as handleRadius, aZ as isAnnotationCollection, a_ as isArrow, a$ as isBox, b0 as isColor, b1 as isComment, b2 as isHexColor, b3 as isPolygon, b4 as isRgbColor, b5 as isRgbaColor, b6 as isRigidConnector, b7 as isStickyNote, b8 as isText, b9 as toggleCommentMode } from './Control-BiYdzv0K.js';
3
+ import { Point as Point$1 } from '@linkurious/ogma';
4
+ import { Position, BBox, Feature, FeatureCollection, Geometry, LineString, Polygon as Polygon$1 } from 'geojson';
5
+ import 'eventemitter3';
6
+
7
+ /**
8
+ * Polyline simplification using a combination of
9
+ * the Radial Distance and
10
+ * the Douglas-Peucker algorithms
11
+ * See https://github.com/mourner/simplify-js for more details
12
+ *
13
+ * @param points Points to simplify
14
+ * @param tolerance Tolerance in pixels
15
+ * @param highestQuality Whether to skip radial distance simplification
16
+ * @returns Simplified points
17
+ */
18
+ declare function simplify(points: Position[], tolerance: number, highestQuality: boolean): Position[];
19
+
20
+ /**
21
+ * Get bounding box of a polygon
22
+ */
23
+ declare function getPolygonBounds(polygon: Polygon): Bounds;
24
+ /**
25
+ * Get centroid (geometric center) of a polygon
26
+ */
27
+ declare function getPolygonCenter(polygon: Polygon): Point;
28
+
29
+ /**
30
+ * Translate (move) a polygon by dx, dy
31
+ */
32
+ declare function translatePolygon(polygon: Polygon, dx: number, dy: number): Polygon;
33
+ /**
34
+ * Update bbox for a polygon
35
+ */
36
+ declare function updatePolygonBbox(polygon: Polygon): void;
37
+ /**
38
+ * Scale polygon around an origin point
39
+ */
40
+ declare function scalePolygon(polygon: Polygon, scale: number, originX: number, originY: number): Polygon;
41
+
42
+ /** @private */
43
+ declare function createSVGElement<T extends SVGElement>(tag: string): T;
44
+ /**
45
+ * Move `el` to the end of `root`'s children. SVG paint order is DOM order,
46
+ * so this is how a shape gets raised to the top of its group. Safe to call
47
+ * every render even when `el` is already last - `appendChild` on an
48
+ * existing child just re-positions it, it doesn't clone or re-trigger
49
+ * insertion.
50
+ */
51
+ declare function bringToTop(root: Element, el: Element): void;
52
+ declare function getBbox<T extends Annotation>(b: T): BBox;
53
+ declare function getBoxSize<T extends Annotation>(t: T): {
54
+ width: number;
55
+ height: number;
56
+ };
57
+ declare const MIN_FONT_SCALE = 0.4;
58
+ declare const MAX_FONT_SCALE = 4;
59
+ /** fontSize * fontScale, the number to actually render/edit at. Shared by
60
+ * the SVG renderer (text.ts) and the live-edit overlay (textArea.ts) so
61
+ * both stay in sync. fontScale absent/undefined is a no-op (×1). */
62
+ declare function getEffectiveFontSize(fontSize: number | string | undefined, fontScale: number | undefined): number;
63
+ declare function getBoxPosition<T extends Annotation>(t: T, fixedSize?: boolean, zoom?: number): {
64
+ x: number;
65
+ y: number;
66
+ };
67
+ declare function getBoxCenter<T extends Annotation>(t: T): {
68
+ x: number;
69
+ y: number;
70
+ };
71
+ declare function updateBbox<T extends Annotation>(t: T): void;
72
+ declare function setBbox(t: Box | Text, x: number, y: number, width: number, height: number): void;
73
+ declare function getArrowStart(a: Arrow): {
74
+ x: number;
75
+ y: number;
76
+ };
77
+ declare function getArrowSide(a: Arrow, side: Side): {
78
+ x: number;
79
+ y: number;
80
+ };
81
+ declare function getArrowEnd(a: Arrow): {
82
+ x: number;
83
+ y: number;
84
+ };
85
+ declare function setArrowStart(a: Arrow, x: number, y: number): void;
86
+ declare function setArrowEnd(a: Arrow, x: number, y: number): void;
87
+ declare function getArrowEndPoints(a: Arrow): {
88
+ start: {
89
+ x: number;
90
+ y: number;
91
+ };
92
+ end: {
93
+ x: number;
94
+ y: number;
95
+ };
96
+ };
97
+ declare function setArrowEndPoint(a: Arrow, side: Side, x: number, y: number): void;
98
+ declare const getHandleId: (handle: HTMLDivElement) => number;
99
+ /**
100
+ * Calculate the bounds of a collection of annotations
101
+ * @param annotations
102
+ * @returns Bounds [minX, minY, maxX, maxY]
103
+ */
104
+ declare function getAnnotationsBounds(annotations: AnnotationCollection): Bounds;
105
+ declare function scaleGeometry(geometry: LineString | Polygon$1, scale: number, ox: number, oy: number): LineString | Polygon$1;
106
+ declare function getCoordinates(geojson: Feature | FeatureCollection | Geometry): Position[];
107
+ declare function getAttachmentPointOnNode(start: Point$1, nodeCenter: Point$1, nodeRadius: number): {
108
+ x: number;
109
+ y: number;
110
+ };
111
+ declare function clientToContainerPosition(evt: ClientMouseEvent, container?: HTMLElement | null): {
112
+ x: number;
113
+ y: number;
114
+ };
115
+ declare function colorToRgba(color: Color, alpha: number): RgbaColor;
116
+ declare function parseColor(color: Color): {
117
+ r: number;
118
+ g: number;
119
+ b: number;
120
+ a: number;
121
+ };
122
+ declare function hexShortToLong(color: HexColor): HexColor;
123
+ /**
124
+ * Adds alpha channel to a hex color
125
+ * @param color
126
+ * @param alpha
127
+ * @returns rgba color string
128
+ */
129
+ declare function hexToRgba(color: HexColor, alpha: number): RgbaColor;
130
+ /**
131
+ * Adds alpha channel to an rgb color
132
+ * @param color
133
+ * @param alpha
134
+ * @returns rgba color string
135
+ */
136
+ declare function rgbToRgba(color: RgbColor, alpha: number): RgbaColor;
137
+ /** @private */
138
+ declare function getBrowserWindow(): HTMLElement | undefined;
139
+ /** @private */
140
+ declare const throttle: <T extends unknown[]>(callback: (...args: T) => void, delay?: number, callIfWaiting?: boolean) => (...args: T) => void;
141
+ /** @private */
142
+ declare const debounce: <F extends (...args: Parameters<F>) => ReturnType<F>>(func: F, waitFor: number) => (...args: Parameters<F>) => void;
143
+ /** @private */
144
+ declare function debounceTail<T, A extends unknown[]>(fn: (this: T, ...args: A) => void, delay: number): (this: T, ...args: A) => void;
145
+
146
+ /**
147
+ * Migrates old Polygon-based Box/Text to new Point-based format
148
+ * Called only when annotations are added/loaded
149
+ * @private
150
+ */
151
+ declare function migrateBoxOrTextIfNeeded<T extends Annotation>(annotation: T): T;
152
+ /**
153
+ * Adjusts the brightness of a color (hex or rgba) based on its perceived luminance.
154
+ * For bright colors, the adjustment is applied as darkening; for dark colors, as lightening.
155
+ *
156
+ * @param color - Color string in hex (#RRGGBB or #RGB) or rgba format
157
+ * @param amount - Adjustment factor between -1 and 1:
158
+ * - Positive values (0 to 1): lighten dark colors, darken bright colors
159
+ * - Negative values (-1 to 0): darken dark colors, lighten bright colors
160
+ * - 0: no change
161
+ * - Example: 0.2 applies a 20% adjustment, -0.1 applies a -10% adjustment
162
+ * @returns Adjusted color in rgba format
163
+ */
164
+ declare function adjustColorBrightness(color: Color, amount: number): RgbaColor;
165
+ /**
166
+ * Brighten a color for highlight purposes.
167
+ * @param color - Color string in hex (#RRGGBB or #RGB) or rgba format
168
+ * @returns
169
+ */
170
+ declare const brighten: (color: Color) => RgbaColor;
171
+ /**
172
+ * Darken a color for highlight purposes.
173
+ * @param color - Color string in hex (#RRGGBB or #RGB) or rgba format
174
+ * @returns
175
+ */
176
+ declare const darken: (color: Color) => RgbaColor;
177
+
178
+ /**
179
+ * Helper functions for managing comment-arrow relationships
180
+ *
181
+ * These functions provide utilities for:
182
+ * - Checking if an arrow is connected to a comment
183
+ * - Determining if arrow endpoints can be detached from comments
184
+ * - Cascading a comment's delete to its arrows, and blocking deletion of a
185
+ * comment's last remaining arrow (store/index.ts:removeFeature uses both)
186
+ */
187
+ /**
188
+ * Check if an arrow is connected to a comment
189
+ *
190
+ * @param arrow - The arrow feature to check
191
+ * @returns True if the arrow has a comment on either end
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * if (isCommentArrow(arrow)) {
196
+ * // Handle comment arrow specially
197
+ * }
198
+ * ```
199
+ */
200
+ declare function isCommentArrow(arrow: Arrow): boolean;
201
+ /**
202
+ * Get the id of the comment an arrow is connected to, if any.
203
+ *
204
+ * A comment is one visual annotation together with the arrow that connects
205
+ * it - callers that raise a comment's z-order (e.g. bringing a newly
206
+ * created/selected comment to the front) should raise this arrow along with
207
+ * it, not just the comment bubble.
208
+ *
209
+ * @param arrow - The arrow feature to check
210
+ * @returns The linked comment's id, or undefined if the arrow isn't attached
211
+ * to a comment
212
+ */
213
+ declare function getCommentLinkId(arrow: Arrow): Id | undefined;
214
+ /**
215
+ * Check if arrow start point can be detached from its source
216
+ *
217
+ * Returns false for arrows originating FROM comments, since comment arrows
218
+ * must always remain attached to the comment on their start side.
219
+ *
220
+ * @param arrow - The arrow feature
221
+ * @returns True if arrow start can be detached
222
+ *
223
+ * @example
224
+ * ```typescript
225
+ * if (canDetachArrowStart(arrow)) {
226
+ * // Allow user to drag arrow start point
227
+ * } else {
228
+ * // Keep arrow start locked to comment
229
+ * }
230
+ * ```
231
+ */
232
+ declare function canDetachArrowStart(arrow: Arrow): boolean;
233
+ /**
234
+ * Check if arrow endpoint can be detached from its target
235
+ *
236
+ * Always returns true since arrow endpoints can be freely retargeted,
237
+ * even for comment arrows. The comment is typically on the start side.
238
+ *
239
+ * @param _arrow - The arrow feature (unused, kept for API consistency)
240
+ * @returns Always true - arrow ends can be detached
241
+ *
242
+ * @example
243
+ * ```typescript
244
+ * if (canDetachArrowEnd(arrow)) {
245
+ * // Allow user to drag arrow end point
246
+ * }
247
+ * ```
248
+ */
249
+ declare function canDetachArrowEnd(_arrow: Arrow): boolean;
250
+ /**
251
+ * Ids that removing `id` should take with it: `id` itself, plus every arrow
252
+ * attached to it when it's a comment or text annotation - deleting the
253
+ * anchor takes its connectors along, since a detached comment-arrow has
254
+ * nothing to point at.
255
+ *
256
+ * @param features - The full feature map (pre-deletion)
257
+ * @param id - The id being removed
258
+ * @returns The complete set of ids to delete
259
+ */
260
+ declare function getCascadeDeleteIds(features: Record<Id, Annotation>, id: Id): Set<Id>;
261
+ /**
262
+ * Comments must always keep at least one arrow. Returns the comment's id
263
+ * when deleting `arrowId` would leave it with none, so the caller can block
264
+ * the deletion instead - or `null` when it's safe to proceed.
265
+ *
266
+ * @param features - The full feature map (pre-deletion)
267
+ * @param arrowId - The arrow being removed
268
+ */
269
+ declare function getCommentLeftOrphanedBy(features: Record<Id, Annotation>, arrowId: Id): Id | null;
270
+
271
+ export { Annotation, AnnotationCollection, Arrow, Bounds, Box, ClientMouseEvent, Color, HexColor, Id, MAX_FONT_SCALE, MIN_FONT_SCALE, Point, Polygon, RgbColor, RgbaColor, Side, Text, adjustColorBrightness, brighten, bringToTop, canDetachArrowEnd, canDetachArrowStart, clientToContainerPosition, colorToRgba, createSVGElement, darken, debounce, debounceTail, getAnnotationsBounds, getArrowEnd, getArrowEndPoints, getArrowSide, getArrowStart, getAttachmentPointOnNode, getBbox, getBoxCenter, getBoxPosition, getBoxSize, getBrowserWindow, getCascadeDeleteIds, getCommentLeftOrphanedBy, getCommentLinkId, getCoordinates, getEffectiveFontSize, getHandleId, getPolygonBounds, getPolygonCenter, getBbox as getTextBbox, getBoxPosition as getTextPosition, getBoxSize as getTextSize, hexShortToLong, hexToRgba, isCommentArrow, migrateBoxOrTextIfNeeded, parseColor, rgbToRgba, scaleGeometry, scalePolygon, setArrowEnd, setArrowEndPoint, setArrowStart, setBbox, setBbox as setTextBbox, simplify as simplifyPolygon, throttle, translatePolygon, updateBbox, updatePolygonBbox, updateBbox as updateTextBbox };