@inweb/markup 25.7.10 → 25.8.1

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.
@@ -0,0 +1,23 @@
1
+ export declare class WorldTransform {
2
+ screenToWorld(position: {
3
+ x: number;
4
+ y: number;
5
+ }): {
6
+ x: number;
7
+ y: number;
8
+ z: number;
9
+ };
10
+ worldToScreen(position: {
11
+ x: number;
12
+ y: number;
13
+ z: number;
14
+ }): {
15
+ x: number;
16
+ y: number;
17
+ };
18
+ getScale(): {
19
+ x: number;
20
+ y: number;
21
+ z: number;
22
+ };
23
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inweb/markup",
3
- "version": "25.7.10",
3
+ "version": "25.8.1",
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.10",
30
- "@inweb/viewer-core": "~25.7.10"
29
+ "@inweb/eventemitter2": "~25.8.1",
30
+ "@inweb/viewer-core": "~25.8.1"
31
31
  },
32
32
  "devDependencies": {
33
33
  "canvas": "^2.11.2",
@@ -31,6 +31,7 @@ import { IMarkupObject } from "../IMarkupObject";
31
31
  import { IMarkupColorable } from "../IMarkupColorable";
32
32
  import { MarkupLineType } from "../IMarkupLine";
33
33
  import { MarkupColor } from "./MarkupColor";
34
+ import { WorldTransform } from "../WorldTransform";
34
35
  import { KonvaLine } from "./KonvaLine";
35
36
  import { KonvaText } from "./KonvaText";
36
37
  import { KonvaRectangle } from "./KonvaRectangle";
@@ -46,31 +47,37 @@ const MarkupMode2Konva = {
46
47
  },
47
48
  Line: {
48
49
  name: "Line",
49
- initializer: (ref: any) => new KonvaLine(null, ref),
50
+ initializer: (ref: any, params = null) => new KonvaLine(params, ref),
51
+ zIndex: 1,
50
52
  },
51
53
  Text: {
52
54
  name: "Text",
53
- initializer: (ref: any) => new KonvaText(null, ref),
55
+ initializer: (ref: any, params = null) => new KonvaText(params, ref),
54
56
  },
55
57
  Rectangle: {
56
58
  name: "Rect",
57
- initializer: (ref: any) => new KonvaRectangle(null, ref),
59
+ initializer: (ref: any, params = null) => new KonvaRectangle(params, ref),
60
+ zIndex: 1,
58
61
  },
59
62
  Ellipse: {
60
63
  name: "Ellipse",
61
- initializer: (ref: any) => new KonvaEllipse(null, ref),
64
+ initializer: (ref: any, params = null) => new KonvaEllipse(params, ref),
65
+ zIndex: 1,
62
66
  },
63
67
  Arrow: {
64
68
  name: "Arrow",
65
- initializer: (ref: any) => new KonvaArrow(null, ref),
69
+ initializer: (ref: any, params = null) => new KonvaArrow(params, ref),
70
+ zIndex: 1,
66
71
  },
67
72
  Image: {
68
73
  name: "Image",
69
- initializer: (ref: any) => new KonvaImage(null, ref),
74
+ initializer: (ref: any, params = null) => new KonvaImage(params, ref),
75
+ zIndex: 0,
70
76
  },
71
77
  Cloud: {
72
78
  name: "Cloud",
73
79
  initializer: (ref: any) => new KonvaCloud(null, ref),
80
+ zIndex: 1,
74
81
  },
75
82
  };
76
83
 
@@ -117,7 +124,7 @@ export class KonvaMarkup implements IMarkup {
117
124
  );
118
125
 
119
126
  this._viewer = viewer;
120
- this._worldTransformer = worldTransformer;
127
+ this._worldTransformer = worldTransformer ?? new WorldTransform();
121
128
  this._container = container;
122
129
  this._pointerEvents = pointerEvents ?? [];
123
130
 
