@inweb/client 25.2.2
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.
- package/LICENSE +20 -0
- package/README.md +70 -0
- package/dist/client.js +21126 -0
- package/dist/client.js.map +1 -0
- package/dist/client.min.js +1 -0
- package/dist/client.module.js +7151 -0
- package/dist/client.module.js.map +1 -0
- package/lib/Api/Assembly.d.ts +339 -0
- package/lib/Api/ClashTest.d.ts +176 -0
- package/lib/Api/Client.d.ts +452 -0
- package/lib/Api/ClientEvents.d.ts +29 -0
- package/lib/Api/File.d.ts +568 -0
- package/lib/Api/HttpClient.d.ts +13 -0
- package/lib/Api/IAssembly.d.ts +14 -0
- package/lib/Api/IFile.d.ts +46 -0
- package/lib/Api/IHttpClient.d.ts +11 -0
- package/lib/Api/IUser.d.ts +11 -0
- package/lib/Api/Job.d.ts +142 -0
- package/lib/Api/Member.d.ts +85 -0
- package/lib/Api/Model.d.ts +147 -0
- package/lib/Api/Permission.d.ts +93 -0
- package/lib/Api/Project.d.ts +247 -0
- package/lib/Api/Role.d.ts +82 -0
- package/lib/Api/User.d.ts +197 -0
- package/lib/Api/impl/FetchError.d.ts +18 -0
- package/lib/Api/impl/Utils.d.ts +33 -0
- package/lib/Api/impl/http.d.ts +67 -0
- package/lib/ConvetMath.d.ts +29 -0
- package/lib/Viewer/CanvasEvents.d.ts +2 -0
- package/lib/Viewer/Commands/ApplyModelTransform.d.ts +2 -0
- package/lib/Viewer/Commands/ClearMarkup.d.ts +2 -0
- package/lib/Viewer/Commands/ClearSlices.d.ts +2 -0
- package/lib/Viewer/Commands/CreatePreview.d.ts +2 -0
- package/lib/Viewer/Commands/Explode.d.ts +2 -0
- package/lib/Viewer/Commands/GetDefaultViewPositions.d.ts +2 -0
- package/lib/Viewer/Commands/GetModels.d.ts +2 -0
- package/lib/Viewer/Commands/GetSelected.d.ts +2 -0
- package/lib/Viewer/Commands/HideSelected.d.ts +2 -0
- package/lib/Viewer/Commands/IsolateSelected.d.ts +2 -0
- package/lib/Viewer/Commands/RegenerateAll.d.ts +2 -0
- package/lib/Viewer/Commands/ResetView.d.ts +2 -0
- package/lib/Viewer/Commands/SelectModel.d.ts +2 -0
- package/lib/Viewer/Commands/SetActiveDragger.d.ts +2 -0
- package/lib/Viewer/Commands/SetDefaultViewPosition.d.ts +2 -0
- package/lib/Viewer/Commands/SetMarkupColor.d.ts +2 -0
- package/lib/Viewer/Commands/SetSelected.d.ts +2 -0
- package/lib/Viewer/Commands/ShowAll.d.ts +2 -0
- package/lib/Viewer/Commands/Unselect.d.ts +2 -0
- package/lib/Viewer/Commands/ZoomToExtents.d.ts +2 -0
- package/lib/Viewer/Commands/ZoomToObjects.d.ts +2 -0
- package/lib/Viewer/Commands/ZoomToSelected.d.ts +2 -0
- package/lib/Viewer/Commands.d.ts +3 -0
- package/lib/Viewer/Draggers/Actions/OrbitAction.d.ts +22 -0
- package/lib/Viewer/Draggers/Actions/PanAction.d.ts +18 -0
- package/lib/Viewer/Draggers/Actions/ZoomAction.d.ts +8 -0
- package/lib/Viewer/Draggers/Common/Geometry.d.ts +115 -0
- package/lib/Viewer/Draggers/Common/GestureManager.d.ts +41 -0
- package/lib/Viewer/Draggers/Common/OdBaseDragger.d.ts +54 -0
- package/lib/Viewer/Draggers/Common/OdaGeAction.d.ts +30 -0
- package/lib/Viewer/Draggers/MeasureLineDragger/MeasureLineItem.d.ts +31 -0
- package/lib/Viewer/Draggers/MeasureLineDragger/MeasureUtils.d.ts +20 -0
- package/lib/Viewer/Draggers/MeasureLineDragger/index.d.ts +24 -0
- package/lib/Viewer/Draggers/OdBaseCuttingPlaneDragger.d.ts +27 -0
- package/lib/Viewer/Draggers/OdCuttingPlaneXAxisDragger.d.ts +8 -0
- package/lib/Viewer/Draggers/OdCuttingPlaneYAxisDragger.d.ts +8 -0
- package/lib/Viewer/Draggers/OdCuttingPlaneZAxisDragger.d.ts +8 -0
- package/lib/Viewer/Draggers/OdOrbitDragger.d.ts +15 -0
- package/lib/Viewer/Draggers/OdPanDragger.d.ts +12 -0
- package/lib/Viewer/Draggers/OdZoomDragger.d.ts +12 -0
- package/lib/Viewer/Draggers/OdZoomWheelDragger.d.ts +11 -0
- package/lib/Viewer/Draggers/OdZoomWindowDragger/OdSelectionFrame.d.ts +19 -0
- package/lib/Viewer/Draggers/OdZoomWindowDragger/index.d.ts +14 -0
- package/lib/Viewer/Draggers/OdaLineDragger.d.ts +15 -0
- package/lib/Viewer/Draggers/OdaTextDragger.d.ts +16 -0
- package/lib/Viewer/Draggers/OdaWalkDragger.d.ts +30 -0
- package/lib/Viewer/Draggers/OrbitAroundBuildingDragger.d.ts +19 -0
- package/lib/Viewer/EventEmitter2.d.ts +54 -0
- package/lib/Viewer/ICommands.d.ts +25 -0
- package/lib/Viewer/IEventEmitter2.d.ts +13 -0
- package/lib/Viewer/IViewer.d.ts +27 -0
- package/lib/Viewer/Loaders/BaseLoader.d.ts +11 -0
- package/lib/Viewer/Loaders/LoaderFactory.d.ts +10 -0
- package/lib/Viewer/Loaders/TCSLoader.d.ts +5 -0
- package/lib/Viewer/Loaders/UpdaterController.d.ts +15 -0
- package/lib/Viewer/Loaders/VsfXLoader.d.ts +5 -0
- package/lib/Viewer/Loaders/VsfXPartialLoader.d.ts +5 -0
- package/lib/Viewer/Markup/Api/IMarkupArrow.d.ts +12 -0
- package/lib/Viewer/Markup/Api/IMarkupColorable.d.ts +5 -0
- package/lib/Viewer/Markup/Api/IMarkupEllipse.d.ts +15 -0
- package/lib/Viewer/Markup/Api/IMarkupImage.d.ts +15 -0
- package/lib/Viewer/Markup/Api/IMarkupLine.d.ts +11 -0
- package/lib/Viewer/Markup/Api/IMarkupObject.d.ts +12 -0
- package/lib/Viewer/Markup/Api/IMarkupRectangle.d.ts +15 -0
- package/lib/Viewer/Markup/Api/IMarkupText.d.ts +13 -0
- package/lib/Viewer/Markup/Api/Impl/Konva/KonvaArrow.d.ts +32 -0
- package/lib/Viewer/Markup/Api/Impl/Konva/KonvaEllipse.d.ts +40 -0
- package/lib/Viewer/Markup/Api/Impl/Konva/KonvaImage.d.ts +36 -0
- package/lib/Viewer/Markup/Api/Impl/Konva/KonvaLine.d.ts +32 -0
- package/lib/Viewer/Markup/Api/Impl/Konva/KonvaRectangle.d.ts +38 -0
- package/lib/Viewer/Markup/Api/Impl/Konva/KonvaText.d.ts +37 -0
- package/lib/Viewer/Markup/IMarkup.d.ts +38 -0
- package/lib/Viewer/Markup/Impl/Konva/KonvaMarkup.d.ts +63 -0
- package/lib/Viewer/Markup/Impl/Konva/MarkupColor.d.ts +19 -0
- package/lib/Viewer/Markup/Impl/Visualize/VisualizeMarkup.d.ts +33 -0
- package/lib/Viewer/Markup/MarkupFactory.d.ts +7 -0
- package/lib/Viewer/Options.d.ts +228 -0
- package/lib/Viewer/OptionsEvents.d.ts +26 -0
- package/lib/Viewer/Viewer.d.ts +353 -0
- package/lib/Viewer/ViewerCommands.d.ts +23 -0
- package/lib/Viewer/ViewerEvents.d.ts +601 -0
- package/lib/Viewer/utils.d.ts +4 -0
- package/lib/index.d.ts +24 -0
- package/package.json +32 -0
- package/src/Api/Assembly.ts +678 -0
- package/src/Api/ClashTest.ts +290 -0
- package/src/Api/Client.ts +816 -0
- package/src/Api/ClientEvents.ts +31 -0
- package/src/Api/File.ts +962 -0
- package/src/Api/HttpClient.ts +73 -0
- package/src/Api/IAssembly.ts +37 -0
- package/src/Api/IFile.ts +74 -0
- package/src/Api/IHttpClient.ts +50 -0
- package/src/Api/IUser.ts +33 -0
- package/src/Api/Job.ts +253 -0
- package/src/Api/Member.ts +161 -0
- package/src/Api/Model.ts +259 -0
- package/src/Api/Permission.ts +173 -0
- package/src/Api/Project.ts +479 -0
- package/src/Api/Role.ts +158 -0
- package/src/Api/User.ts +357 -0
- package/src/Api/impl/FetchError.ts +48 -0
- package/src/Api/impl/Utils.ts +367 -0
- package/src/Api/impl/http.ts +92 -0
- package/src/ConvetMath.ts +372 -0
- package/src/Viewer/CanvasEvents.ts +41 -0
- package/src/Viewer/Commands/ApplyModelTransform.ts +70 -0
- package/src/Viewer/Commands/ClearMarkup.ts +28 -0
- package/src/Viewer/Commands/ClearSlices.ts +27 -0
- package/src/Viewer/Commands/CreatePreview.ts +33 -0
- package/src/Viewer/Commands/Explode.ts +38 -0
- package/src/Viewer/Commands/GetDefaultViewPositions.ts +36 -0
- package/src/Viewer/Commands/GetModels.ts +43 -0
- package/src/Viewer/Commands/GetSelected.ts +58 -0
- package/src/Viewer/Commands/HideSelected.ts +37 -0
- package/src/Viewer/Commands/IsolateSelected.ts +37 -0
- package/src/Viewer/Commands/RegenerateAll.ts +37 -0
- package/src/Viewer/Commands/ResetView.ts +43 -0
- package/src/Viewer/Commands/SelectModel.ts +52 -0
- package/src/Viewer/Commands/SetActiveDragger.ts +29 -0
- package/src/Viewer/Commands/SetDefaultViewPosition.ts +50 -0
- package/src/Viewer/Commands/SetMarkupColor.ts +29 -0
- package/src/Viewer/Commands/SetSelected.ts +47 -0
- package/src/Viewer/Commands/ShowAll.ts +37 -0
- package/src/Viewer/Commands/Unselect.ts +37 -0
- package/src/Viewer/Commands/ZoomToExtents.ts +43 -0
- package/src/Viewer/Commands/ZoomToObjects.ts +47 -0
- package/src/Viewer/Commands/ZoomToSelected.ts +39 -0
- package/src/Viewer/Commands.ts +81 -0
- package/src/Viewer/Draggers/Actions/OrbitAction.ts +250 -0
- package/src/Viewer/Draggers/Actions/PanAction.ts +102 -0
- package/src/Viewer/Draggers/Actions/ZoomAction.ts +45 -0
- package/src/Viewer/Draggers/Common/Geometry.ts +152 -0
- package/src/Viewer/Draggers/Common/GestureManager.ts +263 -0
- package/src/Viewer/Draggers/Common/OdBaseDragger.ts +270 -0
- package/src/Viewer/Draggers/Common/OdaGeAction.ts +146 -0
- package/src/Viewer/Draggers/MeasureLineDragger/MeasureLineItem.ts +248 -0
- package/src/Viewer/Draggers/MeasureLineDragger/MeasureUtils.ts +182 -0
- package/src/Viewer/Draggers/MeasureLineDragger/index.ts +166 -0
- package/src/Viewer/Draggers/OdBaseCuttingPlaneDragger.ts +182 -0
- package/src/Viewer/Draggers/OdCuttingPlaneXAxisDragger.ts +53 -0
- package/src/Viewer/Draggers/OdCuttingPlaneYAxisDragger.ts +53 -0
- package/src/Viewer/Draggers/OdCuttingPlaneZAxisDragger.ts +53 -0
- package/src/Viewer/Draggers/OdOrbitDragger.ts +70 -0
- package/src/Viewer/Draggers/OdPanDragger.ts +62 -0
- package/src/Viewer/Draggers/OdZoomDragger.ts +59 -0
- package/src/Viewer/Draggers/OdZoomWheelDragger.ts +103 -0
- package/src/Viewer/Draggers/OdZoomWindowDragger/OdSelectionFrame.ts +123 -0
- package/src/Viewer/Draggers/OdZoomWindowDragger/index.ts +75 -0
- package/src/Viewer/Draggers/OdaLineDragger.ts +80 -0
- package/src/Viewer/Draggers/OdaTextDragger.ts +118 -0
- package/src/Viewer/Draggers/OdaWalkDragger.ts +278 -0
- package/src/Viewer/Draggers/OrbitAroundBuildingDragger.ts +184 -0
- package/src/Viewer/EventEmitter2.ts +116 -0
- package/src/Viewer/ICommands.ts +53 -0
- package/src/Viewer/IEventEmitter2.ts +36 -0
- package/src/Viewer/IViewer.ts +55 -0
- package/src/Viewer/Loaders/BaseLoader.ts +40 -0
- package/src/Viewer/Loaders/LoaderFactory.ts +44 -0
- package/src/Viewer/Loaders/TCSLoader.ts +82 -0
- package/src/Viewer/Loaders/UpdaterController.ts +36 -0
- package/src/Viewer/Loaders/VsfXLoader.ts +87 -0
- package/src/Viewer/Loaders/VsfXPartialLoader.ts +208 -0
- package/src/Viewer/Markup/Api/IMarkupArrow.ts +15 -0
- package/src/Viewer/Markup/Api/IMarkupColorable.ts +4 -0
- package/src/Viewer/Markup/Api/IMarkupEllipse.ts +15 -0
- package/src/Viewer/Markup/Api/IMarkupImage.ts +15 -0
- package/src/Viewer/Markup/Api/IMarkupLine.ts +10 -0
- package/src/Viewer/Markup/Api/IMarkupObject.ts +15 -0
- package/src/Viewer/Markup/Api/IMarkupRectangle.ts +15 -0
- package/src/Viewer/Markup/Api/IMarkupText.ts +12 -0
- package/src/Viewer/Markup/Api/Impl/Konva/KonvaArrow.ts +119 -0
- package/src/Viewer/Markup/Api/Impl/Konva/KonvaEllipse.ts +113 -0
- package/src/Viewer/Markup/Api/Impl/Konva/KonvaImage.ts +121 -0
- package/src/Viewer/Markup/Api/Impl/Konva/KonvaLine.ts +99 -0
- package/src/Viewer/Markup/Api/Impl/Konva/KonvaRectangle.ts +113 -0
- package/src/Viewer/Markup/Api/Impl/Konva/KonvaText.ts +104 -0
- package/src/Viewer/Markup/IMarkup.ts +39 -0
- package/src/Viewer/Markup/Impl/Konva/KonvaMarkup.ts +872 -0
- package/src/Viewer/Markup/Impl/Konva/MarkupColor.ts +39 -0
- package/src/Viewer/Markup/Impl/Visualize/VisualizeMarkup.ts +273 -0
- package/src/Viewer/Markup/MarkupFactory.ts +32 -0
- package/src/Viewer/Options.ts +502 -0
- package/src/Viewer/OptionsEvents.ts +28 -0
- package/src/Viewer/Viewer.ts +1109 -0
- package/src/Viewer/ViewerCommands.ts +45 -0
- package/src/Viewer/ViewerEvents.ts +700 -0
- package/src/Viewer/utils.ts +74 -0
- package/src/index.ts +48 -0
|
@@ -0,0 +1,872 @@
|
|
|
1
|
+
import Konva from "konva";
|
|
2
|
+
import { IMarkup, MarkupMode } from "../../IMarkup";
|
|
3
|
+
import { Viewer } from "../../../Viewer";
|
|
4
|
+
import { ChangeActiveDraggerEvent, PanEvent } from "../../../ViewerEvents";
|
|
5
|
+
import { MarkupColor } from "./MarkupColor";
|
|
6
|
+
import * as utils from "../../../Draggers/MeasureLineDragger/MeasureUtils";
|
|
7
|
+
import { OdBaseDragger } from "../../../Draggers/Common/OdBaseDragger";
|
|
8
|
+
import { IMarkupObject } from "../../Api/IMarkupObject";
|
|
9
|
+
import { KonvaLine } from "../../Api/Impl/Konva/KonvaLine";
|
|
10
|
+
import { KonvaText } from "../../Api/Impl/Konva/KonvaText";
|
|
11
|
+
import { KonvaRectangle } from "../../Api/Impl/Konva/KonvaRectangle";
|
|
12
|
+
import { KonvaEllipse } from "../../Api/Impl/Konva/KonvaEllipse";
|
|
13
|
+
import { KonvaArrow } from "../../Api/Impl/Konva/KonvaArrow";
|
|
14
|
+
import { KonvaImage } from "../../Api/Impl/Konva/KonvaImage";
|
|
15
|
+
|
|
16
|
+
class KonvaShape {
|
|
17
|
+
name: string;
|
|
18
|
+
initializer: (ref: any) => any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// move to separate class and create factory with enum?
|
|
22
|
+
const MarkupMode2Konva = new Map<MarkupMode, KonvaShape>([
|
|
23
|
+
[
|
|
24
|
+
MarkupMode.Line,
|
|
25
|
+
{
|
|
26
|
+
name: "Line",
|
|
27
|
+
initializer: (ref) => {
|
|
28
|
+
return new KonvaLine(null, ref);
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
[
|
|
33
|
+
MarkupMode.Text,
|
|
34
|
+
{
|
|
35
|
+
name: "Text",
|
|
36
|
+
initializer: (ref) => {
|
|
37
|
+
return new KonvaText(null, ref);
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
MarkupMode.Rectangle,
|
|
43
|
+
{
|
|
44
|
+
name: "Rect",
|
|
45
|
+
initializer: (ref) => {
|
|
46
|
+
return new KonvaRectangle(null, ref);
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
[
|
|
51
|
+
MarkupMode.Ellipse,
|
|
52
|
+
{
|
|
53
|
+
name: "Ellipse",
|
|
54
|
+
initializer: (ref) => {
|
|
55
|
+
return new KonvaEllipse(null, ref);
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
[
|
|
60
|
+
MarkupMode.Arrow,
|
|
61
|
+
{
|
|
62
|
+
name: "Arrow",
|
|
63
|
+
initializer: (ref) => {
|
|
64
|
+
return new KonvaArrow(null, ref);
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
[
|
|
69
|
+
MarkupMode.Image,
|
|
70
|
+
{
|
|
71
|
+
name: "Image",
|
|
72
|
+
initializer: (ref) => {
|
|
73
|
+
return new KonvaImage(null, ref);
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
]);
|
|
78
|
+
|
|
79
|
+
export class KonvaMarkup implements IMarkup {
|
|
80
|
+
private _isInitialized = false;
|
|
81
|
+
private _viewer: Viewer;
|
|
82
|
+
private _canvasOriginal: HTMLCanvasElement;
|
|
83
|
+
private _canvasEvents: string[];
|
|
84
|
+
private _markupIsActive: boolean;
|
|
85
|
+
private _markupMode: MarkupMode;
|
|
86
|
+
private _markupColor: MarkupColor;
|
|
87
|
+
private _konvaStage: Konva.Stage;
|
|
88
|
+
private _konvaLayer: Konva.Layer;
|
|
89
|
+
private _konvaTransformer: Konva.Transformer;
|
|
90
|
+
|
|
91
|
+
private _textInputRef: HTMLTextAreaElement;
|
|
92
|
+
private _textInputPos: Konva.Vector2d;
|
|
93
|
+
private _textInputAngle: number;
|
|
94
|
+
private _markupContainer: HTMLDivElement;
|
|
95
|
+
private _zIndex = 1;
|
|
96
|
+
|
|
97
|
+
private readonly _markupContainerName = "markupContainer";
|
|
98
|
+
private readonly TEXT_FONT_FAMILY = "Calibri";
|
|
99
|
+
|
|
100
|
+
public lineWidth = 4;
|
|
101
|
+
|
|
102
|
+
initialize(viewer: Viewer, canvas: HTMLCanvasElement, canvasEvents: string[] = []): void {
|
|
103
|
+
if (!Konva)
|
|
104
|
+
throw new Error(
|
|
105
|
+
'Konva Markup: Error during Markup Initialization. Konva is not initialized. Update node_modules or add to your page <script src="https://unpkg.com/konva@9/konva.min.js"></script>'
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
this._viewer = viewer;
|
|
109
|
+
|
|
110
|
+
this._canvasOriginal = canvas;
|
|
111
|
+
this._canvasEvents = canvasEvents;
|
|
112
|
+
|
|
113
|
+
this._markupContainer = document.createElement("div");
|
|
114
|
+
this._markupContainer.id = this._markupContainerName;
|
|
115
|
+
this._markupContainer.style.position = "absolute";
|
|
116
|
+
this._markupContainer.style.top = "0px";
|
|
117
|
+
this._markupContainer.style.left = "0px";
|
|
118
|
+
// to eliminate grey box during delete elements
|
|
119
|
+
this._markupContainer.style.outline = "0px";
|
|
120
|
+
|
|
121
|
+
const parentDiv = this._canvasOriginal.parentElement;
|
|
122
|
+
parentDiv.appendChild(this._markupContainer);
|
|
123
|
+
|
|
124
|
+
this._markupColor = new MarkupColor(255, 0, 0);
|
|
125
|
+
this._markupIsActive = false;
|
|
126
|
+
|
|
127
|
+
this.initializeKonva();
|
|
128
|
+
this.resize();
|
|
129
|
+
|
|
130
|
+
this._canvasEvents.forEach((x) => this._markupContainer.addEventListener(x, this.redirectToViewer));
|
|
131
|
+
|
|
132
|
+
this._viewer.addEventListener("resize", this.resize);
|
|
133
|
+
this._viewer.addEventListener("changeactivedragger", this.changeActiveDragger);
|
|
134
|
+
this._viewer.addEventListener("pan", this.pan);
|
|
135
|
+
|
|
136
|
+
this._isInitialized = true;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
dispose(): void {
|
|
140
|
+
if (!this._isInitialized) return;
|
|
141
|
+
|
|
142
|
+
this._canvasEvents.forEach((x) => this._markupContainer.removeEventListener(x, this.redirectToViewer));
|
|
143
|
+
|
|
144
|
+
this._viewer.removeEventListener("pan", this.pan);
|
|
145
|
+
this._viewer.removeEventListener("changeactivedragger", this.changeActiveDragger);
|
|
146
|
+
this._viewer.removeEventListener("resize", this.resize);
|
|
147
|
+
|
|
148
|
+
this.destroyKonva();
|
|
149
|
+
|
|
150
|
+
this._markupContainer.remove();
|
|
151
|
+
|
|
152
|
+
this._markupContainer = undefined;
|
|
153
|
+
this._canvasOriginal = undefined;
|
|
154
|
+
this._viewer = undefined;
|
|
155
|
+
|
|
156
|
+
this._isInitialized = false;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
changeActiveDragger = (event: ChangeActiveDraggerEvent) => {
|
|
160
|
+
const draggerName = event.data;
|
|
161
|
+
|
|
162
|
+
this._markupContainer.className = this._canvasOriginal.className
|
|
163
|
+
.split(" ")
|
|
164
|
+
.filter((x) => !x.startsWith("oda-cursor-"))
|
|
165
|
+
.filter((x) => x)
|
|
166
|
+
.concat(`oda-cursor-${draggerName.toLowerCase()}`)
|
|
167
|
+
.join(" ");
|
|
168
|
+
|
|
169
|
+
this.removeTextInput();
|
|
170
|
+
|
|
171
|
+
const markupMode = MarkupMode[draggerName];
|
|
172
|
+
const konvaMode = MarkupMode2Konva.get(markupMode);
|
|
173
|
+
if (konvaMode) {
|
|
174
|
+
this._markupMode = markupMode;
|
|
175
|
+
this._markupIsActive = true;
|
|
176
|
+
} else {
|
|
177
|
+
this._markupIsActive = false;
|
|
178
|
+
this._konvaTransformer.nodes([]);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
resize = () => {
|
|
183
|
+
this._konvaStage?.width(this._canvasOriginal.clientWidth);
|
|
184
|
+
this._konvaStage?.height(this._canvasOriginal.clientHeight);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
pan = (event: PanEvent) => {
|
|
188
|
+
const dX = event.dX / window.devicePixelRatio;
|
|
189
|
+
const dY = event.dY / window.devicePixelRatio;
|
|
190
|
+
|
|
191
|
+
Object.values(MarkupMode).forEach((mode) => this.konvaLayerFind(mode).forEach((x) => x.move({ x: dX, y: dY })));
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
redirectToViewer = (event) => {
|
|
195
|
+
this._viewer.emit(event);
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
getDraggers(): Map<string, typeof OdBaseDragger> {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
clearOverlay(): void {
|
|
203
|
+
this.removeTextInput();
|
|
204
|
+
this._konvaTransformer.nodes([]);
|
|
205
|
+
Object.values(MarkupMode).forEach((mode) => this.konvaLayerFind(mode).forEach((x) => x.destroy()));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
getMarkupColor(): { r: number; g: number; b: number } {
|
|
209
|
+
return this._markupColor.RGB;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
setMarkupColor(r: number, g: number, b: number): void {
|
|
213
|
+
this._markupColor.setColor(r, g, b);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
colorizeAllMarkup(r = 255, g = 0, b = 0): void {
|
|
217
|
+
const hex = new MarkupColor(r, g, b).HexColor;
|
|
218
|
+
Object.values(MarkupMode).forEach((mode) => {
|
|
219
|
+
this.konvaLayerFind(mode).forEach((x) => {
|
|
220
|
+
const konvaObj = MarkupMode2Konva.get(mode).initializer(x);
|
|
221
|
+
if (konvaObj.setColor) konvaObj.setColor(hex);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
this._konvaLayer.draw();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
drawViewpoint(viewpoint: any): void {
|
|
229
|
+
function getLogicalPoint3dAsArray(point3d) {
|
|
230
|
+
return [point3d.x, point3d.y, point3d.z];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (!this._isInitialized) return;
|
|
234
|
+
if (!this._viewer.visualizeJs) return;
|
|
235
|
+
|
|
236
|
+
const visLib = this._viewer.visLib();
|
|
237
|
+
const visViewer = visLib.getViewer();
|
|
238
|
+
const activeView = visViewer.activeView;
|
|
239
|
+
|
|
240
|
+
this._viewer.resetActiveDragger();
|
|
241
|
+
this._viewer.clearSlices();
|
|
242
|
+
this._viewer.clearOverlay();
|
|
243
|
+
|
|
244
|
+
if (viewpoint.orthogonal_camera) {
|
|
245
|
+
activeView.setView(
|
|
246
|
+
getLogicalPoint3dAsArray(viewpoint.orthogonal_camera.view_point),
|
|
247
|
+
getLogicalPoint3dAsArray(viewpoint.orthogonal_camera.direction),
|
|
248
|
+
getLogicalPoint3dAsArray(viewpoint.orthogonal_camera.up_vector),
|
|
249
|
+
viewpoint.orthogonal_camera.field_width,
|
|
250
|
+
viewpoint.orthogonal_camera.field_height,
|
|
251
|
+
true
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
this._viewer.syncOverlay();
|
|
256
|
+
|
|
257
|
+
const markupColor = viewpoint.custom_fields.markup_color || { r: 255, g: 0, b: 0 };
|
|
258
|
+
this.setMarkupColor(markupColor.r, markupColor.g, markupColor.b);
|
|
259
|
+
|
|
260
|
+
if (viewpoint.clipping_planes) {
|
|
261
|
+
for (const plane of viewpoint.clipping_planes) {
|
|
262
|
+
const cuttingPlane = new visLib.OdTvPlane();
|
|
263
|
+
cuttingPlane.set(getLogicalPoint3dAsArray(plane.location), getLogicalPoint3dAsArray(plane.direction));
|
|
264
|
+
|
|
265
|
+
activeView.addCuttingPlane(cuttingPlane);
|
|
266
|
+
activeView.setEnableCuttingPlaneFill(true, 0x66, 0x66, 0x66);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
this.loadMarkup(viewpoint);
|
|
271
|
+
|
|
272
|
+
this._viewer.update();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
createViewpoint(): object {
|
|
276
|
+
function getLogicalPoint3dFromArray(array) {
|
|
277
|
+
return { x: array[0], y: array[1], z: array[2] };
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (!this._isInitialized) return {};
|
|
281
|
+
if (!this._viewer.visualizeJs) return {};
|
|
282
|
+
|
|
283
|
+
const visLib = this._viewer.visLib();
|
|
284
|
+
const visViewer = visLib.getViewer();
|
|
285
|
+
const activeView = visViewer.activeView;
|
|
286
|
+
|
|
287
|
+
const viewpoint = {
|
|
288
|
+
lines: [],
|
|
289
|
+
texts: [],
|
|
290
|
+
clipping_planes: [],
|
|
291
|
+
} as any;
|
|
292
|
+
|
|
293
|
+
viewpoint.orthogonal_camera = {
|
|
294
|
+
view_point: getLogicalPoint3dFromArray(activeView.viewPosition),
|
|
295
|
+
direction: getLogicalPoint3dFromArray(activeView.viewTarget),
|
|
296
|
+
up_vector: getLogicalPoint3dFromArray(activeView.upVector),
|
|
297
|
+
field_width: activeView.viewFieldWidth,
|
|
298
|
+
field_height: activeView.viewFieldHeight,
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
for (let i = 0; i < activeView.numCuttingPlanes(); i++) {
|
|
302
|
+
const cuttingPlane = activeView.getCuttingPlane(i);
|
|
303
|
+
|
|
304
|
+
const plane = {
|
|
305
|
+
location: getLogicalPoint3dFromArray(cuttingPlane.getOrigin()),
|
|
306
|
+
direction: getLogicalPoint3dFromArray(cuttingPlane.normal()),
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
viewpoint.clipping_planes.push(plane);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
viewpoint.snapshot = {
|
|
313
|
+
data: this.combineMarkupWithDrawing(),
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
viewpoint.custom_fields = {
|
|
317
|
+
markup_color: this.getMarkupColor(),
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
const markupLines = this.getMarkupLines();
|
|
321
|
+
if (markupLines && markupLines.length > 0) {
|
|
322
|
+
markupLines?.forEach((markupLine) => {
|
|
323
|
+
const line = {
|
|
324
|
+
points: [],
|
|
325
|
+
color: markupLine.color || "ff0000",
|
|
326
|
+
width: markupLine.width || 3,
|
|
327
|
+
};
|
|
328
|
+
for (const point of markupLine.points) {
|
|
329
|
+
line.points.push(getLogicalPoint3dFromArray(point));
|
|
330
|
+
}
|
|
331
|
+
viewpoint.lines.push(line);
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const markupTexts = this.getMarkupTexts();
|
|
336
|
+
if (markupTexts && markupTexts.length > 0) {
|
|
337
|
+
markupTexts?.forEach((markupText) => {
|
|
338
|
+
const text = {
|
|
339
|
+
position: getLogicalPoint3dFromArray(markupText.position),
|
|
340
|
+
text: markupText.text,
|
|
341
|
+
angle: markupText.rotation ?? 0,
|
|
342
|
+
text_size: markupText.size,
|
|
343
|
+
color: markupText.color,
|
|
344
|
+
};
|
|
345
|
+
viewpoint.texts.push(text);
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
viewpoint.description = new Date().toDateString();
|
|
350
|
+
return viewpoint;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
createObject(type: string, params: any): IMarkupObject {
|
|
354
|
+
let object;
|
|
355
|
+
let zIndex = this._zIndex;
|
|
356
|
+
|
|
357
|
+
// TODO: factory?
|
|
358
|
+
switch (type) {
|
|
359
|
+
case "line":
|
|
360
|
+
object = new KonvaLine(params);
|
|
361
|
+
zIndex = 1;
|
|
362
|
+
break;
|
|
363
|
+
case "text":
|
|
364
|
+
object = new KonvaText(params);
|
|
365
|
+
break;
|
|
366
|
+
case "rectangle":
|
|
367
|
+
object = new KonvaRectangle(params);
|
|
368
|
+
zIndex = 1;
|
|
369
|
+
break;
|
|
370
|
+
case "ellipse":
|
|
371
|
+
object = new KonvaEllipse(params);
|
|
372
|
+
zIndex = 1;
|
|
373
|
+
break;
|
|
374
|
+
case "arrow":
|
|
375
|
+
object = new KonvaArrow(params);
|
|
376
|
+
break;
|
|
377
|
+
case "image":
|
|
378
|
+
object = new KonvaImage(params);
|
|
379
|
+
zIndex = 0;
|
|
380
|
+
break;
|
|
381
|
+
default:
|
|
382
|
+
throw new Error("Markup CreateObject - unsupported type has been detected.");
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
this.addObject(object);
|
|
386
|
+
|
|
387
|
+
// Set zIndex only when shape has been added to Layer else we will get "Konva warning: Node has no parent. zIndex parameter is ignored."
|
|
388
|
+
object.setZIndex(zIndex);
|
|
389
|
+
this._zIndex++;
|
|
390
|
+
return object;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
getObjects(): IMarkupObject[] {
|
|
394
|
+
const objects = [];
|
|
395
|
+
this.konvaLayerFind(MarkupMode.Line).forEach((line) => {
|
|
396
|
+
objects.push(new KonvaLine(null, line));
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
this.konvaLayerFind(MarkupMode.Text).forEach((text) => {
|
|
400
|
+
objects.push(new KonvaText(null, text));
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
this.konvaLayerFind(MarkupMode.Rectangle).forEach((rectangle) => {
|
|
404
|
+
objects.push(new KonvaRectangle(null, rectangle));
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
this.konvaLayerFind(MarkupMode.Ellipse).forEach((ellipse) => {
|
|
408
|
+
objects.push(new KonvaEllipse(null, ellipse));
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
this.konvaLayerFind(MarkupMode.Arrow).forEach((arrow) => {
|
|
412
|
+
objects.push(new KonvaArrow(null, arrow));
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
this.konvaLayerFind(MarkupMode.Image).forEach((image) => {
|
|
416
|
+
objects.push(new KonvaImage(null, image));
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
return objects;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
getSelectedObjects(): IMarkupObject[] {
|
|
423
|
+
const objects = [];
|
|
424
|
+
|
|
425
|
+
this._konvaTransformer.nodes().forEach((obj) => {
|
|
426
|
+
const konvaShapeName = obj.className;
|
|
427
|
+
switch (konvaShapeName) {
|
|
428
|
+
case "Line":
|
|
429
|
+
objects.push(new KonvaLine(null, obj));
|
|
430
|
+
break;
|
|
431
|
+
case "Text":
|
|
432
|
+
objects.push(new KonvaText(null, obj));
|
|
433
|
+
break;
|
|
434
|
+
case "Rect":
|
|
435
|
+
objects.push(new KonvaRectangle(null, obj));
|
|
436
|
+
break;
|
|
437
|
+
case "Ellipse":
|
|
438
|
+
objects.push(new KonvaEllipse(null, obj));
|
|
439
|
+
break;
|
|
440
|
+
case "Arrow":
|
|
441
|
+
objects.push(new KonvaArrow(null, obj));
|
|
442
|
+
break;
|
|
443
|
+
case "Image":
|
|
444
|
+
objects.push(new KonvaImage(null, obj));
|
|
445
|
+
break;
|
|
446
|
+
default:
|
|
447
|
+
break;
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
return objects;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
selectObjects(objects: IMarkupObject[]) {
|
|
455
|
+
const selectedObjs = this._konvaTransformer.nodes().concat(objects.map((x) => x.ref()));
|
|
456
|
+
this._konvaTransformer.nodes(selectedObjs);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
clearSelected(): void {
|
|
460
|
+
this._konvaTransformer.nodes([]);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
private addObject(object: IMarkupObject): void {
|
|
464
|
+
this._konvaLayer.add(object.ref());
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
private konvaLayerFind(markupShape: MarkupMode): any {
|
|
468
|
+
const konvaShape = MarkupMode2Konva.get(markupShape);
|
|
469
|
+
if (konvaShape) {
|
|
470
|
+
// for "draggable" Konva uses Rectangles in Transformer. We need only Shapes from Layer.
|
|
471
|
+
const konvaShapes = this._konvaLayer.find(konvaShape.name).filter((x) => x.parent instanceof Konva.Layer);
|
|
472
|
+
return konvaShapes;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
private initializeKonva(): any {
|
|
477
|
+
// first we need Konva core things: stage and layer
|
|
478
|
+
this._konvaStage = new Konva.Stage({
|
|
479
|
+
container: this._markupContainerName,
|
|
480
|
+
width: this._canvasOriginal.clientWidth,
|
|
481
|
+
height: this._canvasOriginal.clientHeight,
|
|
482
|
+
});
|
|
483
|
+
const stage = this._konvaStage;
|
|
484
|
+
const layer = new Konva.Layer({ pixelRation: window.devicePixelRatio });
|
|
485
|
+
stage.add(layer);
|
|
486
|
+
this._konvaLayer = layer;
|
|
487
|
+
|
|
488
|
+
const transformer = new Konva.Transformer({
|
|
489
|
+
shouldOverdrawWholeArea: false,
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
this._konvaTransformer = transformer;
|
|
493
|
+
layer.add(transformer);
|
|
494
|
+
|
|
495
|
+
let isPaint = false;
|
|
496
|
+
let lastLine;
|
|
497
|
+
|
|
498
|
+
stage.on("mousedown touchstart", (e) => {
|
|
499
|
+
// do nothing if we mousedown on any shape
|
|
500
|
+
if (!this._markupIsActive || e.target !== stage || this._markupMode === MarkupMode.Text) return;
|
|
501
|
+
|
|
502
|
+
if (e.target === stage && transformer.nodes().length > 0) {
|
|
503
|
+
transformer.nodes([]);
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const pos = stage.getPointerPosition();
|
|
508
|
+
|
|
509
|
+
if (this._markupMode === MarkupMode.Line) {
|
|
510
|
+
// add point twice, so we have some drawings even on a simple click
|
|
511
|
+
lastLine = this.addLine([pos.x, pos.y, pos.x, pos.y]);
|
|
512
|
+
|
|
513
|
+
isPaint = true;
|
|
514
|
+
} else if (this._markupMode === MarkupMode.Rectangle) {
|
|
515
|
+
this.addRectangle({ x: pos.x, y: pos.y }, 50, 50);
|
|
516
|
+
} else if (this._markupMode === MarkupMode.Ellipse) {
|
|
517
|
+
this.addEllipse({ x: pos.x, y: pos.y }, { x: 50, y: 50 });
|
|
518
|
+
} else if (this._markupMode === MarkupMode.Arrow) {
|
|
519
|
+
this.addArrow([pos.x, pos.y, pos.x + 50, pos.y + 50], 5, 5);
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
stage.on("mouseup touchend", (e) => {
|
|
524
|
+
if (!this._markupIsActive) return;
|
|
525
|
+
isPaint = false;
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
stage.on("mousemove touchmove", (e) => {
|
|
529
|
+
if (!this._markupIsActive) return;
|
|
530
|
+
if (!isPaint) {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// prevent scrolling on touch devices
|
|
535
|
+
//e.evt.preventDefault();
|
|
536
|
+
|
|
537
|
+
const pos = stage.getPointerPosition();
|
|
538
|
+
const newPoints = lastLine.points().concat([pos.x, pos.y]);
|
|
539
|
+
lastLine.points(newPoints);
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
// clicks should select/deselect shapes
|
|
543
|
+
stage.on("click tap", (e) => {
|
|
544
|
+
if (!this._markupIsActive) return;
|
|
545
|
+
|
|
546
|
+
// if click on empty area - remove all selections
|
|
547
|
+
if (e.target === stage) {
|
|
548
|
+
if (this._markupMode === MarkupMode.Text) {
|
|
549
|
+
if (this._textInputRef) this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle);
|
|
550
|
+
else if (transformer.nodes().length === 0) {
|
|
551
|
+
const pos = stage.getPointerPosition();
|
|
552
|
+
this.createTextInput(pos, e.evt.pageX, e.evt.pageY, 0, null);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
transformer.nodes([]);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
if (e.target.className === "Text" && transformer.nodes().length === 1 && transformer.nodes()[0] === e.target) {
|
|
560
|
+
if (this._textInputRef) this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle);
|
|
561
|
+
else
|
|
562
|
+
this.createTextInput(
|
|
563
|
+
{ x: e.target.attrs.x, y: e.target.attrs.y },
|
|
564
|
+
e.evt.pageX,
|
|
565
|
+
e.evt.pageY,
|
|
566
|
+
e.target.attrs.rotation,
|
|
567
|
+
e.target.attrs.text
|
|
568
|
+
);
|
|
569
|
+
return;
|
|
570
|
+
} else {
|
|
571
|
+
this.removeTextInput();
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// do we pressed shift or ctrl?
|
|
575
|
+
const metaPressed = e.evt.shiftKey || e.evt.ctrlKey || e.evt.metaKey;
|
|
576
|
+
const isSelected = transformer.nodes().indexOf(e.target) >= 0;
|
|
577
|
+
|
|
578
|
+
if (!metaPressed && !isSelected) {
|
|
579
|
+
// if no key pressed and the node is not selected
|
|
580
|
+
// select just one
|
|
581
|
+
transformer.nodes([e.target]);
|
|
582
|
+
} else if (metaPressed && isSelected) {
|
|
583
|
+
// if we pressed keys and node was selected
|
|
584
|
+
// we need to remove it from selection:
|
|
585
|
+
const nodes = transformer.nodes().slice(); // use slice to have new copy of array
|
|
586
|
+
// remove node from array
|
|
587
|
+
nodes.splice(nodes.indexOf(e.target), 1);
|
|
588
|
+
transformer.nodes(nodes);
|
|
589
|
+
} else if (metaPressed && !isSelected) {
|
|
590
|
+
// add the node into selection
|
|
591
|
+
const nodes = transformer.nodes().concat([e.target]);
|
|
592
|
+
transformer.nodes(nodes);
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
const container = stage.container();
|
|
597
|
+
container.tabIndex = 1;
|
|
598
|
+
// focus it
|
|
599
|
+
// also stage will be in focus on its click
|
|
600
|
+
container.focus();
|
|
601
|
+
|
|
602
|
+
container.addEventListener("keydown", (e) => {
|
|
603
|
+
if (!this._markupIsActive) return;
|
|
604
|
+
if (e.code === "Delete") {
|
|
605
|
+
const trNodes = this._konvaTransformer.nodes();
|
|
606
|
+
if (trNodes.length > 0) {
|
|
607
|
+
this._konvaTransformer.nodes().forEach((x) => x.destroy());
|
|
608
|
+
this._konvaTransformer.nodes([]);
|
|
609
|
+
}
|
|
610
|
+
layer.draw();
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
e.preventDefault();
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
private destroyKonva() {
|
|
618
|
+
this.clearOverlay();
|
|
619
|
+
|
|
620
|
+
this._konvaStage.destroy();
|
|
621
|
+
|
|
622
|
+
this._konvaLayer = undefined;
|
|
623
|
+
this._konvaTransformer = undefined;
|
|
624
|
+
this._konvaStage = undefined;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
private getMarkupLines() {
|
|
628
|
+
const lines = [];
|
|
629
|
+
this.konvaLayerFind(MarkupMode.Line).forEach((line) => {
|
|
630
|
+
const linePoints = line.attrs.points;
|
|
631
|
+
if (!linePoints) return;
|
|
632
|
+
const worldPoints = [];
|
|
633
|
+
const absoluteTransform = line.getAbsoluteTransform();
|
|
634
|
+
for (let i = 0; i < linePoints.length; i += 2) {
|
|
635
|
+
// https://stackoverflow.com/a/57641487 - check answer's comments
|
|
636
|
+
const atPoint = absoluteTransform.point({ x: linePoints[i], y: linePoints[i + 1] });
|
|
637
|
+
const worldPoint = this._viewer
|
|
638
|
+
.visViewer()
|
|
639
|
+
.screenToWorld(atPoint.x * window.devicePixelRatio, atPoint.y * window.devicePixelRatio);
|
|
640
|
+
worldPoints.push(worldPoint);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
const konvaLine = new KonvaLine(null, line);
|
|
644
|
+
lines.push({
|
|
645
|
+
points: worldPoints,
|
|
646
|
+
color: konvaLine.getColor(),
|
|
647
|
+
width: konvaLine.getLineWidth(),
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
return lines;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
private getMarkupTexts() {
|
|
655
|
+
const texts = [];
|
|
656
|
+
|
|
657
|
+
const textSize = 0.02;
|
|
658
|
+
let textScale = 1.0;
|
|
659
|
+
|
|
660
|
+
const projMtrx = this._viewer.visViewer().activeView.projectionMatrix;
|
|
661
|
+
const mtrxNumber = projMtrx.get(1, 1);
|
|
662
|
+
const tol = 1.0e-6;
|
|
663
|
+
if (!(mtrxNumber < tol && mtrxNumber > -tol)) {
|
|
664
|
+
textScale = 1 / mtrxNumber;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
this.konvaLayerFind(MarkupMode.Text).forEach((text) => {
|
|
668
|
+
if (!text) return;
|
|
669
|
+
texts.push({
|
|
670
|
+
position: this._viewer
|
|
671
|
+
.visViewer()
|
|
672
|
+
.screenToWorld(text.attrs.x * window.devicePixelRatio, text.attrs.y * window.devicePixelRatio),
|
|
673
|
+
text: text.attrs.text,
|
|
674
|
+
rotation: text.attrs.rotation && Math.abs(text.attrs.rotation) > tol ? text.attrs.rotation : 0,
|
|
675
|
+
size: textSize * textScale,
|
|
676
|
+
color: text.attrs.fill,
|
|
677
|
+
});
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
return texts;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
private loadMarkup(viewpoint) {
|
|
684
|
+
const vpLines = viewpoint.lines;
|
|
685
|
+
vpLines?.forEach((vpLine) => {
|
|
686
|
+
const linePoints = [];
|
|
687
|
+
vpLine.points.forEach((point) => {
|
|
688
|
+
const screenPoint = utils.worldToScreen(
|
|
689
|
+
[point.x, point.y, point.z],
|
|
690
|
+
this._viewer.visualizeJs,
|
|
691
|
+
this._viewer.visViewer()
|
|
692
|
+
);
|
|
693
|
+
linePoints.push(screenPoint.x);
|
|
694
|
+
linePoints.push(screenPoint.y);
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
this.addLine(linePoints, vpLine.color, vpLine.width);
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
const vpTexts = viewpoint.texts;
|
|
701
|
+
vpTexts?.forEach((vpText) => {
|
|
702
|
+
const screenPoint = utils.worldToScreen(
|
|
703
|
+
[vpText.position.x, vpText.position.y, vpText.position.z],
|
|
704
|
+
this._viewer.visualizeJs,
|
|
705
|
+
this._viewer.visViewer()
|
|
706
|
+
);
|
|
707
|
+
this.addText(vpText.text, screenPoint, vpText.angle, vpText.color);
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
private combineMarkupWithDrawing() {
|
|
712
|
+
const trNodes = this._konvaTransformer.nodes();
|
|
713
|
+
if (trNodes.length > 0) {
|
|
714
|
+
this._konvaTransformer.nodes([]);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
const tempCanvas = document.createElement("canvas");
|
|
718
|
+
tempCanvas.height = this._canvasOriginal.height;
|
|
719
|
+
tempCanvas.width = this._canvasOriginal.width;
|
|
720
|
+
const ctx = tempCanvas.getContext("2d");
|
|
721
|
+
ctx.drawImage(this._canvasOriginal, 0, 0);
|
|
722
|
+
ctx.drawImage(this._konvaStage.toCanvas({ pixelRatio: window.devicePixelRatio }), 0, 0);
|
|
723
|
+
return tempCanvas.toDataURL("image/jpeg", 0.25);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
private addLine(linePoints: number[], color?: string, width?: number): Konva.Line | void {
|
|
727
|
+
if (!linePoints || linePoints.length === 0) return;
|
|
728
|
+
const points: { x: number; y: number }[] = [];
|
|
729
|
+
for (let i = 0; i < linePoints.length; i += 2) {
|
|
730
|
+
points.push({ x: linePoints[i], y: linePoints[i + 1] });
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
const konvaLine = new KonvaLine({
|
|
734
|
+
points,
|
|
735
|
+
color: color || this._markupColor.HexColor,
|
|
736
|
+
width: width || this.lineWidth,
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
const obj = konvaLine.ref();
|
|
740
|
+
this._konvaLayer.add(obj);
|
|
741
|
+
return obj;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
private createTextInput(pos: Konva.Vector2d, inputX: number, inputY: number, angle: number, text: string): void {
|
|
745
|
+
if (!this._textInputRef) {
|
|
746
|
+
this._textInputPos = pos;
|
|
747
|
+
this._textInputAngle = angle;
|
|
748
|
+
this._textInputRef = document.createElement("textarea");
|
|
749
|
+
this._textInputRef.style.zIndex = "9999";
|
|
750
|
+
this._textInputRef.style.position = "absolute";
|
|
751
|
+
this._textInputRef.style.display = "block";
|
|
752
|
+
this._textInputRef.style.top = inputY + "px";
|
|
753
|
+
this._textInputRef.style.left = inputX + "px";
|
|
754
|
+
this._textInputRef.onkeydown = (event) => {
|
|
755
|
+
if (event.key === "Enter") {
|
|
756
|
+
event.preventDefault();
|
|
757
|
+
this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle);
|
|
758
|
+
}
|
|
759
|
+
if (event.key === "Escape") {
|
|
760
|
+
event.preventDefault();
|
|
761
|
+
this.removeTextInput();
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
if (text) this._textInputRef.value = text;
|
|
765
|
+
document.body.appendChild(this._textInputRef);
|
|
766
|
+
|
|
767
|
+
setTimeout(() => {
|
|
768
|
+
this._textInputRef.focus();
|
|
769
|
+
}, 50);
|
|
770
|
+
} else {
|
|
771
|
+
this.removeTextInput();
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
private removeTextInput(): void {
|
|
776
|
+
this._textInputRef?.remove();
|
|
777
|
+
this._textInputRef = null;
|
|
778
|
+
this._textInputPos = null;
|
|
779
|
+
this._textInputAngle = 0;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
private addText(specifiedText: string, pos: Konva.Vector2d, angle: number, color?: string): void {
|
|
783
|
+
if (specifiedText) {
|
|
784
|
+
const konvaText = new Konva.Text({
|
|
785
|
+
x: pos.x,
|
|
786
|
+
y: pos.y,
|
|
787
|
+
text: specifiedText,
|
|
788
|
+
fontSize: 34,
|
|
789
|
+
fontFamily: this.TEXT_FONT_FAMILY,
|
|
790
|
+
fill: color || this._markupColor.HexColor,
|
|
791
|
+
align: "left",
|
|
792
|
+
draggable: true,
|
|
793
|
+
rotation: angle,
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
this._konvaLayer.add(konvaText);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
const trNodes = this._konvaTransformer.nodes();
|
|
800
|
+
if (trNodes.length > 0) {
|
|
801
|
+
// in case of edit - remove old Konva.Text object
|
|
802
|
+
trNodes[0].destroy();
|
|
803
|
+
this._konvaTransformer.nodes([]);
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
this.removeTextInput();
|
|
807
|
+
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
private addRectangle(pos: Konva.Vector2d, width: number, height: number): Konva.Rect | void {
|
|
812
|
+
if (!pos) return;
|
|
813
|
+
const konvaRectangle = new Konva.Rect({
|
|
814
|
+
stroke: this._markupColor.HexColor,
|
|
815
|
+
strokeWidth: this.lineWidth,
|
|
816
|
+
globalCompositeOperation: "source-over",
|
|
817
|
+
lineCap: "round",
|
|
818
|
+
lineJoin: "round",
|
|
819
|
+
x: pos.x,
|
|
820
|
+
y: pos.y,
|
|
821
|
+
width,
|
|
822
|
+
height,
|
|
823
|
+
draggable: true,
|
|
824
|
+
strokeScaleEnabled: false,
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
this._konvaLayer.add(konvaRectangle);
|
|
828
|
+
return konvaRectangle;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
private addEllipse(pos: { x: number; y: number }, radius: { x: number; y: number }): Konva.Ellipse | void {
|
|
832
|
+
if (!pos) return;
|
|
833
|
+
|
|
834
|
+
const konvaEllipse = new Konva.Ellipse({
|
|
835
|
+
stroke: this._markupColor.HexColor,
|
|
836
|
+
strokeWidth: this.lineWidth,
|
|
837
|
+
globalCompositeOperation: "source-over",
|
|
838
|
+
lineCap: "round",
|
|
839
|
+
lineJoin: "round",
|
|
840
|
+
x: pos.x,
|
|
841
|
+
y: pos.y,
|
|
842
|
+
radiusX: radius.x,
|
|
843
|
+
radiusY: radius.y,
|
|
844
|
+
draggable: true,
|
|
845
|
+
strokeScaleEnabled: false,
|
|
846
|
+
});
|
|
847
|
+
|
|
848
|
+
this._konvaLayer.add(konvaEllipse);
|
|
849
|
+
return konvaEllipse;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
private addArrow(points: number[], pointerWidth: number, pointerLength: number): Konva.Arrow | void {
|
|
853
|
+
if (!points) return;
|
|
854
|
+
|
|
855
|
+
const konvaArrow = new Konva.Arrow({
|
|
856
|
+
stroke: this._markupColor.HexColor,
|
|
857
|
+
fill: this._markupColor.HexColor,
|
|
858
|
+
strokeWidth: this.lineWidth,
|
|
859
|
+
globalCompositeOperation: "source-over",
|
|
860
|
+
lineCap: "round",
|
|
861
|
+
lineJoin: "round",
|
|
862
|
+
points,
|
|
863
|
+
pointerWidth,
|
|
864
|
+
pointerLength,
|
|
865
|
+
draggable: true,
|
|
866
|
+
strokeScaleEnabled: false,
|
|
867
|
+
});
|
|
868
|
+
|
|
869
|
+
this._konvaLayer.add(konvaArrow);
|
|
870
|
+
return konvaArrow;
|
|
871
|
+
}
|
|
872
|
+
}
|