@inweb/markup 25.8.3 → 25.8.4

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.
@@ -95,11 +95,10 @@ const MarkupMode2Konva = {
95
95
  * 2D markup core.
96
96
  */
97
97
  export class KonvaMarkup implements IMarkup {
98
- private _isInitialized = false;
99
98
  private _viewer: IEventEmitter;
100
99
  private _worldTransformer: IWorldTransform;
101
100
  private _container: HTMLElement;
102
- private _pointerEvents: string[];
101
+ private _pointerEvents: string[] = [];
103
102
  private _markupIsActive = false;
104
103
  private _markupMode: MarkupMode;
105
104
  private _markupColor = new MarkupColor(255, 0, 0);
@@ -116,8 +115,6 @@ export class KonvaMarkup implements IMarkup {
116
115
  private _resizeObserver: ResizeObserver;
117
116
  private _zIndex = 1;
118
117
 
119
- private readonly _markupContainerName = "markupContainer";
120
-
121
118
  public lineWidth = 4;
122
119
  public lineType: MarkupLineType = "solid";
123
120
  public fontSize = 34;
@@ -128,10 +125,12 @@ export class KonvaMarkup implements IMarkup {
128
125
  viewer?: IEventEmitter,
129
126
  worldTransformer?: IWorldTransform
130
127
  ): void {
131
- if (!Konva)
132
- throw new Error(
133
- 'Markup: Error during initialization. Konva is not initialized. Update node_modules or add to your page <script src="https://unpkg.com/konva@9/konva.min.js"></script>'
128
+ if (!Konva) {
129
+ console.error(
130
+ 'Markup error: Konva is not initialized. Update node_modules or add to your page <script src="https://unpkg.com/konva@9/konva.min.js"></script>'
134
131
  );
132
+ return;
133
+ }
135
134
 
136
135
  this._viewer = viewer;
137
136
  this._worldTransformer = worldTransformer ?? new WorldTransform();
@@ -139,7 +138,7 @@ export class KonvaMarkup implements IMarkup {
139
138
  this._pointerEvents = pointerEvents ?? [];
140
139
 
141
140
  this._markupContainer = document.createElement("div");
142
- this._markupContainer.id = this._markupContainerName;
141
+ this._markupContainer.id = "markup-container";
143
142
  this._markupContainer.style.position = "absolute";
144
143
  this._markupContainer.style.top = "0px";
145
144
  this._markupContainer.style.left = "0px";
@@ -161,26 +160,21 @@ export class KonvaMarkup implements IMarkup {
161
160
  this._viewer.addEventListener("changeactivedragger", this.changeActiveDragger);
162
161
  this._viewer.addEventListener("pan", this.pan);
163
162
  }
164
-
165
- this._isInitialized = true;
166
163
  }
167
164
 
168
165
  dispose(): void {
169
- if (!this._isInitialized) return;
170
-
171
166
  if (this._viewer) {
172
167
  this._viewer.removeEventListener("pan", this.pan);
173
168
  this._viewer.removeEventListener("changeactivedragger", this.changeActiveDragger);
169
+ this._pointerEvents.forEach((x) => this._markupContainer.removeEventListener(x, this.redirectToViewer));
174
170
  }
175
171
 
176
- this._pointerEvents.forEach((x) => this._markupContainer.removeEventListener(x, this.redirectToViewer));
177
-
178
172
  this.destroyKonva();
179
173
 
180
- this._resizeObserver.disconnect();
174
+ this._resizeObserver?.disconnect();
181
175
  this._resizeObserver = undefined;
182
176
 
183
- this._markupContainer.remove();
177
+ this._markupContainer?.remove();
184
178
  this._markupContainer = undefined;
185
179
 
186
180
  this._container = undefined;
@@ -188,7 +182,6 @@ export class KonvaMarkup implements IMarkup {
188
182
  this._worldTransformer = undefined;
189
183
 
190
184
  this._markupIsActive = false;
191
- this._isInitialized = false;
192
185
  }
193
186
 
194
187
  changeActiveDragger = (event: ChangeActiveDraggerEvent) => {
@@ -211,9 +204,10 @@ export class KonvaMarkup implements IMarkup {
211
204
  const { width, height } = entries[0].contentRect;
212
205
 
213
206
  if (!width || !height) return; // <- invisible container, or container with parent removed
207
+ if (!this._konvaStage) return;
214
208
 
215
- this._konvaStage?.width(width);
216
- this._konvaStage?.height(height);
209
+ this._konvaStage.width(width);
210
+ this._konvaStage.height(height);
217
211
  };
218
212
 
219
213
  pan = (event: PanEvent) => {
@@ -232,7 +226,7 @@ export class KonvaMarkup implements IMarkup {
232
226
  this.removeTextInput();
233
227
  this.removeImageInput();
234
228
  this.clearSelected();
235
- this.getObjects().forEach((obj) => obj.ref().destroy());
229
+ this.getObjects().forEach((obj) => obj.delete());
236
230
  }
237
231
 
238
232
  getMarkupColor(): { r: number; g: number; b: number } {
@@ -354,6 +348,8 @@ export class KonvaMarkup implements IMarkup {
354
348
  }
355
349
 
356
350
  getSelectedObjects(): IMarkupObject[] {
351
+ if (!this._konvaTransformer) return [];
352
+
357
353
  return this._konvaTransformer
358
354
  .nodes()
359
355
  .map((ref) => {
@@ -365,35 +361,39 @@ export class KonvaMarkup implements IMarkup {
365
361
  }
366
362
 
367
363
  selectObjects(objects: IMarkupObject[]) {
364
+ if (!this._konvaTransformer) return;
365
+
368
366
  const selectedObjs = this._konvaTransformer.nodes().concat(objects.map((x) => x.ref()));
369
367
  this._konvaTransformer.nodes(selectedObjs);
370
368
  }
371
369
 
372
370
  clearSelected(): void {
373
- this._konvaTransformer.nodes([]);
371
+ if (this._konvaTransformer) this._konvaTransformer.nodes([]);
374
372
  }
375
373
 
376
374
  private addObject(object: IMarkupObject): void {
377
- this._konvaLayer.add(object.ref());
375
+ if (this._konvaLayer) this._konvaLayer.add(object.ref());
378
376
  }
379
377
 
380
378
  private konvaLayerFind(type: string): any {
379
+ if (!this._konvaLayer) return [];
380
+
381
381
  const konvaShape = MarkupMode2Konva[type];
382
- if (konvaShape && konvaShape.initializer) {
383
- // for "draggable" Konva uses Rectangles in Transformer. We need only Shapes from layer.
384
- return this._konvaLayer.find(konvaShape.name).filter((ref) => ref.parent === this._konvaLayer);
385
- }
386
- return [];
382
+ if (!konvaShape || !konvaShape.initializer) return [];
383
+
384
+ // for "draggable" Konva uses Rectangles in Transformer. We need only Shapes from layer.
385
+ return this._konvaLayer.find(konvaShape.name).filter((ref) => ref.parent === this._konvaLayer);
387
386
  }
388
387
 
389
388
  private initializeKonva(): any {
390
389
  // first we need Konva core things: stage and layer
391
- this._konvaStage = new Konva.Stage({
392
- container: this._markupContainerName,
390
+ const stage = new Konva.Stage({
391
+ container: this._markupContainer,
393
392
  width: this._container.clientWidth,
394
393
  height: this._container.clientHeight,
395
394
  });
396
- const stage = this._konvaStage;
395
+ this._konvaStage = stage;
396
+
397
397
  const layer = new Konva.Layer({ pixelRation: window.devicePixelRatio });
398
398
  stage.add(layer);
399
399
  this._konvaLayer = layer;
@@ -403,9 +403,8 @@ export class KonvaMarkup implements IMarkup {
403
403
  keepRatio: false,
404
404
  flipEnabled: false,
405
405
  });
406
-
407
- this._konvaTransformer = transformer;
408
406
  layer.add(transformer);
407
+ this._konvaTransformer = transformer;
409
408
 
410
409
  let isPaint = false;
411
410
  let lastLine;
@@ -601,12 +600,8 @@ export class KonvaMarkup implements IMarkup {
601
600
  container.addEventListener("keydown", (e) => {
602
601
  if (!this._markupIsActive) return;
603
602
  if (e.code === "Delete") {
604
- const trNodes = this._konvaTransformer.nodes();
605
- if (trNodes.length > 0) {
606
- this._konvaTransformer.nodes().forEach((x) => x.destroy());
607
- this._konvaTransformer.nodes([]);
608
- }
609
- layer.draw();
603
+ this.getSelectedObjects().forEach((obj: IMarkupObject) => obj.delete());
604
+ this.clearSelected();
610
605
  return;
611
606
  }
612
607
  e.preventDefault();
@@ -616,7 +611,7 @@ export class KonvaMarkup implements IMarkup {
616
611
  private destroyKonva() {
617
612
  this.clearOverlay();
618
613
 
619
- this._konvaStage.destroy();
614
+ this._konvaStage?.destroy();
620
615
 
621
616
  this._konvaLayer = undefined;
622
617
  this._konvaTransformer = undefined;
@@ -659,10 +654,10 @@ export class KonvaMarkup implements IMarkup {
659
654
  private getMarkupTexts(): Array<IText> {
660
655
  const texts = [];
661
656
 
662
- const textSize = 0.02;
663
- const textScale = this._worldTransformer.getScale();
664
-
665
657
  this.konvaLayerFind("Text").forEach((ref) => {
658
+ const textSize = 0.02;
659
+ const textScale = this._worldTransformer.getScale();
660
+
666
661
  const position = { x: ref.x(), y: ref.y() };
667
662
  const worldPoint = this._worldTransformer.screenToWorld(position);
668
663
 
@@ -804,12 +799,14 @@ export class KonvaMarkup implements IMarkup {
804
799
  this.clearSelected();
805
800
 
806
801
  const tempCanvas = document.createElement("canvas");
807
- tempCanvas.width = this._konvaStage.width();
808
- tempCanvas.height = this._konvaStage.height();
802
+ if (this._konvaStage) {
803
+ tempCanvas.width = this._konvaStage.width();
804
+ tempCanvas.height = this._konvaStage.height();
809
805
 
810
- const ctx = tempCanvas.getContext("2d");
811
- if (this._container instanceof HTMLCanvasElement) ctx.drawImage(this._container, 0, 0);
812
- ctx.drawImage(this._konvaStage.toCanvas({ pixelRatio: window.devicePixelRatio }), 0, 0);
806
+ const ctx = tempCanvas.getContext("2d");
807
+ if (this._container instanceof HTMLCanvasElement) ctx.drawImage(this._container, 0, 0);
808
+ ctx.drawImage(this._konvaStage.toCanvas({ pixelRatio: window.devicePixelRatio }), 0, 0);
809
+ }
813
810
 
814
811
  return tempCanvas.toDataURL("image/jpeg", 0.25);
815
812
  }
@@ -836,7 +833,7 @@ export class KonvaMarkup implements IMarkup {
836
833
  id,
837
834
  });
838
835
 
839
- this._konvaLayer.add(konvaLine.ref());
836
+ this.addObject(konvaLine);
840
837
  return konvaLine;
841
838
  }
842
839
 
@@ -925,7 +922,7 @@ export class KonvaMarkup implements IMarkup {
925
922
  }
926
923
 
927
924
  private addText(
928
- specifiedText: string,
925
+ text: string,
929
926
  position: Konva.Vector2d,
930
927
  angle?: number,
931
928
  color?: string,
@@ -933,15 +930,12 @@ export class KonvaMarkup implements IMarkup {
933
930
  fontSize?: number,
934
931
  id?: string
935
932
  ): KonvaText | void {
936
- if (!specifiedText) return;
933
+ if (!text) return;
937
934
 
938
- const trNodes = this._konvaTransformer.nodes();
939
- if (trNodes.length > 0) {
940
- // in case of edit - remove old Konva.Text object
941
- trNodes[0].destroy();
942
- this._konvaTransformer.nodes([]);
943
- }
935
+ // in case of edit - remove old Konva.Text object
936
+ this.getSelectedObjects().at(0)?.delete();
944
937
 
938
+ this.clearSelected();
945
939
  this.removeTextInput();
946
940
 
947
941
  // in case we have old viewpoint without font_size
@@ -954,14 +948,14 @@ export class KonvaMarkup implements IMarkup {
954
948
 
955
949
  const konvaText = new KonvaText({
956
950
  position: { x: position.x, y: position.y },
957
- text: specifiedText,
951
+ text,
958
952
  rotation: angle,
959
953
  fontSize: fontSize || this.fontSize,
960
954
  color: color || this._markupColor.HexColor,
961
955
  id,
962
956
  });
963
957
 
964
- this._konvaLayer.add(konvaText.ref());
958
+ this.addObject(konvaText);
965
959
  return konvaText;
966
960
  }
967
961
 
@@ -984,7 +978,7 @@ export class KonvaMarkup implements IMarkup {
984
978
  id,
985
979
  });
986
980
 
987
- this._konvaLayer.add(konvaRectangle.ref());
981
+ this.addObject(konvaRectangle);
988
982
  return konvaRectangle;
989
983
  }
990
984
 
@@ -1005,7 +999,7 @@ export class KonvaMarkup implements IMarkup {
1005
999
  id,
1006
1000
  });
1007
1001
 
1008
- this._konvaLayer.add(konvaEllipse.ref());
1002
+ this.addObject(konvaEllipse);
1009
1003
  return konvaEllipse;
1010
1004
  }
1011
1005
 
@@ -1024,7 +1018,7 @@ export class KonvaMarkup implements IMarkup {
1024
1018
  id,
1025
1019
  });
1026
1020
 
1027
- this._konvaLayer.add(konvaArrow.ref());
1021
+ this.addObject(konvaArrow);
1028
1022
  return konvaArrow;
1029
1023
  }
1030
1024
 
@@ -1047,7 +1041,7 @@ export class KonvaMarkup implements IMarkup {
1047
1041
  id,
1048
1042
  });
1049
1043
 
1050
- this._konvaLayer.add(konvaCloud.ref());
1044
+ this.addObject(konvaCloud);
1051
1045
  return konvaCloud;
1052
1046
  }
1053
1047
 
@@ -1060,13 +1054,10 @@ export class KonvaMarkup implements IMarkup {
1060
1054
  ): KonvaImage | void {
1061
1055
  if (!position || !src) return;
1062
1056
 
1063
- const trNodes = this._konvaTransformer.nodes();
1064
- if (trNodes.length > 0) {
1065
- // in case of edit - remove old Image placeholder object
1066
- trNodes[0].destroy();
1067
- this._konvaTransformer.nodes([]);
1068
- }
1057
+ // in case of edit - remove old Image placeholder object
1058
+ this.getSelectedObjects().at(0)?.delete();
1069
1059
 
1060
+ this.clearSelected();
1070
1061
  this.removeImageInput();
1071
1062
 
1072
1063
  const konvaImage = new KonvaImage({
@@ -1077,7 +1068,7 @@ export class KonvaMarkup implements IMarkup {
1077
1068
  id,
1078
1069
  });
1079
1070
 
1080
- this._konvaLayer.add(konvaImage.ref());
1071
+ this.addObject(konvaImage);
1081
1072
  return konvaImage;
1082
1073
  }
1083
1074
  }