@inweb/viewer-visualize 25.3.21 → 25.3.23

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,20 +1,6 @@
1
1
  import { Viewer } from "../../Viewer";
2
2
  import { Point2d } from "./Geometry";
3
3
  import { OdaGeAction } from "./OdaGeAction";
4
- /**
5
- * A [Viewer]{@link Viewer} event that fires when the viewer needs to be updated.
6
- *
7
- * @property {string} type - `update`
8
- * @event update
9
- */
10
- /**
11
- * A [Viewer]{@link Viewer} event that fires when the user selects an entity with the mouse.
12
- *
13
- * @property {string} type - `select`
14
- * @property {OdTvSelectionSet} data - The set of selected entities. For more information, see
15
- * [OdTvSelectionSet](https://cloud.opendesign.com/docs/index.html#/vis/OdTvSelectionSet?id=odtvselectionset).
16
- * @event select
17
- */
18
4
  export declare class OdBaseDragger extends OdaGeAction {
19
5
  protected subject: Viewer;
20
6
  protected needInputText: boolean;
@@ -29,6 +29,7 @@ export interface IMarkup {
29
29
  b: number;
30
30
  };
31
31
  colorizeAllMarkup(r: number, g: number, b: number): void;
32
+ colorizeSelectedMarkups(r: number, g: number, b: number): void;
32
33
  setViewpoint(viewpoint: IViewpoint): void;
33
34
  getViewpoint(): IViewpoint;
34
35
  createObject(type: string, params: any): IMarkupObject;
@@ -17,6 +17,8 @@ export declare class KonvaMarkup implements IMarkup {
17
17
  private _textInputRef;
18
18
  private _textInputPos;
19
19
  private _textInputAngle;
20
+ private _imageInputRef;
21
+ private _imageInputPos;
20
22
  private _markupContainer;
21
23
  private _zIndex;
22
24
  private readonly _markupContainerName;
@@ -36,6 +38,7 @@ export declare class KonvaMarkup implements IMarkup {
36
38
  };
37
39
  setMarkupColor(r: number, g: number, b: number): void;
38
40
  colorizeAllMarkup(r?: number, g?: number, b?: number): void;
41
+ colorizeSelectedMarkups(r: number, g: number, b: number): void;
39
42
  setViewpoint(viewpoint: IViewpoint): void;
40
43
  getViewpoint(): IViewpoint;
41
44
  createObject(type: string, params: any): IMarkupObject;
@@ -61,6 +64,8 @@ export declare class KonvaMarkup implements IMarkup {
61
64
  private addLine;
62
65
  private createTextInput;
63
66
  private removeTextInput;
67
+ private createImageInput;
68
+ private removeImageInput;
64
69
  private addText;
65
70
  private addRectangle;
66
71
  private addEllipse;
@@ -22,6 +22,7 @@ export declare class VisualizeMarkup implements IMarkup {
22
22
  };
23
23
  setMarkupColor(r: number, g: number, b: number): void;
24
24
  colorizeAllMarkup(r?: number, g?: number, b?: number): void;
25
+ colorizeSelectedMarkups(r?: number, g?: number, b?: number): void;
25
26
  setViewpoint(viewpoint: IViewpoint): void;
26
27
  getViewpoint(): IViewpoint;
27
28
  getLayer(): any;
@@ -17,7 +17,7 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & OptionsEventM
17
17
  private _renderTime;
18
18
  protected _options: Options;
19
19
  protected _visualizeJsUrl: string;
20
- protected _abortControllerForReferences: AbortController | undefined;
20
+ protected _visualizeJs: any;
21
21
  private canvaseventlistener;
22
22
  draggerFactory: Map<string, typeof OdBaseDragger>;
23
23
  canvasEvents: string[];
@@ -25,9 +25,9 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & OptionsEventM
25
25
  private _resizeObserver;
26
26
  canvas: HTMLCanvasElement | undefined;
27
27
  markup: IMarkup;
28
- visualizeJs: any;
29
28
  _abortController: AbortController | undefined;
30
29
  _abortControllerForRequestMap: Map<string, AbortController> | undefined;
30
+ _abortControllerForReferences: AbortController | undefined;
31
31
  client: Client | undefined;
32
32
  /**
33
33
  * @param client - The `Client` instance that provides access to a server. Do not specify
@@ -122,6 +122,11 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & OptionsEventM
122
122
  */
123
123
  private scheduleUpdateAsync;
124
124
  updateAsync(maxScheduleUpdateTimeInMs?: number, maxScheduleUpdateCount?: number): Promise<void>;
125
+ /**
126
+ * Returns `VisualizeJS`
127
+ * {@link https://cloud.opendesign.com/docs/index.html#/visualizejs_api | module} instance.
128
+ */
129
+ get visualizeJs(): any;
125
130
  /**
126
131
  * Returns `VisualizeJS`
127
132
  * {@link https://cloud.opendesign.com/docs/index.html#/visualizejs_api | module} instance.
@@ -171,7 +176,7 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & OptionsEventM
171
176
  *
172
177
  * Fires:
173
178
  *
174
- * - {@link ChangeActiveDragger | changeactivedragger}
179
+ * - {@link ChangeActiveDraggerEvent | changeactivedragger}
175
180
  *
176
181
  * @param name - Dragger name. Can be one of the {@link Viewer#draggers | draggers} list.
177
182
  * @returns Returns active dragger instance or `null` if there is no dragger with the given name.
@@ -311,22 +316,28 @@ export declare class Viewer extends EventEmitter2<ViewerEventMap & OptionsEventM
311
316
  * @param b - `Blue` part of color.
312
317
  */
313
318
  colorizeAllMarkup(r?: number, g?: number, b?: number): void;
319
+ /**
320
+ * Colorize all selected markup entities with the specified color.
321
+ *
322
+ * @param r - `Red` part of color.
323
+ * @param g - `Green` part of color.
324
+ * @param b - `Blue` part of color.
325
+ */
326
+ colorizeSelectedMarkups(r?: number, g?: number, b?: number): void;
314
327
  /**
315
328
  * Add an empty markup entity to the overlay.
316
329
  */
317
330
  addMarkupEntity(entityName: string): any;
318
331
  /**
319
332
  * Draw a viewpoint. To get a list of available model viewpoints, use the
320
- * {@link Model#getViewpoints | Model.getViewpoints()} or
321
- * {@link File#getViewpoints | File.getViewpoints()}.
333
+ * {@link Model.getViewpoints()} or {@link File.getViewpoints()}.
322
334
  *
323
- * @param viewpoint - Viewpoint.
335
+ * @param viewpoint - Viewpoint data.
324
336
  */
325
337
  drawViewpoint(viewpoint: IViewpoint): void;
326
338
  /**
327
339
  * Create a viewpoint. To add a viewpoint to the list of model viewpoints, use the
328
- * {@link Model#saveViewpoint | Model.saveViewpoint()} or
329
- * {@link File#saveViewpoint | File.saveViewpoint()}.
340
+ * {@link Model.saveViewpoint()} or {@link File.saveViewpoint()}.
330
341
  */
331
342
  createViewpoint(): IViewpoint;
332
343
  private getPoint3dFromArray;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inweb/viewer-visualize",
3
- "version": "25.3.21",
3
+ "version": "25.3.23",
4
4
  "description": "3D CAD and BIM data Viewer powered by Visualize",
5
5
  "homepage": "https://cloud.opendesign.com/docs/index.html",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -25,7 +25,8 @@
25
25
  ],
26
26
  "scripts": {
27
27
  "build": "rollup -c rollup.config.js",
28
- "test": "karma start karma.conf.js"
28
+ "test": "karma start karma.conf.js",
29
+ "ts-docs": "typedoc"
29
30
  },
30
31
  "dependencies": {
31
32
  "@inweb/client": "^25.3.19",
@@ -31,22 +31,6 @@ const CLICK_DELTA = 5;
31
31
 
32
32
  const INTERACTIVITY_FPS = 24;
33
33
 
34
- /**
35
- * A [Viewer]{@link Viewer} event that fires when the viewer needs to be updated.
36
- *
37
- * @property {string} type - `update`
38
- * @event update
39
- */
40
-
41
- /**
42
- * A [Viewer]{@link Viewer} event that fires when the user selects an entity with the mouse.
43
- *
44
- * @property {string} type - `select`
45
- * @property {OdTvSelectionSet} data - The set of selected entities. For more information, see
46
- * [OdTvSelectionSet](https://cloud.opendesign.com/docs/index.html#/vis/OdTvSelectionSet?id=odtvselectionset).
47
- * @event select
48
- */
49
-
50
34
  export class OdBaseDragger extends OdaGeAction {
51
35
  protected subject: Viewer;
52
36
  protected needInputText: boolean;
@@ -33,6 +33,8 @@ export class KonvaImage implements IMarkupImage {
33
33
 
34
34
  this._canvasImage.onload = () => {
35
35
  this._ref.image(this._canvasImage);
36
+ if (this._ref.height() === 0) this._ref.height(this._canvasImage.height);
37
+ if (this._ref.width() === 0) this._ref.width(this._canvasImage.width);
36
38
  this._ratio = this._ref.height() === 0 || this._ref.width() === 0 ? 1 : this._ref.height() / this._ref.width();
37
39
  };
38
40
 
@@ -31,6 +31,7 @@ export interface IMarkup {
31
31
  setMarkupColor(r: number, g: number, b: number): void;
32
32
  getMarkupColor(): { r: number; g: number; b: number };
33
33
  colorizeAllMarkup(r: number, g: number, b: number): void;
34
+ colorizeSelectedMarkups(r: number, g: number, b: number): void;
34
35
  setViewpoint(viewpoint: IViewpoint): void;
35
36
  getViewpoint(): IViewpoint;
36
37
 
@@ -7,6 +7,7 @@ import { MarkupColor } from "./MarkupColor";
7
7
  import * as utils from "../../../Draggers/MeasureLineDragger/MeasureUtils";
8
8
  import { OdBaseDragger } from "../../../Draggers/Common/OdBaseDragger";
9
9
  import { IMarkupObject } from "../../Api/IMarkupObject";
10
+ import { IMarkupColorable } from "../../Api/IMarkupColorable";
10
11
  import { KonvaLine } from "../../Api/Impl/Konva/KonvaLine";
11
12
  import { KonvaText } from "../../Api/Impl/Konva/KonvaText";
12
13
  import { KonvaRectangle } from "../../Api/Impl/Konva/KonvaRectangle";
@@ -14,6 +15,12 @@ import { KonvaEllipse } from "../../Api/Impl/Konva/KonvaEllipse";
14
15
  import { KonvaArrow } from "../../Api/Impl/Konva/KonvaArrow";
15
16
  import { KonvaImage } from "../../Api/Impl/Konva/KonvaImage";
16
17
  import { KonvaCloud } from "../../Api/Impl/Konva/KonvaCloud";
18
+ import { IMarkupLine } from "../../Api/IMarkupLine";
19
+ import { IMarkupArrow } from "../../Api/IMarkupArrow";
20
+ import { IMarkupEllipse } from "../../Api/IMarkupEllipse";
21
+ import { IMarkupRectangle } from "../../Api/IMarkupRectangle";
22
+ import { IMarkupCloud } from "../../Api/IMarkupCloud";
23
+ import { IMarkupImage } from "../../Api/IMarkupImage";
17
24
 
18
25
  class KonvaShape {
19
26
  name: string;
@@ -102,6 +109,8 @@ export class KonvaMarkup implements IMarkup {
102
109
  private _textInputRef: HTMLTextAreaElement;
103
110
  private _textInputPos: Konva.Vector2d;
104
111
  private _textInputAngle: number;
112
+ private _imageInputRef: HTMLInputElement;
113
+ private _imageInputPos: Konva.Vector2d;
105
114
  private _markupContainer: HTMLDivElement;
106
115
  private _zIndex = 1;
107
116
 
@@ -177,6 +186,7 @@ export class KonvaMarkup implements IMarkup {
177
186
  .join(" ");
178
187
 
179
188
  this.removeTextInput();
189
+ this.removeImageInput();
180
190
 
181
191
  const markupMode = MarkupMode[draggerName];
182
192
  const konvaMode = MarkupMode2Konva.get(markupMode);
@@ -211,6 +221,7 @@ export class KonvaMarkup implements IMarkup {
211
221
 
212
222
  clearOverlay(): void {
213
223
  this.removeTextInput();
224
+ this.removeImageInput();
214
225
  this._konvaTransformer.nodes([]);
215
226
  Object.values(MarkupMode).forEach((mode) => this.konvaLayerFind(mode).forEach((x) => x.destroy()));
216
227
  }
@@ -235,6 +246,15 @@ export class KonvaMarkup implements IMarkup {
235
246
  this._konvaLayer.draw();
236
247
  }
237
248
 
249
+ colorizeSelectedMarkups(r: number, g: number, b: number): void {
250
+ this.getSelectedObjects().forEach((obj) => {
251
+ const colorable = obj as unknown as IMarkupColorable;
252
+ if (colorable && colorable.setColor) {
253
+ colorable.setColor(new MarkupColor(r, g, b).HexColor);
254
+ }
255
+ });
256
+ }
257
+
238
258
  setViewpoint(viewpoint: IViewpoint): void {
239
259
  const markupColor = viewpoint.custom_fields.markup_color || { r: 255, g: 0, b: 0 };
240
260
  this.setMarkupColor(markupColor.r, markupColor.g, markupColor.b);
@@ -480,10 +500,18 @@ export class KonvaMarkup implements IMarkup {
480
500
 
481
501
  let isPaint = false;
482
502
  let lastLine;
503
+ let mouseDownPos;
504
+ let lastObj;
483
505
 
484
506
  stage.on("mousedown touchstart", (e) => {
485
507
  // do nothing if we mousedown on any shape
486
- if (!this._markupIsActive || e.target !== stage || this._markupMode === MarkupMode.Text) return;
508
+ if (
509
+ !this._markupIsActive ||
510
+ e.target !== stage ||
511
+ this._markupMode === MarkupMode.Text ||
512
+ this._markupMode === MarkupMode.Image
513
+ )
514
+ return;
487
515
 
488
516
  if (e.target === stage && transformer.nodes().length > 0) {
489
517
  transformer.nodes([]);
@@ -491,27 +519,44 @@ export class KonvaMarkup implements IMarkup {
491
519
  }
492
520
 
493
521
  const pos = stage.getPointerPosition();
522
+ mouseDownPos = pos;
494
523
 
524
+ isPaint = [MarkupMode.Arrow, MarkupMode.Cloud, MarkupMode.Ellipse, MarkupMode.Line, MarkupMode.Rectangle].some(
525
+ (m) => m === this._markupMode
526
+ );
495
527
  if (this._markupMode === MarkupMode.Line) {
496
528
  // add point twice, so we have some drawings even on a simple click
497
529
  lastLine = this.addLine([pos.x, pos.y, pos.x, pos.y]);
498
-
499
- isPaint = true;
500
- }
501
- // 25.2 - currently only for debug purposes:
502
- else if (this._markupMode === MarkupMode.Rectangle) {
503
- this.addRectangle({ x: pos.x, y: pos.y }, 50, 50);
504
- } else if (this._markupMode === MarkupMode.Ellipse) {
505
- this.addEllipse({ x: pos.x, y: pos.y }, { x: 50, y: 50 });
506
- } else if (this._markupMode === MarkupMode.Arrow) {
507
- this.addArrow({ x: pos.x, y: pos.y }, { x: pos.x + 50, y: pos.y + 50 });
508
- } else if (this._markupMode === MarkupMode.Cloud) {
509
- this.addCloud({ x: pos.x, y: pos.y }, 200, 400);
510
530
  }
511
531
  });
512
532
 
513
533
  stage.on("mouseup touchend", (e) => {
514
534
  if (!this._markupIsActive) return;
535
+
536
+ if (isPaint) {
537
+ const pos = stage.getPointerPosition();
538
+ const defParams = mouseDownPos && pos.x === mouseDownPos.x && pos.y === mouseDownPos.y;
539
+ const startX = defParams ? mouseDownPos.x : Math.min(mouseDownPos.x, pos.x);
540
+ const startY = defParams ? mouseDownPos.y : Math.min(mouseDownPos.y, pos.y);
541
+ const dX = defParams ? 200 : Math.abs(mouseDownPos.x - pos.x);
542
+ const dY = defParams ? 200 : Math.abs(mouseDownPos.y - pos.y);
543
+ if (defParams) {
544
+ if (this._markupMode === MarkupMode.Rectangle) {
545
+ this.addRectangle({ x: startX, y: startY }, dX, dY);
546
+ } else if (this._markupMode === MarkupMode.Ellipse) {
547
+ this.addEllipse({ x: startX, y: startY }, { x: dX / 2, y: dY / 2 });
548
+ } else if (this._markupMode === MarkupMode.Arrow) {
549
+ this.addArrow(
550
+ { x: mouseDownPos.x, y: mouseDownPos.y },
551
+ { x: defParams ? mouseDownPos.x + 200 : pos.x, y: defParams ? startY : pos.y }
552
+ );
553
+ } else if (this._markupMode === MarkupMode.Cloud) {
554
+ this.addCloud({ x: startX, y: startY }, Math.max(100, dX), Math.max(100, dY));
555
+ }
556
+ }
557
+ }
558
+
559
+ lastObj = undefined;
515
560
  isPaint = false;
516
561
  });
517
562
 
@@ -525,8 +570,36 @@ export class KonvaMarkup implements IMarkup {
525
570
  //e.evt.preventDefault();
526
571
 
527
572
  const pos = stage.getPointerPosition();
528
- const newPoints = lastLine.points().concat([pos.x, pos.y]);
529
- lastLine.points(newPoints);
573
+ const defParams = mouseDownPos && pos.x === mouseDownPos.x && pos.y === mouseDownPos.y;
574
+ const startX = defParams ? mouseDownPos.x : Math.min(mouseDownPos.x, pos.x);
575
+ const startY = defParams ? mouseDownPos.y : Math.min(mouseDownPos.y, pos.y);
576
+ const dX = defParams ? 200 : Math.abs(mouseDownPos.x - pos.x);
577
+ const dY = defParams ? 200 : Math.abs(mouseDownPos.y - pos.y);
578
+
579
+ if (this._markupMode === MarkupMode.Line) {
580
+ lastLine.addPoints([{ x: pos.x, y: pos.y }]);
581
+ } else if (this._markupMode === MarkupMode.Arrow) {
582
+ if (lastObj) lastObj.setEndPoint(pos.x, pos.y);
583
+ else lastObj = this.addArrow({ x: mouseDownPos.x, y: mouseDownPos.y }, { x: pos.x, y: pos.y });
584
+ } else if (this._markupMode === MarkupMode.Rectangle) {
585
+ if (lastObj) {
586
+ lastObj.setPosition(startX, startY);
587
+ lastObj.setWidth(dX);
588
+ lastObj.setHeight(dY);
589
+ } else lastObj = this.addRectangle({ x: startX, y: startY }, dX, dY);
590
+ } else if (this._markupMode === MarkupMode.Ellipse) {
591
+ if (lastObj) {
592
+ lastObj.setPosition(startX, startY);
593
+ lastObj.setRadiusX(dX);
594
+ lastObj.setRadiusY(dY);
595
+ } else lastObj = this.addEllipse({ x: startX, y: startY }, { x: dX, y: dY });
596
+ } else if (this._markupMode === MarkupMode.Cloud) {
597
+ if (lastObj) {
598
+ lastObj.setPosition(startX, startY);
599
+ lastObj.setWidth(Math.max(100, dX));
600
+ lastObj.setHeight(Math.max(100, dY));
601
+ } else lastObj = this.addCloud({ x: startX, y: startY }, dX, dY);
602
+ }
530
603
  });
531
604
 
532
605
  // clicks should select/deselect shapes
@@ -536,18 +609,33 @@ export class KonvaMarkup implements IMarkup {
536
609
  // if click on empty area - remove all selections
537
610
  if (e.target === stage) {
538
611
  if (this._markupMode === MarkupMode.Text) {
539
- if (this._textInputRef) this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle);
612
+ if (this._textInputRef && this._textInputRef.value)
613
+ this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle);
540
614
  else if (transformer.nodes().length === 0) {
541
615
  const pos = stage.getPointerPosition();
542
616
  this.createTextInput(pos, e.evt.pageX, e.evt.pageY, 0, null);
543
617
  }
618
+ } else if (this._markupMode === MarkupMode.Image) {
619
+ if (this._imageInputRef && this._imageInputRef.value)
620
+ this.addImage(
621
+ { x: this._imageInputPos.x, y: this._imageInputPos.y },
622
+ this._imageInputRef.value,
623
+ 0,
624
+ 0,
625
+ this._imageInputRef.value
626
+ );
627
+ else if (transformer.nodes().length === 0) {
628
+ const pos = stage.getPointerPosition();
629
+ this.createImageInput(pos);
630
+ }
544
631
  }
545
632
  transformer.nodes([]);
546
633
  return;
547
634
  }
548
635
 
549
636
  if (e.target.className === "Text" && transformer.nodes().length === 1 && transformer.nodes()[0] === e.target) {
550
- if (this._textInputRef) this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle);
637
+ if (this._textInputRef && this._textInputRef.value)
638
+ this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle);
551
639
  else
552
640
  this.createTextInput(
553
641
  { x: e.target.attrs.x, y: e.target.attrs.y },
@@ -561,6 +649,15 @@ export class KonvaMarkup implements IMarkup {
561
649
  this.removeTextInput();
562
650
  }
563
651
 
652
+ if (e.target.className === "Image" && transformer.nodes().length === 1 && transformer.nodes()[0] === e.target) {
653
+ if (this._imageInputRef && this._imageInputRef.value)
654
+ this.addImage(this._imageInputPos, this._imageInputRef.value, 0, 0);
655
+ else this.createImageInput({ x: e.target.attrs.x, y: e.target.attrs.y });
656
+ return;
657
+ } else {
658
+ this.removeImageInput();
659
+ }
660
+
564
661
  if (transformer.nodes().filter((x) => x.className === "Cloud").length > 0 || e.target.className === "Cloud") {
565
662
  transformer.rotateEnabled(false);
566
663
  } else {
@@ -922,7 +1019,7 @@ export class KonvaMarkup implements IMarkup {
922
1019
  type?: LineType,
923
1020
  width?: number,
924
1021
  id?: string
925
- ): Konva.Line | void {
1022
+ ): IMarkupLine | void {
926
1023
  if (!linePoints || linePoints.length === 0) return;
927
1024
  const points: { x: number; y: number }[] = [];
928
1025
  for (let i = 0; i < linePoints.length; i += 2) {
@@ -939,7 +1036,7 @@ export class KonvaMarkup implements IMarkup {
939
1036
 
940
1037
  const obj = konvaLine.ref();
941
1038
  this._konvaLayer.add(obj);
942
- return obj;
1039
+ return konvaLine;
943
1040
  }
944
1041
 
945
1042
  private createTextInput(pos: Konva.Vector2d, inputX: number, inputY: number, angle: number, text: string): void {
@@ -980,6 +1077,52 @@ export class KonvaMarkup implements IMarkup {
980
1077
  this._textInputAngle = 0;
981
1078
  }
982
1079
 
1080
+ private createImageInput(pos: Konva.Vector2d): void {
1081
+ if (!this._imageInputRef) {
1082
+ const convertBase64 = (file) => {
1083
+ return new Promise<string | ArrayBuffer>((resolve, reject) => {
1084
+ const fileReader = new FileReader();
1085
+ fileReader.readAsDataURL(file);
1086
+
1087
+ fileReader.onload = () => {
1088
+ resolve(fileReader.result);
1089
+ };
1090
+
1091
+ fileReader.onerror = (error) => {
1092
+ reject(error);
1093
+ };
1094
+ });
1095
+ };
1096
+
1097
+ this._imageInputPos = pos;
1098
+ this._imageInputRef = document.createElement("input");
1099
+ this._imageInputRef.style.display = "none";
1100
+ this._imageInputRef.type = "file";
1101
+ this._imageInputRef.accept = "image/png, image/jpeg";
1102
+ this._imageInputRef.onchange = async (event) => {
1103
+ const file = (event.target as HTMLInputElement).files[0];
1104
+ const base64 = await convertBase64(file);
1105
+ this.addImage({ x: this._imageInputPos.x, y: this._imageInputPos.y }, base64.toString(), 0, 0);
1106
+ };
1107
+ this._imageInputRef.oncancel = (event) => {
1108
+ this.removeImageInput();
1109
+ };
1110
+ document.body.appendChild(this._imageInputRef);
1111
+
1112
+ setTimeout(() => {
1113
+ this._imageInputRef.click();
1114
+ }, 50);
1115
+ } else {
1116
+ this.removeImageInput();
1117
+ }
1118
+ }
1119
+
1120
+ private removeImageInput(): void {
1121
+ this._imageInputRef?.remove();
1122
+ this._imageInputRef = null;
1123
+ this._imageInputPos = null;
1124
+ }
1125
+
983
1126
  private addText(
984
1127
  specifiedText: string,
985
1128
  position: Konva.Vector2d,
@@ -1037,7 +1180,7 @@ export class KonvaMarkup implements IMarkup {
1037
1180
  lineWidth?: number,
1038
1181
  color?: string,
1039
1182
  id?: string
1040
- ): Konva.Rect | void {
1183
+ ): IMarkupRectangle | void {
1041
1184
  if (!position) return;
1042
1185
 
1043
1186
  const konvaRectangle = new KonvaRectangle({
@@ -1051,7 +1194,7 @@ export class KonvaMarkup implements IMarkup {
1051
1194
 
1052
1195
  const obj = konvaRectangle.ref();
1053
1196
  this._konvaLayer.add(obj);
1054
- return obj;
1197
+ return konvaRectangle;
1055
1198
  }
1056
1199
 
1057
1200
  private addEllipse(
@@ -1060,7 +1203,7 @@ export class KonvaMarkup implements IMarkup {
1060
1203
  lineWidth?: number,
1061
1204
  color?: string,
1062
1205
  id?: string
1063
- ): Konva.Ellipse | void {
1206
+ ): IMarkupEllipse | void {
1064
1207
  if (!position) return;
1065
1208
 
1066
1209
  const konvaEllipse = new KonvaEllipse({
@@ -1073,7 +1216,7 @@ export class KonvaMarkup implements IMarkup {
1073
1216
 
1074
1217
  const obj = konvaEllipse.ref();
1075
1218
  this._konvaLayer.add(obj);
1076
- return obj;
1219
+ return konvaEllipse;
1077
1220
  }
1078
1221
 
1079
1222
  private addArrow(
@@ -1081,7 +1224,7 @@ export class KonvaMarkup implements IMarkup {
1081
1224
  end: { x: number; y: number },
1082
1225
  color?: string,
1083
1226
  id?: string
1084
- ): Konva.Arrow | void {
1227
+ ): IMarkupArrow | void {
1085
1228
  if (!start || !end) return;
1086
1229
 
1087
1230
  const konvaArrow = new KonvaArrow({
@@ -1093,7 +1236,7 @@ export class KonvaMarkup implements IMarkup {
1093
1236
 
1094
1237
  const obj = konvaArrow.ref();
1095
1238
  this._konvaLayer.add(obj);
1096
- return obj;
1239
+ return konvaArrow;
1097
1240
  }
1098
1241
 
1099
1242
  private addCloud(
@@ -1103,7 +1246,7 @@ export class KonvaMarkup implements IMarkup {
1103
1246
  lineWidth?: number,
1104
1247
  color?: string,
1105
1248
  id?: string
1106
- ): Konva.Shape | void {
1249
+ ): IMarkupCloud | void {
1107
1250
  if (!position || !width || !height) return;
1108
1251
 
1109
1252
  const konvaCloud = new KonvaCloud({
@@ -1117,28 +1260,40 @@ export class KonvaMarkup implements IMarkup {
1117
1260
 
1118
1261
  const obj = konvaCloud.ref();
1119
1262
  this._konvaLayer.add(obj);
1120
- return obj;
1263
+ return konvaCloud;
1121
1264
  }
1122
1265
 
1123
1266
  private addImage(
1124
1267
  position: { x: number; y: number },
1125
1268
  src: string,
1126
- width: number,
1127
- height: number,
1269
+ width?: number,
1270
+ height?: number,
1128
1271
  id?: string
1129
- ): Konva.Image | void {
1130
- if (!position || !width || !height) return;
1272
+ ): void {
1273
+ if (!position) return;
1131
1274
 
1132
- const konvaImage = new KonvaImage({
1133
- position,
1134
- src,
1135
- width,
1136
- height,
1137
- id,
1138
- });
1275
+ if (src) {
1276
+ const konvaImage = new KonvaImage({
1277
+ position,
1278
+ src,
1279
+ width,
1280
+ height,
1281
+ id,
1282
+ });
1139
1283
 
1140
- const obj = konvaImage.ref();
1141
- this._konvaLayer.add(obj);
1142
- return obj;
1284
+ const obj = konvaImage.ref();
1285
+ this._konvaLayer.add(obj);
1286
+
1287
+ const trNodes = this._konvaTransformer.nodes();
1288
+ if (trNodes.length > 0) {
1289
+ // in case of edit - remove old Image placeholder object
1290
+ trNodes[0].destroy();
1291
+ this._konvaTransformer.nodes([]);
1292
+ }
1293
+ }
1294
+
1295
+ this.removeImageInput();
1296
+
1297
+ return;
1143
1298
  }
1144
1299
  }
@@ -68,6 +68,10 @@ export class VisualizeMarkup implements IMarkup {
68
68
  this._viewer.update();
69
69
  }
70
70
 
71
+ colorizeSelectedMarkups(r = 255, g = 0, b = 0): void {
72
+ throw new Error("Not implemented yet");
73
+ }
74
+
71
75
  setViewpoint(viewpoint: IViewpoint): void {
72
76
  function getLogicalPoint3dAsArray(point3d) {
73
77
  return [point3d.x, point3d.y, point3d.z];