@inweb/markup 25.7.4 → 25.7.5

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.
@@ -3,19 +3,9 @@ import { IViewpoint } from "@inweb/viewer-core";
3
3
  import { IWorldTransform } from "./IWorldTransform";
4
4
  import { IMarkupObject } from "./IMarkupObject";
5
5
  /**
6
- * Defines type of markup object. For `VisualizeJS` markup only the `Line` and `Text` markup
7
- * objects are supported.
6
+ * Markup edit mode. Matches the type of markup object being created or object selecting mode.
8
7
  */
9
- export declare enum MarkupMode {
10
- SelectMarkup = "SelectMarkup",
11
- Line = "Line",
12
- Text = "Text",
13
- Rectangle = "Rectangle",
14
- Ellipse = "Ellipse",
15
- Arrow = "Arrow",
16
- Image = "Image",
17
- Cloud = "Cloud"
18
- }
8
+ export type MarkupMode = "SelectMarkup" | "Line" | "Text" | "Rectangle" | "Ellipse" | "Arrow" | "Image" | "Cloud";
19
9
  /**
20
10
  * 2D markup core interface.
21
11
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inweb/markup",
3
- "version": "25.7.4",
3
+ "version": "25.7.5",
4
4
  "description": "JavaScript 2D markups",
5
5
  "homepage": "https://cloud.opendesign.com/docs/index.html",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -26,8 +26,8 @@
26
26
  "docs": "typedoc"
27
27
  },
28
28
  "dependencies": {
29
- "@inweb/eventemitter2": "~25.7.4",
30
- "@inweb/viewer-core": "~25.7.4"
29
+ "@inweb/eventemitter2": "~25.7.5",
30
+ "@inweb/viewer-core": "~25.7.5"
31
31
  },
32
32
  "devDependencies": {
33
33
  "canvas": "^2.11.2",
@@ -27,19 +27,9 @@ import { IWorldTransform } from "./IWorldTransform";
27
27
  import { IMarkupObject } from "./IMarkupObject";
28
28
 
29
29
  /**
30
- * Defines type of markup object. For `VisualizeJS` markup only the `Line` and `Text` markup
31
- * objects are supported.
30
+ * Markup edit mode. Matches the type of markup object being created or object selecting mode.
32
31
  */
33
- export enum MarkupMode {
34
- SelectMarkup = "SelectMarkup",
35
- Line = "Line",
36
- Text = "Text",
37
- Rectangle = "Rectangle",
38
- Ellipse = "Ellipse",
39
- Arrow = "Arrow",
40
- Image = "Image",
41
- Cloud = "Cloud",
42
- }
32
+ export type MarkupMode = "SelectMarkup" | "Line" | "Text" | "Rectangle" | "Ellipse" | "Arrow" | "Image" | "Cloud";
43
33
 