@@ -202,10 +209,7 @@ export class KonvaMarkup implements IMarkup {
202
209
  pan = (event: PanEvent) => {
203
210
  const dX = event.dX / window.devicePixelRatio;
204
211
  const dY = event.dY / window.devicePixelRatio;
205
-
206
- Object.keys(MarkupMode2Konva).forEach((mode) =>
207
- this.konvaLayerFind(mode).forEach((ref) => ref.move({ x: dX, y: dY }))
208
- );
212
+ this.getObjects().forEach((obj) => obj.ref().move({ x: dX, y: dY }));
209
213
  };
210
214
 
211
215
  redirectToViewer = (event: any) => {
@@ -217,8 +221,8 @@ export class KonvaMarkup implements IMarkup {
217
221
  clearOverlay(): void {
218
222
  this.removeTextInput();
219
223
  this.removeImageInput();
220
- this._konvaTransformer.nodes([]);
221
- Object.keys(MarkupMode2Konva).forEach((mode) => this.konvaLayerFind(mode).forEach((ref) => ref.destroy()));
224
+ this.clearSelected();
225
+ this.getObjects().forEach((obj) => obj.ref().destroy());
222
226
  }
223
227
 
224
228
  getMarkupColor(): { r: number; g: number; b: number } {
@@ -229,25 +233,21 @@ export class KonvaMarkup implements IMarkup {
229
233
  this._markupColor.setColor(r, g, b);
230
234
  }
231
235
 
232
- colorizeAllMarkup(r = 255, g = 0, b = 0): void {
233
- const hex = new MarkupColor(r, g, b).HexColor;
234
- Object.keys(MarkupMode2Konva).forEach((mode) => {
235
- this.konvaLayerFind(mode).forEach((ref) => {
236
- const konvaShape = MarkupMode2Konva[mode];
237
- const konvaObj = konvaShape.initializer(ref);
238
- if (konvaObj.setColor) konvaObj.setColor(hex);
239
- });
236
+ colorizeAllMarkup(r: number, g: number, b: number): void {
237
+ const hexColor = new MarkupColor(r, g, b).HexColor;
238
+ this.getObjects().forEach((obj) => {
239
+ const colorable = obj as unknown as IMarkupColorable;
240
+ if (colorable && colorable.setColor) colorable.setColor(hexColor);
240
241
  });
241
242
 
242
243
  this._konvaLayer.draw();
243
244
  }
244
245
 
245
246
  colorizeSelectedMarkups(r: number, g: number, b: number): void {
247
+ const hexColor = new MarkupColor(r, g, b).HexColor;
246
248
  this.getSelectedObjects().forEach((obj) => {
247
249
  const colorable = obj as unknown as IMarkupColorable;
248
- if (colorable && colorable.setColor) {
249
- colorable.setColor(new MarkupColor(r, g, b).HexColor);
250
- }
250
+ if (colorable && colorable.setColor) colorable.setColor(hexColor);
251
251
  });
252
252
  }
253
253
 
@@ -295,115 +295,39 @@ export class KonvaMarkup implements IMarkup {
295
295
  }
296
296
 
297
297
  createObject(type: string, params: any): IMarkupObject {
298
- let object = null;
299
- let zIndex = this._zIndex;
300
-
301
- // TODO: factory?
302
- switch (type.toLocaleLowerCase()) {
303
- case "line":
304
- object = new KonvaLine(params);
305
- zIndex = 1;
306
- break;
307
- case "text":
308
- object = new KonvaText(params);
309
- break;
310
- case "rectangle":
311
- object = new KonvaRectangle(params);
312
- zIndex = 1;
313
- break;
314
- case "ellipse":
315
- object = new KonvaEllipse(params);
316
- zIndex = 1;
317
- break;
318
- case "arrow":
319
- object = new KonvaArrow(params);
320
- break;
321
- case "image":
322
- object = new KonvaImage(params);
323
- zIndex = 0;
324
- break;
325
- case "cloud":
326
- object = new KonvaCloud(params);
327
- zIndex = 1;
328
- break;
329
- default:
330
- throw new Error("Markup CreateObject - unsupported type has been detected.");
331
- }
298
+ const konvaShape = MarkupMode2Konva[type];
299
+ if (!konvaShape || !konvaShape.initializer)
300
+ throw new Error(`Markup CreateObject - unsupported markup type ${type}`);
332
301
 
302
+ const object = konvaShape.initializer(null, params);
333
303
  this.addObject(object);
334
304
 
335
- // Set zIndex only when shape has been added to Layer else we will get "Konva warning: Node has no parent. zIndex parameter is ignored."
336
- object.setZIndex(zIndex);
305
+ // Set zIndex only when shape has been added to Layer else we will get
306
+ // "Konva warning: Node has no parent. zIndex parameter is ignored."
307
+ object.setZIndex(konvaShape.zIndex ?? this._zIndex);
337
308
  this._zIndex++;
309
+
338
310
  return object;
339
311
  }
340
312
 
341
313
  getObjects(): IMarkupObject[] {
342
314
  const objects = [];
343
- this.konvaLayerFind("Line").forEach((line) => {
344
- objects.push(new KonvaLine(null, line));
315
+ Object.keys(MarkupMode2Konva).forEach((type) => {
316
+ const konvaShape = MarkupMode2Konva[type];
317
+ this.konvaLayerFind(type).forEach((ref) => objects.push(konvaShape.initializer(ref)));
345
318
  });
346
-
347
- this.konvaLayerFind("Text").forEach((text) => {
348
- objects.push(new KonvaText(null, text));
349
- });
350
-
351
- this.konvaLayerFind("Rectangle").forEach((rectangle) => {
352
- objects.push(new KonvaRectangle(null, rectangle));
353
- });
354
-
355
- this.konvaLayerFind("Ellipse").forEach((ellipse) => {
356
- objects.push(new KonvaEllipse(null, ellipse));
357
- });
358
-
359
- this.konvaLayerFind("Arrow").forEach((arrow) => {
360
- objects.push(new KonvaArrow(null, arrow));
361
- });
362
-
363
- this.konvaLayerFind("Image").forEach((image) => {
364
- objects.push(new KonvaImage(null, image));
365
- });
366
-
367
- this.konvaLayerFind("Cloud").forEach((cloud) => {
368
- objects.push(new KonvaCloud(null, cloud));
369
- });
370
-
371
319
  return objects;
372
320
  }
373
321
 
374
322
  getSelectedObjects(): IMarkupObject[] {
375
- const objects = [];
376
-
377
- this._konvaTransformer.nodes().forEach((obj) => {
378
- const konvaShapeName = obj.className;
379
- switch (konvaShapeName) {
380
- case "Line":
381
- objects.push(new KonvaLine(null, obj));
382
- break;
383
- case "Text":
384
- objects.push(new KonvaText(null, obj));
385
- break;
386
- case "Rect":
387
- objects.push(new KonvaRectangle(null, obj));
388
- break;
389
- case "Ellipse":
390
- objects.push(new KonvaEllipse(null, obj));
391
- break;
392
- case "Arrow":
393
- objects.push(new KonvaArrow(null, obj));
394
- break;
395
- case "Image":
396
- objects.push(new KonvaImage(null, obj));
397
- break;
398
- case "Cloud":
399
- objects.push(new KonvaCloud(null, obj));
400
- break;
401
- default:
402
- break;
403
- }
404
- });
405
-
406
- return objects;
323
+ return this._konvaTransformer
324
+ .nodes()
325
+ .map((ref) => {
326
+ const name = ref.className;
327
+ const konvaShape = Object.values(MarkupMode2Konva).find((shape) => shape.name === name);
328
+ return konvaShape ? konvaShape.initializer(ref) : null;
329
+ })
330
+ .filter((x) => x);
407
331
  }
408
332
 
409
333
  selectObjects(objects: IMarkupObject[]) {
@@ -415,10 +339,6 @@ export class KonvaMarkup implements IMarkup {
415
339
  this._konvaTransformer.nodes([]);
416
340
  }
417
341
 
418
- private getPoint3dFromArray(array) {
419
- return { x: array[0], y: array[1], z: array[2] };
420
- }
421
-
422
342
  private fillViewpointShapes(viewpoint) {
423
343
  const markupLines = this.getMarkupLines();
424
344
  if (markupLines && markupLines.length > 0) {
@@ -474,8 +394,8 @@ export class KonvaMarkup implements IMarkup {
474
394
  this._konvaLayer.add(object.ref());
475
395
  }
476
396
 
477
- private konvaLayerFind(markupShape: string): any {
478
- const konvaShape = MarkupMode2Konva[markupShape];
397
+ private konvaLayerFind(type: string): any {
398
+ const konvaShape = MarkupMode2Konva[type];
479
399
  if (konvaShape && konvaShape.initializer) {
480
400
  // for "draggable" Konva uses Rectangles in Transformer. We need only Shapes from layer.
481
401
  return this._konvaLayer.find(konvaShape.name).filter((ref) => ref.parent === this._konvaLayer);
@@ -739,7 +659,7 @@ export class KonvaMarkup implements IMarkup {
739
659
  const konvaLine = new KonvaLine(null, line);
740
660
  lines.push({
741
661
  id: konvaLine.id(),
742
- points: worldPoints.map((p) => this.getPoint3dFromArray(p)),
662
+ points: worldPoints,
743
663
  color: konvaLine.getColor() || "#ff0000",
744
664
  type: konvaLine.getLineType() || this.lineType,
745
665
  width: konvaLine.getLineWidth() || this.lineWidth,
@@ -758,15 +678,13 @@ export class KonvaMarkup implements IMarkup {
758
678
  this.konvaLayerFind("Text").forEach((text) => {
759
679
  if (!text) return;
760
680
 
761
- const position = this._worldTransformer.screenToWorld({
762
- x: text.x(),
763
- y: text.y(),
764
- });
681
+ const position = { x: text.x(), y: text.y() };
682
+ const worldPoint = this._worldTransformer.screenToWorld(position);
765
683
 
766
684
  const shape = new KonvaText(null, text);
767
685
  texts.push({
768
686
  id: shape.id(),
769
- position: this.getPoint3dFromArray(position),
687
+ position: worldPoint,
770
688
  text: shape.getText(),
771
689
  text_size: textSize * textScale.y,
772
690
  angle: shape.getRotation(),
@@ -787,7 +705,7 @@ export class KonvaMarkup implements IMarkup {
787
705
  const shape = new KonvaRectangle(null, rect);
788
706
  rectangles.push({
789
707
  id: shape.id(),
790
- position: this.getPoint3dFromArray(worldPoint),
708
+ position: worldPoint,
791
709
  width: shape.getWidth(),
792
710
  height: shape.getHeigth(),
793
711
  line_width: shape.getLineWidth(),
@@ -807,7 +725,7 @@ export class KonvaMarkup implements IMarkup {
807
725
  const shape = new KonvaEllipse(null, ellipse);
808
726
  ellipses.push({
809
727
  id: shape.id(),
810
- position: this.getPoint3dFromArray(worldPoint),
728
+ position: worldPoint,
811
729
  radius: { x: ellipse.getRadiusX(), y: ellipse.getRadiusY() },
812
730
  line_width: shape.getLineWidth(),
813
731
  color: shape.getColor(),
@@ -832,8 +750,8 @@ export class KonvaMarkup implements IMarkup {
832
750
  const shape = new KonvaArrow(null, arrow);
833
751
  arrows.push({
834
752
  id: shape.id(),
835
- start: this.getPoint3dFromArray(worldStartPoint),
836
- end: this.getPoint3dFromArray(worldEndPoint),
753
+ start: worldStartPoint,
754
+ end: worldEndPoint,
837
755
  color: shape.getColor(),
838
756
  });
839
757
  });
@@ -850,7 +768,7 @@ export class KonvaMarkup implements IMarkup {
850
768
  const shape = new KonvaImage(null, image);
851
769
  images.push({
852
770
  id: shape.id(),
853
- position: this.getPoint3dFromArray(worldPoint),
771
+ position: worldPoint,
854
772
  src: shape.getSrc(),
855
773
  width: shape.getWidth(),
856
774
  height: shape.getHeight(),
@@ -869,7 +787,7 @@ export class KonvaMarkup implements IMarkup {
869
787
  const shape = new KonvaCloud(null, cloud);
870
788
  clouds.push({
871
789
  id: shape.id(),
872
- position: this.getPoint3dFromArray(worldPoint),
790
+ position: worldPoint,
873
791
  width: shape.getWidth(),
874
792
  height: shape.getHeigth(),
875
793
  line_width: shape.getLineWidth(),
@@ -0,0 +1,36 @@
1
+ ///////////////////////////////////////////////////////////////////////////////
2
+ // Copyright (C) 2002-2024, Open Design Alliance (the "Alliance").
3
+ // All rights reserved.
4
+ //
5
+ // This software and its documentation and related materials are owned by
6
+ // the Alliance. The software may only be incorporated into application
7
+ // programs owned by members of the Alliance, subject to a signed
8
+ // Membership Agreement and Supplemental Software License Agreement with the
9
+ // Alliance. The structure and organization of this software are the valuable
10
+ // trade secrets of the Alliance and its suppliers. The software is also
11
+ // protected by copyright law and international treaty provisions. Application
12
+ // programs incorporating this software must include the following statement
13
+ // with their copyright notices:
14
+ //
15
+ // This application incorporates Open Design Alliance software pursuant to a
16
+ // license agreement with Open Design Alliance.
17
+ // Open Design Alliance Copyright (C) 2002-2024 by Open Design Alliance.
18
+ // All rights reserved.
19
+ //
20
+ // By use of this software, its documentation or related materials, you
21
+ // acknowledge and accept the above terms.
22
+ ///////////////////////////////////////////////////////////////////////////////
23
+
24
+ export class WorldTransform {
25
+ screenToWorld(position: { x: number; y: number }): { x: number; y: number; z: number } {
26
+ return { x: position.x, y: position.y, z: 0 };
27
+ }
28
+
29
+ worldToScreen(position: { x: number; y: number; z: number }): { x: number; y: number } {
30
+ return { x: position.x, y: position.y };
31
+ }
32
+
33
+ getScale(): { x: number; y: number; z: number } {
34
+ return { x: 1, y: 1, z: 1 };
35
+ }
36
+ }