44
34
  /**
45
35
  * 2D markup core interface.
@@ -25,7 +25,7 @@ import Konva from "konva";
25
25
  import { IEventEmitter } from "@inweb/eventemitter2";
26
26
  import { ChangeActiveDraggerEvent, IViewpoint, PanEvent } from "@inweb/viewer-core";
27
27
 
28
- import { IMarkup, MarkupMode } from "../IMarkup";
28
+ import { IMarkup } from "../IMarkup";
29
29
  import { IWorldTransform } from "../IWorldTransform";
30
30
  import { MarkupColor } from "./MarkupColor";
31
31
  import { IMarkupObject } from "../IMarkupObject";
@@ -45,84 +45,40 @@ import { IMarkupCloud } from "../IMarkupCloud";
45
45
  import { IMarkupImage } from "../IMarkupImage";
46
46
  import { IMarkupText } from "../IMarkupText";
47
47
 
48
- class KonvaShape {
49
- name: string;
50
- initializer: (ref: any) => any;
51
- }
52
-
53
- // move to separate class and create factory with enum?
54
- const MarkupMode2Konva = new Map<MarkupMode, KonvaShape>([
55
- [
56
- MarkupMode.SelectMarkup,
57
- {
58
- name: "SelectMarkup",
59
- initializer: () => {},
60
- },
61
- ],
62
- [
63
- MarkupMode.Line,
64
- {
65
- name: "Line",
66
- initializer: (ref) => {
67
- return new KonvaLine(null, ref);
68
- },
69
- },
70
- ],
71
- [
72
- MarkupMode.Text,
73
- {
74
- name: "Text",
75
- initializer: (ref) => {
76
- return new KonvaText(null, ref);
77
- },
78
- },
79
- ],
80
- [
81
- MarkupMode.Rectangle,
82
- {
83
- name: "Rect",
84
- initializer: (ref) => {
85
- return new KonvaRectangle(null, ref);
86
- },
87
- },
88
- ],
89
- [
90
- MarkupMode.Ellipse,
91
- {
92
- name: "Ellipse",
93
- initializer: (ref) => {
94
- return new KonvaEllipse(null, ref);
95
- },
96
- },
97
- ],
98
- [
99
- MarkupMode.Arrow,
100
- {
101
- name: "Arrow",
102
- initializer: (ref) => {
103
- return new KonvaArrow(null, ref);
104
- },
105
- },
106
- ],
107
- [
108
- MarkupMode.Image,
109
- {
110
- name: "Image",
111
- initializer: (ref) => {
112
- return new KonvaImage(null, ref);
113
- },
114
- },
115
- ],
116
- [
117
- MarkupMode.Cloud,
118
- {
119
- name: "Cloud",
120
- initializer: (ref) => {
121
- return new KonvaCloud(null, ref);
122
- },
123
- },
124
- ],
125
- ]);
48
+ const MarkupMode2Konva = {
49
+ SelectMarkup: {
50
+ name: "SelectMarkup",
51
+ initializer: null,
52
+ },
53
+ Line: {
54
+ name: "Line",
55
+ initializer: (ref: any) => new KonvaLine(null, ref),
56
+ },
57
+ Text: {
58
+ name: "Text",
59
+ initializer: (ref: any) => new KonvaText(null, ref),
60
+ },
61
+ Rectangle: {
62
+ name: "Rect",
63
+ initializer: (ref: any) => new KonvaRectangle(null, ref),
64
+ },
65
+ Ellipse: {
66
+ name: "Ellipse",
67
+ initializer: (ref: any) => new KonvaEllipse(null, ref),
68
+ },
69
+ Arrow: {
70
+ name: "Arrow",
71
+ initializer: (ref: any) => new KonvaArrow(null, ref),
72
+ },
73
+ Image: {
74
+ name: "Image",
75
+ initializer: (ref: any) => new KonvaImage(null, ref),
76
+ },
77
+ Cloud: {
78
+ name: "Cloud",
79
+ initializer: (ref: any) => new KonvaCloud(null, ref),
80
+ },
81
+ };
126
82
 
127
83
  /**
128
84
  * 2D markup core.
@@ -134,7 +90,7 @@ export class KonvaMarkup implements IMarkup {
134
90
  private _canvasOriginal: HTMLCanvasElement;
135
91
  private _canvasEvents: string[];
136
92
  private _markupIsActive = false;
137
- private _markupMode: MarkupMode;
93
+ private _markupMode: string;
138
94
  private _markupColor = new MarkupColor(255, 0, 0);
139
95
  private _konvaStage: Konva.Stage;
140
96
  private _konvaLayer: Konva.Layer;
@@ -234,10 +190,9 @@ export class KonvaMarkup implements IMarkup {
234
190
  this.removeTextInput();
235
191
  this.removeImageInput();
236
192
 
237
- const markupMode = MarkupMode[draggerName];
238
- const konvaMode = MarkupMode2Konva.get(markupMode);
239
- if (konvaMode) {
240
- this._markupMode = markupMode;
193
+ const konvaShape = MarkupMode2Konva[draggerName];
194
+ if (konvaShape) {
195
+ this._markupMode = draggerName;
241
196
  this._markupIsActive = true;
242
197
  } else {
243
198
  this._markupIsActive = false;
@@ -254,7 +209,9 @@ export class KonvaMarkup implements IMarkup {
254
209
  const dX = event.dX / window.devicePixelRatio;
255
210
  const dY = event.dY / window.devicePixelRatio;
256
211
 
257
- Object.values(MarkupMode).forEach((mode) => this.konvaLayerFind(mode).forEach((x) => x.move({ x: dX, y: dY })));
212
+ Object.keys(MarkupMode2Konva).forEach((mode) =>
213
+ this.konvaLayerFind(mode).forEach((ref) => ref.move({ x: dX, y: dY }))
214
+ );
258
215
  };
259
216
 
260
217
  redirectToViewer = (event: any) => {
@@ -267,7 +224,7 @@ export class KonvaMarkup implements IMarkup {
267
224
  this.removeTextInput();
268
225
  this.removeImageInput();
269
226
  this._konvaTransformer.nodes([]);
270
- Object.values(MarkupMode).forEach((mode) => this.konvaLayerFind(mode).forEach((x) => x.destroy()));
227
+ Object.keys(MarkupMode2Konva).forEach((mode) => this.konvaLayerFind(mode).forEach((ref) => ref.destroy()));
271
228
  }
272
229
 
273
230
  getMarkupColor(): { r: number; g: number; b: number } {
@@ -280,10 +237,11 @@ export class KonvaMarkup implements IMarkup {
280
237
 
281
238
  colorizeAllMarkup(r = 255, g = 0, b = 0): void {
282
239
  const hex = new MarkupColor(r, g, b).HexColor;
283
- Object.values(MarkupMode).forEach((mode) => {
284
- this.konvaLayerFind(mode).forEach((x) => {
285
- const konvaObj = MarkupMode2Konva.get(mode)?.initializer(x);
286
- if (konvaObj && konvaObj.setColor) konvaObj.setColor(hex);
240
+ Object.keys(MarkupMode2Konva).forEach((mode) => {
241
+ this.konvaLayerFind(mode).forEach((ref) => {
242
+ const konvaShape = MarkupMode2Konva[mode];
243
+ const konvaObj = konvaShape.initializer(ref);
244
+ if (konvaObj.setColor) konvaObj.setColor(hex);
287
245
  });
288
246
  });
289
247
 
@@ -377,31 +335,31 @@ export class KonvaMarkup implements IMarkup {
377
335
 
378
336
  getObjects(): IMarkupObject[] {
379
337
  const objects = [];
380
- this.konvaLayerFind(MarkupMode.Line).forEach((line) => {
338
+ this.konvaLayerFind("Line").forEach((line) => {
381
339
  objects.push(new KonvaLine(null, line));
382
340
  });
383
341
 
384
- this.konvaLayerFind(MarkupMode.Text).forEach((text) => {
342
+ this.konvaLayerFind("Text").forEach((text) => {
385
343
  objects.push(new KonvaText(null, text));
386
344
  });
387
345
 
388
- this.konvaLayerFind(MarkupMode.Rectangle).forEach((rectangle) => {
346
+ this.konvaLayerFind("Rectangle").forEach((rectangle) => {
389
347
  objects.push(new KonvaRectangle(null, rectangle));
390
348
  });
391
349
 
392
- this.konvaLayerFind(MarkupMode.Ellipse).forEach((ellipse) => {
350
+ this.konvaLayerFind("Ellipse").forEach((ellipse) => {
393
351
  objects.push(new KonvaEllipse(null, ellipse));
394
352
  });
395
353
 
396
- this.konvaLayerFind(MarkupMode.Arrow).forEach((arrow) => {
354
+ this.konvaLayerFind("Arrow").forEach((arrow) => {
397
355
  objects.push(new KonvaArrow(null, arrow));
398
356
  });
399
357
 
400
- this.konvaLayerFind(MarkupMode.Image).forEach((image) => {
358
+ this.konvaLayerFind("Image").forEach((image) => {
401
359
  objects.push(new KonvaImage(null, image));
402
360
  });
403
361
 
404
- this.konvaLayerFind(MarkupMode.Cloud).forEach((cloud) => {
362
+ this.konvaLayerFind("Cloud").forEach((cloud) => {
405
363
  objects.push(new KonvaCloud(null, cloud));
406
364
  });
407
365
 
@@ -511,12 +469,11 @@ export class KonvaMarkup implements IMarkup {
511
469
  this._konvaLayer.add(object.ref());
512
470
  }
513
471
 
514
- private konvaLayerFind(markupShape: MarkupMode): any {
515
- const konvaShape = MarkupMode2Konva.get(markupShape);
516
- if (konvaShape) {
517
- // for "draggable" Konva uses Rectangles in Transformer. We need only Shapes from Layer.
518
- const konvaShapes = this._konvaLayer.find(konvaShape.name).filter((x) => x.parent instanceof Konva.Layer);
519
- return konvaShapes;
472
+ private konvaLayerFind(markupShape: string): any {
473
+ const konvaShape = MarkupMode2Konva[markupShape];
474
+ if (konvaShape && konvaShape.initializer) {
475
+ // for "draggable" Konva uses Rectangles in Transformer. We need only Shapes from layer.
476
+ return this._konvaLayer.find(konvaShape.name).filter((ref) => ref.parent === this._konvaLayer);
520
477
  }
521
478
  return [];
522
479
  }
@@ -549,12 +506,7 @@ export class KonvaMarkup implements IMarkup {
549
506
 
550
507
  stage.on("mousedown touchstart", (e) => {
551
508
  // do nothing if we mousedown on any shape
552
- if (
553
- !this._markupIsActive ||
554
- e.target !== stage ||
555
- this._markupMode === MarkupMode.Text ||
556
- this._markupMode === MarkupMode.Image
557
- )
509
+ if (!this._markupIsActive || e.target !== stage || this._markupMode === "Text" || this._markupMode === "Image")
558
510
  return;
559
511
 
560
512
  if (e.target === stage && transformer.nodes().length > 0) {
@@ -565,10 +517,8 @@ export class KonvaMarkup implements IMarkup {
565
517
  const pos = stage.getPointerPosition();
566
518
  mouseDownPos = pos;
567
519
 
568
- isPaint = [MarkupMode.Arrow, MarkupMode.Cloud, MarkupMode.Ellipse, MarkupMode.Line, MarkupMode.Rectangle].some(
569
- (m) => m === this._markupMode
570
- );
571
- if (this._markupMode === MarkupMode.Line) {
520
+ isPaint = ["Arrow", "Cloud", "Ellipse", "Line", "Rectangle"].some((m) => m === this._markupMode);
521
+ if (this._markupMode === "Line") {
572
522
  // add point twice, so we have some drawings even on a simple click
573
523
  lastLine = this.addLine([pos.x, pos.y, pos.x, pos.y]);
574
524
  }
@@ -585,16 +535,16 @@ export class KonvaMarkup implements IMarkup {
585
535
  const dX = defParams ? 200 : Math.abs(mouseDownPos.x - pos.x);
586
536
  const dY = defParams ? 200 : Math.abs(mouseDownPos.y - pos.y);
587
537
  if (defParams) {
588
- if (this._markupMode === MarkupMode.Rectangle) {
538
+ if (this._markupMode === "Rectangle") {
589
539
  this.addRectangle({ x: startX, y: startY }, dX, dY);
590
- } else if (this._markupMode === MarkupMode.Ellipse) {
540
+ } else if (this._markupMode === "Ellipse") {
591
541
  this.addEllipse({ x: startX, y: startY }, { x: dX / 2, y: dY / 2 });
592
- } else if (this._markupMode === MarkupMode.Arrow) {
542
+ } else if (this._markupMode === "Arrow") {
593
543
  this.addArrow(
594
544
  { x: mouseDownPos.x, y: mouseDownPos.y },
595
545
  { x: defParams ? mouseDownPos.x + 200 : pos.x, y: defParams ? startY : pos.y }
596
546
  );
597
- } else if (this._markupMode === MarkupMode.Cloud) {
547
+ } else if (this._markupMode === "Cloud") {
598
548
  this.addCloud({ x: startX, y: startY }, Math.max(100, dX), Math.max(100, dY));
599
549
  }
600
550
  }
@@ -620,24 +570,24 @@ export class KonvaMarkup implements IMarkup {
620
570
  const dX = defParams ? 200 : Math.abs(mouseDownPos.x - pos.x);
621
571
  const dY = defParams ? 200 : Math.abs(mouseDownPos.y - pos.y);
622
572
 
623
- if (this._markupMode === MarkupMode.Line) {
573
+ if (this._markupMode === "Line") {
624
574
  lastLine.addPoints([{ x: pos.x, y: pos.y }]);
625
- } else if (this._markupMode === MarkupMode.Arrow) {
575
+ } else if (this._markupMode === "Arrow") {
626
576
  if (lastObj) lastObj.setEndPoint(pos.x, pos.y);
627
577
  else lastObj = this.addArrow({ x: mouseDownPos.x, y: mouseDownPos.y }, { x: pos.x, y: pos.y });
628
- } else if (this._markupMode === MarkupMode.Rectangle) {
578
+ } else if (this._markupMode === "Rectangle") {
629
579
  if (lastObj) {
630
580
  lastObj.setPosition(startX, startY);
631
581
  lastObj.setWidth(dX);
632
582
  lastObj.setHeight(dY);
633
583
  } else lastObj = this.addRectangle({ x: startX, y: startY }, dX, dY);
634
- } else if (this._markupMode === MarkupMode.Ellipse) {
584
+ } else if (this._markupMode === "Ellipse") {
635
585
  if (lastObj) {
636
586
  lastObj.setPosition(startX, startY);
637
587
  lastObj.setRadiusX(dX);
638
588
  lastObj.setRadiusY(dY);
639
589
  } else lastObj = this.addEllipse({ x: startX, y: startY }, { x: dX, y: dY });
640
- } else if (this._markupMode === MarkupMode.Cloud) {
590
+ } else if (this._markupMode === "Cloud") {
641
591
  if (lastObj) {
642
592
  lastObj.setPosition(startX, startY);
643
593
  lastObj.setWidth(Math.max(100, dX));
@@ -652,14 +602,14 @@ export class KonvaMarkup implements IMarkup {
652
602
 
653
603
  // if click on empty area - remove all selections
654
604
  if (e.target === stage) {
655
- if (this._markupMode === MarkupMode.Text) {
605
+ if (this._markupMode === "Text") {
656
606
  if (this._textInputRef && this._textInputRef.value)
657
607
  this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle);
658
608
  else if (transformer.nodes().length === 0) {
659
609
  const pos = stage.getPointerPosition();
660
610
  this.createTextInput(pos, e.evt.pageX, e.evt.pageY, 0, null);
661
611
  }
662
- } else if (this._markupMode === MarkupMode.Image) {
612
+ } else if (this._markupMode === "Image") {
663
613
  if (this._imageInputRef && this._imageInputRef.value)
664
614
  this.addImage(
665
615
  { x: this._imageInputPos.x, y: this._imageInputPos.y },
@@ -677,7 +627,7 @@ export class KonvaMarkup implements IMarkup {
677
627
  return;
678
628
  }
679
629
 
680
- if (this._markupMode === MarkupMode.Text || this._markupMode === MarkupMode.SelectMarkup) {
630
+ if (this._markupMode === "Text" || this._markupMode === "SelectMarkup") {
681
631
  if (e.target.className === "Text" && transformer.nodes().length === 1 && transformer.nodes()[0] === e.target) {
682
632
  if (this._textInputRef && this._textInputRef.value)
683
633
  this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle);
@@ -695,7 +645,7 @@ export class KonvaMarkup implements IMarkup {
695
645
  }
696
646
  }
697
647
 
698
- if (this._markupMode === MarkupMode.Image || this._markupMode === MarkupMode.SelectMarkup) {
648
+ if (this._markupMode === "Image" || this._markupMode === "SelectMarkup") {
699
649
  if (e.target.className === "Image" && transformer.nodes().length === 1 && transformer.nodes()[0] === e.target) {
700
650
  if (this._imageInputRef && this._imageInputRef.value)
701
651
  this.addImage(this._imageInputPos, this._imageInputRef.value, 0, 0);
@@ -767,7 +717,7 @@ export class KonvaMarkup implements IMarkup {
767
717
 
768
718
  private getMarkupLines() {
769
719
  const lines = [];
770
- this.konvaLayerFind(MarkupMode.Line).forEach((line) => {
720
+ this.konvaLayerFind("Line").forEach((line) => {
771
721
  const linePoints = line.points();
772
722
  if (!linePoints) return;
773
723
  const worldPoints = [];
@@ -800,7 +750,7 @@ export class KonvaMarkup implements IMarkup {
800
750
  const textSize = 0.02;
801
751
  const textScale = this._worldTransformer.getScale();
802
752
 
803
- this.konvaLayerFind(MarkupMode.Text).forEach((text) => {
753
+ this.konvaLayerFind("Text").forEach((text) => {
804
754
  if (!text) return;
805
755
 
806
756
  const position = this._worldTransformer.screenToWorld({
@@ -825,7 +775,7 @@ export class KonvaMarkup implements IMarkup {
825
775
 
826
776
  private getMarkupRectangles() {
827
777
  const rectangles = [];
828
- this.konvaLayerFind(MarkupMode.Rectangle).forEach((rect) => {
778
+ this.konvaLayerFind("Rectangle").forEach((rect) => {
829
779
  const position = rect.position();
830
780
  const worldPoint = this._worldTransformer.screenToWorld(position);
831
781
 
@@ -845,7 +795,7 @@ export class KonvaMarkup implements IMarkup {
845
795
 
846
796
  private getMarkupEllipses() {
847
797
  const ellipses = [];
848
- this.konvaLayerFind(MarkupMode.Ellipse).forEach((ellipse) => {
798
+ this.konvaLayerFind("Ellipse").forEach((ellipse) => {
849
799
  const position = ellipse.position();
850
800
  const worldPoint = this._worldTransformer.screenToWorld(position);
851
801
 
@@ -864,7 +814,7 @@ export class KonvaMarkup implements IMarkup {
864
814
 
865
815
  private getMarkupArrows() {
866
816
  const arrows = [];
867
- this.konvaLayerFind(MarkupMode.Arrow).forEach((arrow) => {
817
+ this.konvaLayerFind("Arrow").forEach((arrow) => {
868
818
  // we need getAbsoluteTransform because inside Konva position starts from {0, 0}
869
819
  const absoluteTransform = arrow.getAbsoluteTransform();
870
820
 
@@ -888,7 +838,7 @@ export class KonvaMarkup implements IMarkup {
888
838
 
889
839
  private getMarkupImages() {
890
840
  const images = [];
891
- this.konvaLayerFind(MarkupMode.Image).forEach((image) => {
841
+ this.konvaLayerFind("Image").forEach((image) => {
892
842
  const position = image.position();
893
843
  const worldPoint = this._worldTransformer.screenToWorld(position);
894
844
 
@@ -907,7 +857,7 @@ export class KonvaMarkup implements IMarkup {
907
857
 
908
858
  private getMarkupClouds() {
909
859
  const clouds = [];
910
- this.konvaLayerFind(MarkupMode.Cloud).forEach((cloud) => {
860
+ this.konvaLayerFind("Cloud").forEach((cloud) => {
911
861
  const position = cloud.position();
912
862
  const worldPoint = this._worldTransformer.screenToWorld(position);
913
863