@inweb/viewer-three 26.1.3 → 26.1.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.
- package/dist/viewer-three.js +16315 -16590
- package/dist/viewer-three.js.map +1 -1
- package/dist/viewer-three.min.js +3 -9
- package/dist/viewer-three.module.js +2472 -224
- package/dist/viewer-three.module.js.map +1 -1
- package/lib/Viewer/Viewer.d.ts +34 -34
- package/lib/Viewer/commands/index.d.ts +8 -14
- package/lib/Viewer/components/DefaultPositionComponent.d.ts +9 -0
- package/lib/Viewer/components/WCSHelperComponent.d.ts +0 -1
- package/lib/Viewer/components/index.d.ts +20 -20
- package/lib/Viewer/draggers/OrbitDragger.d.ts +0 -1
- package/lib/Viewer/draggers/index.d.ts +19 -25
- package/package.json +9 -9
- package/src/Viewer/Viewer.ts +50 -112
- package/src/Viewer/commands/Explode.ts +27 -26
- package/src/Viewer/commands/IsolateSelected.ts +15 -6
- package/src/Viewer/commands/SetDefaultViewPosition.ts +4 -4
- package/src/Viewer/commands/ZoomToExtents.ts +15 -2
- package/src/Viewer/commands/ZoomToObjects.ts +12 -4
- package/src/Viewer/commands/ZoomToSelected.ts +14 -3
- package/src/Viewer/commands/index.ts +8 -14
- package/src/Viewer/{commands/ZoomTo.ts → components/DefaultPositionComponent.ts} +22 -34
- package/src/Viewer/components/ExtentsComponent.ts +3 -10
- package/src/Viewer/components/ResizeCanvasComponent.ts +2 -13
- package/src/Viewer/components/WCSHelperComponent.ts +0 -9
- package/src/Viewer/components/index.ts +22 -22
- package/src/Viewer/draggers/OrbitDragger.ts +8 -11
- package/src/Viewer/draggers/index.ts +19 -25
- package/lib/Viewer/commands/ZoomTo.d.ts +0 -3
- package/lib/Viewer/components/CameraComponent.d.ts +0 -8
- package/src/Viewer/components/CameraComponent.ts +0 -78
|
@@ -1,20 +1,2315 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Konva from "konva";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { Line, BufferGeometry, Float32BufferAttribute, LineBasicMaterial, Mesh, MeshBasicMaterial, DoubleSide, Vector3, EventDispatcher, MOUSE, TOUCH, Quaternion, Spherical, Vector2, Plane, Object3D, Matrix4, Vector4, Raycaster, Controls, Clock, Box3, Sphere, Color, PMREMGenerator, AmbientLight, DirectionalLight, OrthographicCamera, CylinderGeometry, Sprite, CanvasTexture, SRGBColorSpace, SpriteMaterial, LoadingManager, LoaderUtils, Scene, PerspectiveCamera, WebGLRenderer, LinearToneMapping } from "three";
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { TransformControls } from "three/examples/jsm/controls/TransformControls.js";
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
import { RoomEnvironment } from "three/examples/jsm/environments/RoomEnvironment.js";
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
class CommandsRegistry {
|
|
12
|
+
constructor() {
|
|
13
|
+
this._commands = new Map;
|
|
14
|
+
}
|
|
15
|
+
registerCommand(id, handler, description, thisArg) {
|
|
16
|
+
this._commands.set(id, {
|
|
17
|
+
id: id,
|
|
18
|
+
handler: handler,
|
|
19
|
+
thisArg: thisArg,
|
|
20
|
+
description: description
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
registerCommandAlias(id, alias) {
|
|
24
|
+
this.registerCommand(alias, ((viewer, ...args) => this.executeCommand(id, viewer, ...args)));
|
|
25
|
+
}
|
|
26
|
+
getCommand(id) {
|
|
27
|
+
return this._commands.get(id);
|
|
28
|
+
}
|
|
29
|
+
getCommands() {
|
|
30
|
+
const map = new Map;
|
|
31
|
+
this._commands.forEach(((value, key) => map.set(key, value)));
|
|
32
|
+
return map;
|
|
33
|
+
}
|
|
34
|
+
executeCommand(id, viewer, ...args) {
|
|
35
|
+
const command = this._commands.get(id);
|
|
36
|
+
if (!command) {
|
|
37
|
+
if (viewer) {
|
|
38
|
+
const isDraggerCommand = viewer.draggers.includes(id);
|
|
39
|
+
if (isDraggerCommand) return viewer.setActiveDragger(id);
|
|
40
|
+
}
|
|
41
|
+
console.warn(`Command '${id}' not found`);
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
const {handler: handler, thisArg: thisArg} = command;
|
|
45
|
+
const result = handler.apply(thisArg, [ viewer, ...args ]);
|
|
46
|
+
viewer === null || viewer === void 0 ? void 0 : viewer.emit({
|
|
47
|
+
type: "command",
|
|
48
|
+
data: id,
|
|
49
|
+
args: args
|
|
50
|
+
});
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
12
54
|
|
|
13
|
-
|
|
55
|
+
const _commandsRegistry = new Map;
|
|
56
|
+
|
|
57
|
+
function commandsRegistry(viewerType = "") {
|
|
58
|
+
let result = _commandsRegistry.get(viewerType);
|
|
59
|
+
if (!result) {
|
|
60
|
+
result = new CommandsRegistry;
|
|
61
|
+
_commandsRegistry.set(viewerType, result);
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
class Dragger {
|
|
67
|
+
constructor(viewer) {
|
|
68
|
+
this.name = "";
|
|
69
|
+
}
|
|
70
|
+
dispose() {}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
class DraggersRegistry {
|
|
74
|
+
constructor() {
|
|
75
|
+
this._draggers = new Map;
|
|
76
|
+
}
|
|
77
|
+
registerDragger(name, provider) {
|
|
78
|
+
this._draggers.set(name, provider);
|
|
79
|
+
}
|
|
80
|
+
registerDraggerAlias(name, alias) {
|
|
81
|
+
const provider = this.getDragger(name);
|
|
82
|
+
if (provider) this.registerDragger(alias, (viewer => provider(viewer)));
|
|
83
|
+
}
|
|
84
|
+
getDragger(name) {
|
|
85
|
+
return this._draggers.get(name);
|
|
86
|
+
}
|
|
87
|
+
getDraggers() {
|
|
88
|
+
const map = new Map;
|
|
89
|
+
this._draggers.forEach(((value, key) => map.set(key, value)));
|
|
90
|
+
return map;
|
|
91
|
+
}
|
|
92
|
+
createDragger(name, viewer) {
|
|
93
|
+
const provider = this.getDragger(name);
|
|
94
|
+
if (!provider) return null;
|
|
95
|
+
const dragger = provider(viewer);
|
|
96
|
+
dragger.name = name;
|
|
97
|
+
return dragger;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const _draggersRegistry = new Map;
|
|
102
|
+
|
|
103
|
+
function draggersRegistry(viewerType = "") {
|
|
104
|
+
let result = _draggersRegistry.get(viewerType);
|
|
105
|
+
if (!result) {
|
|
106
|
+
result = new DraggersRegistry;
|
|
107
|
+
_draggersRegistry.set(viewerType, result);
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
class Component {
|
|
113
|
+
constructor(viewer) {
|
|
114
|
+
this.name = "";
|
|
115
|
+
}
|
|
116
|
+
dispose() {}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
class Components {
|
|
120
|
+
constructor() {
|
|
121
|
+
this._components = new Map;
|
|
122
|
+
}
|
|
123
|
+
registerComponent(name, provider) {
|
|
124
|
+
this._components.set(name, provider);
|
|
125
|
+
}
|
|
126
|
+
registerComponentAlias(name, alias) {
|
|
127
|
+
const provider = this.getComponent(name);
|
|
128
|
+
if (provider) this.registerComponent(alias, (viewer => provider(viewer)));
|
|
129
|
+
}
|
|
130
|
+
getComponent(name) {
|
|
131
|
+
return this._components.get(name);
|
|
132
|
+
}
|
|
133
|
+
getComponents() {
|
|
134
|
+
const map = new Map;
|
|
135
|
+
this._components.forEach(((value, key) => map.set(key, value)));
|
|
136
|
+
return map;
|
|
137
|
+
}
|
|
138
|
+
createComponent(name, viewer) {
|
|
139
|
+
const provider = this.getComponent(name);
|
|
140
|
+
if (!provider) return null;
|
|
141
|
+
const component = provider(viewer);
|
|
142
|
+
component.name = name;
|
|
143
|
+
return component;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const _components = new Map;
|
|
148
|
+
|
|
149
|
+
function componentsRegistry(viewerType = "") {
|
|
150
|
+
let result = _components.get(viewerType);
|
|
151
|
+
if (!result) {
|
|
152
|
+
result = new Components;
|
|
153
|
+
_components.set(viewerType, result);
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function defaultOptions() {
|
|
159
|
+
return {
|
|
160
|
+
showWCS: true,
|
|
161
|
+
cameraAnimation: true,
|
|
162
|
+
antialiasing: true,
|
|
163
|
+
groundShadow: false,
|
|
164
|
+
shadows: false,
|
|
165
|
+
cameraAxisXSpeed: 4,
|
|
166
|
+
cameraAxisYSpeed: 1,
|
|
167
|
+
ambientOcclusion: false,
|
|
168
|
+
enableStreamingMode: true,
|
|
169
|
+
enablePartialMode: false,
|
|
170
|
+
memoryLimit: 3294967296,
|
|
171
|
+
cuttingPlaneFillColor: {
|
|
172
|
+
red: 255,
|
|
173
|
+
green: 152,
|
|
174
|
+
blue: 0
|
|
175
|
+
},
|
|
176
|
+
edgesColor: {
|
|
177
|
+
r: 255,
|
|
178
|
+
g: 152,
|
|
179
|
+
b: 0
|
|
180
|
+
},
|
|
181
|
+
facesColor: {
|
|
182
|
+
r: 255,
|
|
183
|
+
g: 152,
|
|
184
|
+
b: 0
|
|
185
|
+
},
|
|
186
|
+
edgesVisibility: true,
|
|
187
|
+
edgesOverlap: true,
|
|
188
|
+
facesOverlap: false,
|
|
189
|
+
facesTransparancy: 200,
|
|
190
|
+
enableCustomHighlight: true,
|
|
191
|
+
sceneGraph: false,
|
|
192
|
+
edgeModel: true,
|
|
193
|
+
reverseZoomWheel: false,
|
|
194
|
+
enableZoomWheel: true,
|
|
195
|
+
enableGestures: true,
|
|
196
|
+
geometryType: "vsfx",
|
|
197
|
+
rulerUnit: "Default"
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
class Options {
|
|
202
|
+
constructor(emitter) {
|
|
203
|
+
this._emitter = emitter;
|
|
204
|
+
this._data = defaultOptions();
|
|
205
|
+
this.loadFromStorage();
|
|
206
|
+
}
|
|
207
|
+
static defaults() {
|
|
208
|
+
return defaultOptions();
|
|
209
|
+
}
|
|
210
|
+
notifierChangeEvent() {
|
|
211
|
+
console.warn("Options.notifierChangeEvent() has been deprecated since 25.3 and will be removed in a future release, use Options.change() instead.");
|
|
212
|
+
this.change();
|
|
213
|
+
}
|
|
214
|
+
change() {
|
|
215
|
+
if (this._emitter !== undefined) {
|
|
216
|
+
this.saveToStorage();
|
|
217
|
+
this._emitter.emit({
|
|
218
|
+
type: "optionschange",
|
|
219
|
+
data: this
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
saveToStorage() {
|
|
224
|
+
if (typeof window !== "undefined") try {
|
|
225
|
+
localStorage.setItem("od-client-settings", JSON.stringify(this.data));
|
|
226
|
+
} catch (error) {
|
|
227
|
+
console.error("Cannot save client settings.", error);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
loadFromStorage() {
|
|
231
|
+
if (typeof window !== "undefined") try {
|
|
232
|
+
const item = localStorage.getItem("od-client-settings");
|
|
233
|
+
if (item) {
|
|
234
|
+
const data = JSON.parse(item);
|
|
235
|
+
this.data = {
|
|
236
|
+
...data
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.error("Cannot load client settings.", error);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
resetToDefaults(fields) {
|
|
244
|
+
if (fields !== undefined) {
|
|
245
|
+
const defaults = Options.defaults();
|
|
246
|
+
const resetData = fields.reduce(((acc, field) => {
|
|
247
|
+
acc[field] = defaults[field];
|
|
248
|
+
return acc;
|
|
249
|
+
}), {});
|
|
250
|
+
this.data = {
|
|
251
|
+
...this.data,
|
|
252
|
+
...resetData
|
|
253
|
+
};
|
|
254
|
+
} else {
|
|
255
|
+
this.data = {
|
|
256
|
+
...this.data,
|
|
257
|
+
...Options.defaults()
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
get data() {
|
|
262
|
+
return this._data;
|
|
263
|
+
}
|
|
264
|
+
set data(value) {
|
|
265
|
+
const enablePartialMode = value.enableStreamingMode ? value.enablePartialMode : false;
|
|
266
|
+
const sceneGraph = enablePartialMode ? false : value.sceneGraph;
|
|
267
|
+
this._data = {
|
|
268
|
+
...Options.defaults(),
|
|
269
|
+
...this._data,
|
|
270
|
+
...value,
|
|
271
|
+
enablePartialMode: enablePartialMode,
|
|
272
|
+
sceneGraph: sceneGraph
|
|
273
|
+
};
|
|
274
|
+
this.change();
|
|
275
|
+
}
|
|
276
|
+
get showWCS() {
|
|
277
|
+
return this._data.showWCS;
|
|
278
|
+
}
|
|
279
|
+
set showWCS(value) {
|
|
280
|
+
this._data.showWCS = value;
|
|
281
|
+
this.change();
|
|
282
|
+
}
|
|
283
|
+
get cameraAnimation() {
|
|
284
|
+
return this._data.cameraAnimation;
|
|
285
|
+
}
|
|
286
|
+
set cameraAnimation(value) {
|
|
287
|
+
this._data.cameraAnimation = value;
|
|
288
|
+
this.change();
|
|
289
|
+
}
|
|
290
|
+
get antialiasing() {
|
|
291
|
+
return this._data.antialiasing;
|
|
292
|
+
}
|
|
293
|
+
set antialiasing(value) {
|
|
294
|
+
this._data.antialiasing = value;
|
|
295
|
+
this.change();
|
|
296
|
+
}
|
|
297
|
+
get groundShadow() {
|
|
298
|
+
return this._data.groundShadow;
|
|
299
|
+
}
|
|
300
|
+
set groundShadow(value) {
|
|
301
|
+
this._data.groundShadow = value;
|
|
302
|
+
this.change();
|
|
303
|
+
}
|
|
304
|
+
get shadows() {
|
|
305
|
+
return this._data.shadows;
|
|
306
|
+
}
|
|
307
|
+
set shadows(value) {
|
|
308
|
+
this._data.shadows = value;
|
|
309
|
+
this.change();
|
|
310
|
+
}
|
|
311
|
+
get cameraAxisXSpeed() {
|
|
312
|
+
return this._data.cameraAxisXSpeed;
|
|
313
|
+
}
|
|
314
|
+
set cameraAxisXSpeed(value) {
|
|
315
|
+
this._data.cameraAxisXSpeed = value;
|
|
316
|
+
this.change();
|
|
317
|
+
}
|
|
318
|
+
get cameraAxisYSpeed() {
|
|
319
|
+
return this._data.cameraAxisYSpeed;
|
|
320
|
+
}
|
|
321
|
+
set cameraAxisYSpeed(value) {
|
|
322
|
+
this.cameraAxisYSpeed = value;
|
|
323
|
+
this.change();
|
|
324
|
+
}
|
|
325
|
+
get ambientOcclusion() {
|
|
326
|
+
return this._data.ambientOcclusion;
|
|
327
|
+
}
|
|
328
|
+
set ambientOcclusion(value) {
|
|
329
|
+
this._data.ambientOcclusion = value;
|
|
330
|
+
this.change();
|
|
331
|
+
}
|
|
332
|
+
get enableStreamingMode() {
|
|
333
|
+
return this._data.enableStreamingMode;
|
|
334
|
+
}
|
|
335
|
+
set enableStreamingMode(value) {
|
|
336
|
+
this._data.enableStreamingMode = value;
|
|
337
|
+
if (!value) this._data.enablePartialMode = false;
|
|
338
|
+
this.change();
|
|
339
|
+
}
|
|
340
|
+
get enablePartialMode() {
|
|
341
|
+
return this._data.enablePartialMode;
|
|
342
|
+
}
|
|
343
|
+
set enablePartialMode(value) {
|
|
344
|
+
this._data.enablePartialMode = value;
|
|
345
|
+
if (value) {
|
|
346
|
+
this._data.enableStreamingMode = true;
|
|
347
|
+
this._data.sceneGraph = false;
|
|
348
|
+
}
|
|
349
|
+
this.change();
|
|
350
|
+
}
|
|
351
|
+
get memoryLimit() {
|
|
352
|
+
return this._data.memoryLimit;
|
|
353
|
+
}
|
|
354
|
+
set memoryLimit(value) {
|
|
355
|
+
this._data.memoryLimit = value;
|
|
356
|
+
this.change();
|
|
357
|
+
}
|
|
358
|
+
get cuttingPlaneFillColor() {
|
|
359
|
+
return this._data.cuttingPlaneFillColor;
|
|
360
|
+
}
|
|
361
|
+
set cuttingPlaneFillColor(value) {
|
|
362
|
+
this._data.cuttingPlaneFillColor = value;
|
|
363
|
+
this.change();
|
|
364
|
+
}
|
|
365
|
+
get edgesColor() {
|
|
366
|
+
return this._data.edgesColor;
|
|
367
|
+
}
|
|
368
|
+
set edgesColor(value) {
|
|
369
|
+
this._data.edgesColor = value;
|
|
370
|
+
this.change();
|
|
371
|
+
}
|
|
372
|
+
get facesColor() {
|
|
373
|
+
return this._data.facesColor;
|
|
374
|
+
}
|
|
375
|
+
set facesColor(value) {
|
|
376
|
+
this._data.facesColor = value;
|
|
377
|
+
this.change();
|
|
378
|
+
}
|
|
379
|
+
get edgesVisibility() {
|
|
380
|
+
return this._data.edgesVisibility;
|
|
381
|
+
}
|
|
382
|
+
set edgesVisibility(value) {
|
|
383
|
+
this._data.edgesVisibility = value;
|
|
384
|
+
this.change();
|
|
385
|
+
}
|
|
386
|
+
get edgesOverlap() {
|
|
387
|
+
return this._data.edgesOverlap;
|
|
388
|
+
}
|
|
389
|
+
set edgesOverlap(value) {
|
|
390
|
+
this._data.edgesOverlap = value;
|
|
391
|
+
this.change();
|
|
392
|
+
}
|
|
393
|
+
get facesOverlap() {
|
|
394
|
+
return this._data.facesOverlap;
|
|
395
|
+
}
|
|
396
|
+
set facesOverlap(value) {
|
|
397
|
+
this._data.facesOverlap = value;
|
|
398
|
+
this.change();
|
|
399
|
+
}
|
|
400
|
+
get facesTransparancy() {
|
|
401
|
+
return this._data.facesTransparancy;
|
|
402
|
+
}
|
|
403
|
+
set facesTransparancy(value) {
|
|
404
|
+
this._data.facesTransparancy = value;
|
|
405
|
+
this.change();
|
|
406
|
+
}
|
|
407
|
+
get enableCustomHighlight() {
|
|
408
|
+
return this._data.enableCustomHighlight;
|
|
409
|
+
}
|
|
410
|
+
set enableCustomHighlight(value) {
|
|
411
|
+
this._data.enableCustomHighlight = value;
|
|
412
|
+
this.change();
|
|
413
|
+
}
|
|
414
|
+
get sceneGraph() {
|
|
415
|
+
return this._data.sceneGraph;
|
|
416
|
+
}
|
|
417
|
+
set sceneGraph(value) {
|
|
418
|
+
this._data.sceneGraph = value;
|
|
419
|
+
if (value) this._data.enablePartialMode = false;
|
|
420
|
+
this.change();
|
|
421
|
+
}
|
|
422
|
+
get edgeModel() {
|
|
423
|
+
return Boolean(this._data.edgeModel);
|
|
424
|
+
}
|
|
425
|
+
set edgeModel(value) {
|
|
426
|
+
this._data.edgeModel = Boolean(value);
|
|
427
|
+
this.change();
|
|
428
|
+
}
|
|
429
|
+
get reverseZoomWheel() {
|
|
430
|
+
return this._data.reverseZoomWheel;
|
|
431
|
+
}
|
|
432
|
+
set reverseZoomWheel(value) {
|
|
433
|
+
this._data.reverseZoomWheel = !!value;
|
|
434
|
+
this.change();
|
|
435
|
+
}
|
|
436
|
+
get enableZoomWheel() {
|
|
437
|
+
return this._data.enableZoomWheel;
|
|
438
|
+
}
|
|
439
|
+
set enableZoomWheel(value) {
|
|
440
|
+
this._data.enableZoomWheel = !!value;
|
|
441
|
+
this.change();
|
|
442
|
+
}
|
|
443
|
+
get enableGestures() {
|
|
444
|
+
return this._data.enableGestures;
|
|
445
|
+
}
|
|
446
|
+
set enableGestures(value) {
|
|
447
|
+
this._data.enableGestures = !!value;
|
|
448
|
+
this.change();
|
|
449
|
+
}
|
|
450
|
+
get geometryType() {
|
|
451
|
+
return this._data.geometryType;
|
|
452
|
+
}
|
|
453
|
+
set geometryType(value) {
|
|
454
|
+
this._data.geometryType = value;
|
|
455
|
+
this.change();
|
|
456
|
+
}
|
|
457
|
+
get rulerUnit() {
|
|
458
|
+
return this._data.rulerUnit;
|
|
459
|
+
}
|
|
460
|
+
set rulerUnit(value) {
|
|
461
|
+
this._data.rulerUnit = value;
|
|
462
|
+
this.change();
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
const CanvasEvents = [ "click", "contextmenu", "dblclick", "mousedown", "mouseleave", "mousemove", "mouseup", "pointercancel", "pointerdown", "pointerleave", "pointermove", "pointerup", "touchcancel", "touchend", "touchmove", "touchstart", "wheel" ];
|
|
467
|
+
|
|
468
|
+
const CANVAS_EVENTS = CanvasEvents;
|
|
469
|
+
|
|
470
|
+
class WorldTransform {
|
|
471
|
+
screenToWorld(position) {
|
|
472
|
+
return {
|
|
473
|
+
x: position.x,
|
|
474
|
+
y: position.y,
|
|
475
|
+
z: 0
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
worldToScreen(position) {
|
|
479
|
+
return {
|
|
480
|
+
x: position.x,
|
|
481
|
+
y: position.y
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
getScale() {
|
|
485
|
+
return {
|
|
486
|
+
x: 1,
|
|
487
|
+
y: 1,
|
|
488
|
+
z: 1
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
class MarkupColor {
|
|
494
|
+
constructor(r, g, b) {
|
|
495
|
+
this.setColor(r, g, b);
|
|
496
|
+
}
|
|
497
|
+
asHex() {
|
|
498
|
+
return "#" + this.HEX;
|
|
499
|
+
}
|
|
500
|
+
asRGB() {
|
|
501
|
+
return {
|
|
502
|
+
r: this.R,
|
|
503
|
+
g: this.G,
|
|
504
|
+
b: this.B
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
setColor(r, g, b) {
|
|
508
|
+
this.R = r;
|
|
509
|
+
this.G = g;
|
|
510
|
+
this.B = b;
|
|
511
|
+
this.HEX = this.rgbToHex(r, g, b);
|
|
512
|
+
}
|
|
513
|
+
rgbToHex(r, g, b) {
|
|
514
|
+
const valueToHex = c => {
|
|
515
|
+
const hex = c.toString(16);
|
|
516
|
+
return hex === "0" ? "00" : hex;
|
|
517
|
+
};
|
|
518
|
+
return valueToHex(r) + valueToHex(g) + valueToHex(b);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
const LineTypeSpecs = new Map([ [ "solid", [] ], [ "dot", [ 30, 30, .001, 30 ] ], [ "dash", [ 30, 30 ] ] ]);
|
|
523
|
+
|
|
524
|
+
class KonvaLine {
|
|
525
|
+
constructor(params, ref = null) {
|
|
526
|
+
var _a, _b;
|
|
527
|
+
if (ref) {
|
|
528
|
+
this._ref = ref;
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
if (!params) params = {};
|
|
532
|
+
if (!params.points) params.points = [ {
|
|
533
|
+
x: 50,
|
|
534
|
+
y: 50
|
|
535
|
+
}, {
|
|
536
|
+
x: 100,
|
|
537
|
+
y: 100
|
|
538
|
+
} ];
|
|
539
|
+
const konvaPoints = [];
|
|
540
|
+
params.points.forEach((point => konvaPoints.push(point.x, point.y)));
|
|
541
|
+
this._ref = new Konva.Line({
|
|
542
|
+
stroke: (_a = params.color) !== null && _a !== void 0 ? _a : "#ff0000",
|
|
543
|
+
strokeWidth: (_b = params.width) !== null && _b !== void 0 ? _b : 4,
|
|
544
|
+
globalCompositeOperation: "source-over",
|
|
545
|
+
lineCap: "round",
|
|
546
|
+
lineJoin: "round",
|
|
547
|
+
points: konvaPoints,
|
|
548
|
+
draggable: true,
|
|
549
|
+
strokeScaleEnabled: false,
|
|
550
|
+
dash: LineTypeSpecs.get(params.type) || []
|
|
551
|
+
});
|
|
552
|
+
this._ref.on("transform", (e => {
|
|
553
|
+
const attrs = e.target.attrs;
|
|
554
|
+
if (attrs.rotation !== this._ref.rotation()) this._ref.rotation(attrs.rotation);
|
|
555
|
+
}));
|
|
556
|
+
this._ref.id(this._ref._id.toString());
|
|
557
|
+
}
|
|
558
|
+
ref() {
|
|
559
|
+
return this._ref;
|
|
560
|
+
}
|
|
561
|
+
id() {
|
|
562
|
+
return this._ref.id();
|
|
563
|
+
}
|
|
564
|
+
enableMouseEditing(value) {
|
|
565
|
+
this._ref.draggable(value);
|
|
566
|
+
}
|
|
567
|
+
type() {
|
|
568
|
+
return "Line";
|
|
569
|
+
}
|
|
570
|
+
getColor() {
|
|
571
|
+
return this._ref.stroke();
|
|
572
|
+
}
|
|
573
|
+
setColor(hex) {
|
|
574
|
+
this._ref.stroke(hex);
|
|
575
|
+
}
|
|
576
|
+
getRotation() {
|
|
577
|
+
return this._ref.rotation();
|
|
578
|
+
}
|
|
579
|
+
setRotation(degrees) {
|
|
580
|
+
this._ref.rotation(degrees);
|
|
581
|
+
}
|
|
582
|
+
getZIndex() {
|
|
583
|
+
return this._ref.zIndex();
|
|
584
|
+
}
|
|
585
|
+
setZIndex(zIndex) {
|
|
586
|
+
this._ref.zIndex(zIndex);
|
|
587
|
+
}
|
|
588
|
+
delete() {
|
|
589
|
+
this._ref.destroy();
|
|
590
|
+
this._ref = null;
|
|
591
|
+
}
|
|
592
|
+
getPoints() {
|
|
593
|
+
return this._ref.points();
|
|
594
|
+
}
|
|
595
|
+
setLineWidth(size) {
|
|
596
|
+
this._ref.strokeWidth(size);
|
|
597
|
+
}
|
|
598
|
+
getLineWidth() {
|
|
599
|
+
return this._ref.strokeWidth();
|
|
600
|
+
}
|
|
601
|
+
getLineType() {
|
|
602
|
+
const typeSpecs = this._ref.dash() || [];
|
|
603
|
+
let type;
|
|
604
|
+
switch (typeSpecs) {
|
|
605
|
+
case LineTypeSpecs.get("dot"):
|
|
606
|
+
type = "dot";
|
|
607
|
+
break;
|
|
608
|
+
|
|
609
|
+
case LineTypeSpecs.get("dash"):
|
|
610
|
+
type = "dash";
|
|
611
|
+
break;
|
|
612
|
+
|
|
613
|
+
default:
|
|
614
|
+
type = "solid";
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
return type;
|
|
618
|
+
}
|
|
619
|
+
setLineType(type) {
|
|
620
|
+
const specs = LineTypeSpecs.get(type);
|
|
621
|
+
if (specs) this._ref.dash(specs);
|
|
622
|
+
}
|
|
623
|
+
addPoints(points) {
|
|
624
|
+
let newPoints = this._ref.points();
|
|
625
|
+
points.forEach((point => {
|
|
626
|
+
newPoints = newPoints.concat([ point.x, point.y ]);
|
|
627
|
+
}));
|
|
628
|
+
this._ref.points(newPoints);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
class KonvaText {
|
|
633
|
+
constructor(params, ref = null) {
|
|
634
|
+
var _a, _b, _c;
|
|
635
|
+
this.TEXT_FONT_FAMILY = "Calibri";
|
|
636
|
+
if (ref) {
|
|
637
|
+
this._ref = ref;
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
if (!params) params = {};
|
|
641
|
+
if (!params.position) params.position = {
|
|
642
|
+
x: 100,
|
|
643
|
+
y: 100
|
|
644
|
+
};
|
|
645
|
+
if (!params.text) params.text = "default";
|
|
646
|
+
this._ref = new Konva.Text({
|
|
647
|
+
x: params.position.x,
|
|
648
|
+
y: params.position.y,
|
|
649
|
+
text: params.text,
|
|
650
|
+
fontSize: (_a = params.fontSize) !== null && _a !== void 0 ? _a : 34,
|
|
651
|
+
fontFamily: this.TEXT_FONT_FAMILY,
|
|
652
|
+
fill: (_b = params.color) !== null && _b !== void 0 ? _b : "#ff0000",
|
|
653
|
+
align: "left",
|
|
654
|
+
draggable: true,
|
|
655
|
+
rotation: (_c = params.rotation) !== null && _c !== void 0 ? _c : 0
|
|
656
|
+
});
|
|
657
|
+
this._ref.width(this._ref.getTextWidth());
|
|
658
|
+
this._ref.on("transform", (e => {
|
|
659
|
+
const attrs = e.target.attrs;
|
|
660
|
+
if (attrs.rotation !== this._ref.rotation()) this._ref.rotation(attrs.rotation);
|
|
661
|
+
const scaleByX = Math.abs(attrs.scaleX - 1) > 1e-5;
|
|
662
|
+
const scaleByY = Math.abs(attrs.scaleY - 1) > 1e-5;
|
|
663
|
+
let newWidth = this._ref.width();
|
|
664
|
+
if (scaleByX) newWidth *= attrs.scaleX;
|
|
665
|
+
let newHeight = this._ref.height();
|
|
666
|
+
if (scaleByY) newHeight *= attrs.scaleY;
|
|
667
|
+
const minWidth = 50;
|
|
668
|
+
if (newWidth < minWidth) newWidth = minWidth;
|
|
669
|
+
if (newHeight < Math.round(this.getFontSize())) newHeight = Math.round(this.getFontSize());
|
|
670
|
+
if (scaleByX) {
|
|
671
|
+
this._ref.width(newWidth);
|
|
672
|
+
}
|
|
673
|
+
if (scaleByY) {
|
|
674
|
+
this._ref.height(newHeight);
|
|
675
|
+
}
|
|
676
|
+
this._ref.scale({
|
|
677
|
+
x: 1,
|
|
678
|
+
y: 1
|
|
679
|
+
});
|
|
680
|
+
}));
|
|
681
|
+
this._ref.id(this._ref._id.toString());
|
|
682
|
+
}
|
|
683
|
+
ref() {
|
|
684
|
+
return this._ref;
|
|
685
|
+
}
|
|
686
|
+
id() {
|
|
687
|
+
return this._ref.id();
|
|
688
|
+
}
|
|
689
|
+
enableMouseEditing(value) {
|
|
690
|
+
this._ref.draggable(value);
|
|
691
|
+
}
|
|
692
|
+
type() {
|
|
693
|
+
return "Text";
|
|
694
|
+
}
|
|
695
|
+
getColor() {
|
|
696
|
+
return this._ref.fill();
|
|
697
|
+
}
|
|
698
|
+
setColor(hex) {
|
|
699
|
+
this._ref.fill(hex);
|
|
700
|
+
}
|
|
701
|
+
getRotation() {
|
|
702
|
+
return this._ref.rotation();
|
|
703
|
+
}
|
|
704
|
+
setRotation(degrees) {
|
|
705
|
+
this._ref.rotation(degrees);
|
|
706
|
+
}
|
|
707
|
+
getZIndex() {
|
|
708
|
+
return this._ref.zIndex();
|
|
709
|
+
}
|
|
710
|
+
setZIndex(zIndex) {
|
|
711
|
+
this._ref.zIndex(zIndex);
|
|
712
|
+
}
|
|
713
|
+
delete() {
|
|
714
|
+
this._ref.destroy();
|
|
715
|
+
this._ref = null;
|
|
716
|
+
}
|
|
717
|
+
getText() {
|
|
718
|
+
return this._ref.text();
|
|
719
|
+
}
|
|
720
|
+
setText(text) {
|
|
721
|
+
this._ref.text(text);
|
|
722
|
+
}
|
|
723
|
+
getPosition() {
|
|
724
|
+
return this._ref.getPosition();
|
|
725
|
+
}
|
|
726
|
+
setPosition(x, y) {
|
|
727
|
+
this._ref.setPosition({
|
|
728
|
+
x: x,
|
|
729
|
+
y: y
|
|
730
|
+
});
|
|
731
|
+
}
|
|
732
|
+
getFontSize() {
|
|
733
|
+
return this._ref.fontSize();
|
|
734
|
+
}
|
|
735
|
+
setFontSize(size) {
|
|
736
|
+
this._ref.fontSize(size);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
class KonvaRectangle {
|
|
741
|
+
constructor(params, ref = null) {
|
|
742
|
+
var _a, _b, _c, _d;
|
|
743
|
+
if (ref) {
|
|
744
|
+
this._ref = ref;
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
if (!params) params = {};
|
|
748
|
+
if (!params.position) params.position = {
|
|
749
|
+
x: 100,
|
|
750
|
+
y: 100
|
|
751
|
+
};
|
|
752
|
+
this._ref = new Konva.Rect({
|
|
753
|
+
stroke: (_a = params.color) !== null && _a !== void 0 ? _a : "#ff0000",
|
|
754
|
+
strokeWidth: (_b = params.lineWidth) !== null && _b !== void 0 ? _b : 4,
|
|
755
|
+
globalCompositeOperation: "source-over",
|
|
756
|
+
lineCap: "round",
|
|
757
|
+
lineJoin: "round",
|
|
758
|
+
x: params.position.x,
|
|
759
|
+
y: params.position.y,
|
|
760
|
+
width: (_c = params.width) !== null && _c !== void 0 ? _c : 200,
|
|
761
|
+
height: (_d = params.height) !== null && _d !== void 0 ? _d : 200,
|
|
762
|
+
draggable: true,
|
|
763
|
+
strokeScaleEnabled: false
|
|
764
|
+
});
|
|
765
|
+
this._ref.on("transform", (e => {
|
|
766
|
+
const attrs = e.target.attrs;
|
|
767
|
+
if (attrs.rotation !== this._ref.rotation()) this._ref.rotation(attrs.rotation);
|
|
768
|
+
const scaleByX = Math.abs(attrs.scaleX - 1) > 1e-5;
|
|
769
|
+
const scaleByY = Math.abs(attrs.scaleY - 1) > 1e-5;
|
|
770
|
+
let newWidth = this._ref.width();
|
|
771
|
+
if (scaleByX) newWidth *= attrs.scaleX;
|
|
772
|
+
let newHeight = this._ref.height();
|
|
773
|
+
if (scaleByY) newHeight *= attrs.scaleY;
|
|
774
|
+
const minWidth = 50;
|
|
775
|
+
const minHeight = 50;
|
|
776
|
+
if (newWidth < minWidth) newWidth = minWidth;
|
|
777
|
+
if (newHeight < minHeight) newHeight = minHeight;
|
|
778
|
+
if (scaleByX) {
|
|
779
|
+
this._ref.width(newWidth);
|
|
780
|
+
}
|
|
781
|
+
if (scaleByY) {
|
|
782
|
+
this._ref.height(newHeight);
|
|
783
|
+
}
|
|
784
|
+
this._ref.scale({
|
|
785
|
+
x: 1,
|
|
786
|
+
y: 1
|
|
787
|
+
});
|
|
788
|
+
}));
|
|
789
|
+
this._ref.id(this._ref._id.toString());
|
|
790
|
+
}
|
|
791
|
+
getPosition() {
|
|
792
|
+
return this._ref.position();
|
|
793
|
+
}
|
|
794
|
+
getWidth() {
|
|
795
|
+
return this._ref.width();
|
|
796
|
+
}
|
|
797
|
+
getHeigth() {
|
|
798
|
+
return this._ref.height();
|
|
799
|
+
}
|
|
800
|
+
setWidth(w) {
|
|
801
|
+
this._ref.width(w);
|
|
802
|
+
}
|
|
803
|
+
setHeight(h) {
|
|
804
|
+
this._ref.height(h);
|
|
805
|
+
}
|
|
806
|
+
setPosition(x, y) {
|
|
807
|
+
this._ref.setPosition({
|
|
808
|
+
x: x,
|
|
809
|
+
y: y
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
ref() {
|
|
813
|
+
return this._ref;
|
|
814
|
+
}
|
|
815
|
+
id() {
|
|
816
|
+
return this._ref.id();
|
|
817
|
+
}
|
|
818
|
+
enableMouseEditing(value) {
|
|
819
|
+
this._ref.draggable(value);
|
|
820
|
+
}
|
|
821
|
+
type() {
|
|
822
|
+
return "Rectangle";
|
|
823
|
+
}
|
|
824
|
+
getColor() {
|
|
825
|
+
return this._ref.stroke();
|
|
826
|
+
}
|
|
827
|
+
setColor(hex) {
|
|
828
|
+
this._ref.stroke(hex);
|
|
829
|
+
}
|
|
830
|
+
getRotation() {
|
|
831
|
+
return this._ref.rotation();
|
|
832
|
+
}
|
|
833
|
+
setRotation(degrees) {
|
|
834
|
+
this._ref.rotation(degrees);
|
|
835
|
+
}
|
|
836
|
+
getZIndex() {
|
|
837
|
+
return this._ref.zIndex();
|
|
838
|
+
}
|
|
839
|
+
setZIndex(zIndex) {
|
|
840
|
+
this._ref.zIndex(zIndex);
|
|
841
|
+
}
|
|
842
|
+
delete() {
|
|
843
|
+
this._ref.destroy();
|
|
844
|
+
this._ref = null;
|
|
845
|
+
}
|
|
846
|
+
setLineWidth(size) {
|
|
847
|
+
this._ref.strokeWidth(size);
|
|
848
|
+
}
|
|
849
|
+
getLineWidth() {
|
|
850
|
+
return this._ref.strokeWidth();
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
class KonvaEllipse {
|
|
855
|
+
constructor(params, ref = null) {
|
|
856
|
+
var _a, _b;
|
|
857
|
+
if (ref) {
|
|
858
|
+
this._ref = ref;
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
if (!params) params = {};
|
|
862
|
+
if (!params.position) params.position = {
|
|
863
|
+
x: 100,
|
|
864
|
+
y: 100
|
|
865
|
+
};
|
|
866
|
+
if (!params.radius) params.radius = {
|
|
867
|
+
x: 25,
|
|
868
|
+
y: 25
|
|
869
|
+
};
|
|
870
|
+
this._ref = new Konva.Ellipse({
|
|
871
|
+
stroke: (_a = params.color) !== null && _a !== void 0 ? _a : "#ff0000",
|
|
872
|
+
strokeWidth: (_b = params.lineWidth) !== null && _b !== void 0 ? _b : 4,
|
|
873
|
+
globalCompositeOperation: "source-over",
|
|
874
|
+
lineCap: "round",
|
|
875
|
+
lineJoin: "round",
|
|
876
|
+
x: params.position.x,
|
|
877
|
+
y: params.position.y,
|
|
878
|
+
radiusX: params.radius.x,
|
|
879
|
+
radiusY: params.radius.y,
|
|
880
|
+
draggable: true,
|
|
881
|
+
strokeScaleEnabled: false
|
|
882
|
+
});
|
|
883
|
+
this._ref.on("transform", (e => {
|
|
884
|
+
const attrs = e.target.attrs;
|
|
885
|
+
if (attrs.rotation !== this._ref.rotation()) this._ref.rotation(attrs.rotation);
|
|
886
|
+
const scaleByX = Math.abs(attrs.scaleX - 1) > 1e-5;
|
|
887
|
+
const scaleByY = Math.abs(attrs.scaleY - 1) > 1e-5;
|
|
888
|
+
let newRadiusX = this._ref.radiusX();
|
|
889
|
+
if (scaleByX) newRadiusX *= attrs.scaleX;
|
|
890
|
+
let newRadiusY = this._ref.radiusY();
|
|
891
|
+
if (scaleByY) newRadiusY *= attrs.scaleY;
|
|
892
|
+
const minRadiusX = 25;
|
|
893
|
+
const minRadiusY = 25;
|
|
894
|
+
if (newRadiusX < minRadiusX) newRadiusX = minRadiusX;
|
|
895
|
+
if (newRadiusY < minRadiusY) newRadiusY = minRadiusY;
|
|
896
|
+
if (e.evt.ctrlKey || e.evt.shiftKey) {
|
|
897
|
+
if (scaleByX) {
|
|
898
|
+
this._ref.radius({
|
|
899
|
+
x: newRadiusX,
|
|
900
|
+
y: newRadiusX
|
|
901
|
+
});
|
|
902
|
+
} else {
|
|
903
|
+
this._ref.radius({
|
|
904
|
+
x: newRadiusY,
|
|
905
|
+
y: newRadiusY
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
} else {
|
|
909
|
+
this._ref.radius({
|
|
910
|
+
x: newRadiusX,
|
|
911
|
+
y: newRadiusY
|
|
912
|
+
});
|
|
913
|
+
}
|
|
914
|
+
this._ref.scale({
|
|
915
|
+
x: 1,
|
|
916
|
+
y: 1
|
|
917
|
+
});
|
|
918
|
+
}));
|
|
919
|
+
this._ref.id(this._ref._id.toString());
|
|
920
|
+
}
|
|
921
|
+
getPosition() {
|
|
922
|
+
return this._ref.position();
|
|
923
|
+
}
|
|
924
|
+
setPosition(x, y) {
|
|
925
|
+
this._ref.setPosition({
|
|
926
|
+
x: x,
|
|
927
|
+
y: y
|
|
928
|
+
});
|
|
929
|
+
}
|
|
930
|
+
getRadiusX() {
|
|
931
|
+
return this._ref.radiusX();
|
|
932
|
+
}
|
|
933
|
+
setRadiusX(r) {
|
|
934
|
+
this._ref.radiusX(r);
|
|
935
|
+
}
|
|
936
|
+
getRadiusY() {
|
|
937
|
+
return this._ref.radiusY();
|
|
938
|
+
}
|
|
939
|
+
setRadiusY(r) {
|
|
940
|
+
this._ref.radiusY(r);
|
|
941
|
+
}
|
|
942
|
+
getLineWidth() {
|
|
943
|
+
return this._ref.strokeWidth();
|
|
944
|
+
}
|
|
945
|
+
setLineWidth(size) {
|
|
946
|
+
this._ref.strokeWidth(size);
|
|
947
|
+
}
|
|
948
|
+
ref() {
|
|
949
|
+
return this._ref;
|
|
950
|
+
}
|
|
951
|
+
id() {
|
|
952
|
+
return this._ref.id();
|
|
953
|
+
}
|
|
954
|
+
enableMouseEditing(value) {
|
|
955
|
+
this._ref.draggable(value);
|
|
956
|
+
}
|
|
957
|
+
type() {
|
|
958
|
+
return "Ellipse";
|
|
959
|
+
}
|
|
960
|
+
getColor() {
|
|
961
|
+
return this._ref.stroke();
|
|
962
|
+
}
|
|
963
|
+
setColor(hex) {
|
|
964
|
+
this._ref.stroke(hex);
|
|
965
|
+
}
|
|
966
|
+
getRotation() {
|
|
967
|
+
return this._ref.rotation();
|
|
968
|
+
}
|
|
969
|
+
setRotation(degrees) {
|
|
970
|
+
this._ref.rotation(degrees);
|
|
971
|
+
}
|
|
972
|
+
getZIndex() {
|
|
973
|
+
return this._ref.zIndex();
|
|
974
|
+
}
|
|
975
|
+
setZIndex(zIndex) {
|
|
976
|
+
this._ref.zIndex(zIndex);
|
|
977
|
+
}
|
|
978
|
+
delete() {
|
|
979
|
+
this._ref.destroy();
|
|
980
|
+
this._ref = null;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
class KonvaArrow {
|
|
985
|
+
constructor(params, ref = null) {
|
|
986
|
+
var _a, _b;
|
|
987
|
+
if (ref) {
|
|
988
|
+
this._ref = ref;
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
if (!params) params = {};
|
|
992
|
+
if (!params.start) params.start = {
|
|
993
|
+
x: 50,
|
|
994
|
+
y: 50
|
|
995
|
+
};
|
|
996
|
+
if (!params.end) params.end = {
|
|
997
|
+
x: 100,
|
|
998
|
+
y: 100
|
|
999
|
+
};
|
|
1000
|
+
this._ref = new Konva.Arrow({
|
|
1001
|
+
stroke: (_a = params.color) !== null && _a !== void 0 ? _a : "#ff0000",
|
|
1002
|
+
fill: (_b = params.color) !== null && _b !== void 0 ? _b : "#ff0000",
|
|
1003
|
+
strokeWidth: 4,
|
|
1004
|
+
globalCompositeOperation: "source-over",
|
|
1005
|
+
lineCap: "round",
|
|
1006
|
+
lineJoin: "round",
|
|
1007
|
+
points: [ params.start.x, params.start.y, params.end.x, params.end.y ],
|
|
1008
|
+
draggable: true,
|
|
1009
|
+
strokeScaleEnabled: false
|
|
1010
|
+
});
|
|
1011
|
+
this._ref.on("transform", (e => {
|
|
1012
|
+
const attrs = e.target.attrs;
|
|
1013
|
+
if (attrs.rotation !== this._ref.rotation()) this._ref.rotation(attrs.rotation);
|
|
1014
|
+
}));
|
|
1015
|
+
this._ref.id(this._ref._id.toString());
|
|
1016
|
+
}
|
|
1017
|
+
ref() {
|
|
1018
|
+
return this._ref;
|
|
1019
|
+
}
|
|
1020
|
+
id() {
|
|
1021
|
+
return this._ref.id();
|
|
1022
|
+
}
|
|
1023
|
+
enableMouseEditing(value) {
|
|
1024
|
+
this._ref.draggable(value);
|
|
1025
|
+
}
|
|
1026
|
+
type() {
|
|
1027
|
+
return "Arrow";
|
|
1028
|
+
}
|
|
1029
|
+
getColor() {
|
|
1030
|
+
return this._ref.stroke();
|
|
1031
|
+
}
|
|
1032
|
+
setColor(hex) {
|
|
1033
|
+
this._ref.stroke(hex);
|
|
1034
|
+
this._ref.fill(hex);
|
|
1035
|
+
}
|
|
1036
|
+
getRotation() {
|
|
1037
|
+
return this._ref.rotation();
|
|
1038
|
+
}
|
|
1039
|
+
setRotation(degrees) {
|
|
1040
|
+
this._ref.rotation(degrees);
|
|
1041
|
+
}
|
|
1042
|
+
getZIndex() {
|
|
1043
|
+
return this._ref.zIndex();
|
|
1044
|
+
}
|
|
1045
|
+
setZIndex(zIndex) {
|
|
1046
|
+
this._ref.zIndex(zIndex);
|
|
1047
|
+
}
|
|
1048
|
+
delete() {
|
|
1049
|
+
this._ref.destroy();
|
|
1050
|
+
this._ref = null;
|
|
1051
|
+
}
|
|
1052
|
+
getPoints() {
|
|
1053
|
+
const points = this._ref.points();
|
|
1054
|
+
return [ {
|
|
1055
|
+
x: points[0],
|
|
1056
|
+
y: points[1]
|
|
1057
|
+
}, {
|
|
1058
|
+
x: points[2],
|
|
1059
|
+
y: points[3]
|
|
1060
|
+
} ];
|
|
1061
|
+
}
|
|
1062
|
+
setPoints(points) {
|
|
1063
|
+
if (points.length === 2) {
|
|
1064
|
+
this._ref.points([ points[0].x, points[0].y, points[1].x, points[1].y ]);
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
getStartPoint() {
|
|
1068
|
+
const points = this._ref.points();
|
|
1069
|
+
return {
|
|
1070
|
+
x: points[0],
|
|
1071
|
+
y: points[1]
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
setStartPoint(x, y) {
|
|
1075
|
+
const points = this._ref.points();
|
|
1076
|
+
this._ref.points([ x, y, points[2], points[3] ]);
|
|
1077
|
+
}
|
|
1078
|
+
getEndPoint() {
|
|
1079
|
+
const points = this._ref.points();
|
|
1080
|
+
return {
|
|
1081
|
+
x: points[2],
|
|
1082
|
+
y: points[3]
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
setEndPoint(x, y) {
|
|
1086
|
+
const points = this._ref.points();
|
|
1087
|
+
this._ref.points([ points[0], points[1], x, y ]);
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
class KonvaImage {
|
|
1092
|
+
constructor(params, ref = null) {
|
|
1093
|
+
var _a, _b;
|
|
1094
|
+
this._ratio = 1;
|
|
1095
|
+
this.EPSILON = 1e-5;
|
|
1096
|
+
this.BASE64_HEADER_START = "data:image/";
|
|
1097
|
+
this.BASE64_NOT_FOUND = "data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAADsAAAA7AF5KHG9AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAmhJREFUWIXtlr9rVEEQxz+H8RQUJIdeIopYm0vkCg0GBBtbG1NF7Kxt7dR/IGIw/uhTaBNLERURg2kCEUyCYCPi70b0InjGS57FzOZN3r19d+9HJIVfWO52dma/s7Mz8xa2KAaBCWAR+AkECWOmSOIdwC1gtQOpHc+NfQ8wClQ8+1d0vcdH/lQ3bSIRGAZ2pTjAqNovANXIWlXlAXA2zvi2Ln4AjqYgtagYEutENSLvjRoOImFv5iB32Ae8UrLXwFBk3h9ndF0VJnKSO9gTu3yKu5Z1LKnS8YIcABgw5Ks692JZFXcXRJ46Aq6kikCnHNi/mQ50WwVtfaIoBzL3gRk2drSscJ2wrc4VvUoe2wn/41/iBfoVLRnBGnDSY3AAKacy8AmYR+o7K1zCl6wgrgpOAc/MuhvfgMuk+1JGHQgSBcAloKXy78AjYBppJk5/noTulseBMZ23iD/piHFkEdgTQzKk+5wHjmHC3cmBg0BD5xcSTrFXyQPgIWFtDwMvab+2N8DpbhyY1v/3E8gdDgNfVX9SCVZ0/gW4B0wB71S2BpxLcuCM/jaQSHSDEeAX4VMuAG4gTzyHbcAVXXO6GxxwIX+vvxe7JHcYQ07nHqklj96UIW/YhSWzMKcep8VVtf8B1Dw6h4DfhB+sdbgn2R+gnoEc5NR3dZ+3QJ9H74HqXLPCGlJyTfI9y3YCs0owq3OLOpKkLeBI1HhSDT/mdKIPiUCARMTlQx34TMLjtww8IczmO8AJ/N/2JNSQXAiQ671JePePge0+wzJSQq4FFzlaenIvucUAkiQLhC/mLGNZ9xgn5s63BP4CCk0QDtm4BhoAAAAASUVORK5CYII=";
|
|
1098
|
+
if (ref) {
|
|
1099
|
+
if (!ref.src || !ref.src.startsWith(this.BASE64_HEADER_START)) ref.src = this.BASE64_NOT_FOUND;
|
|
1100
|
+
if (ref.height() <= this.EPSILON) ref.height(32);
|
|
1101
|
+
if (ref.width() <= this.EPSILON) ref.width(32);
|
|
1102
|
+
this._ref = ref;
|
|
1103
|
+
this._canvasImage = ref.image();
|
|
1104
|
+
this._ratio = this._ref.height() <= this.EPSILON || this._ref.width() <= this.EPSILON ? 1 : this._ref.height() / this._ref.width();
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
if (!params) params = {};
|
|
1108
|
+
if (!params.position) params.position = {
|
|
1109
|
+
x: 50,
|
|
1110
|
+
y: 50
|
|
1111
|
+
};
|
|
1112
|
+
if (!params.src || !params.src.startsWith(this.BASE64_HEADER_START)) params.src = this.BASE64_NOT_FOUND;
|
|
1113
|
+
this._canvasImage = new Image;
|
|
1114
|
+
this._canvasImage.onload = () => {
|
|
1115
|
+
this._ref.image(this._canvasImage);
|
|
1116
|
+
if (this._ref.height() <= this.EPSILON) this._ref.height(this._canvasImage.height);
|
|
1117
|
+
if (this._ref.width() <= this.EPSILON) this._ref.width(this._canvasImage.width);
|
|
1118
|
+
this._ratio = this._ref.height() <= this.EPSILON || this._ref.width() <= this.EPSILON ? 1 : this._ref.height() / this._ref.width();
|
|
1119
|
+
if ((params.width <= this.EPSILON || params.height <= this.EPSILON) && (params.maxWidth >= this.EPSILON || params.maxWidth >= this.EPSILON)) {
|
|
1120
|
+
const heightOutOfCanvas = params.maxHeight - this._canvasImage.height;
|
|
1121
|
+
const widthOutOfCanvas = params.maxWidth - this._canvasImage.width;
|
|
1122
|
+
if (heightOutOfCanvas <= this.EPSILON || widthOutOfCanvas <= this.EPSILON) {
|
|
1123
|
+
if (widthOutOfCanvas <= this.EPSILON && widthOutOfCanvas < heightOutOfCanvas / this._ratio) {
|
|
1124
|
+
this._ref.height(params.maxWidth * this._ratio);
|
|
1125
|
+
this._ref.width(params.maxWidth);
|
|
1126
|
+
} else {
|
|
1127
|
+
this._ref.width(params.maxHeight / this._ratio);
|
|
1128
|
+
this._ref.height(params.maxHeight);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
};
|
|
1133
|
+
this._canvasImage.onerror = () => {
|
|
1134
|
+
this._canvasImage.onerror = function() {};
|
|
1135
|
+
this._canvasImage.src = this.BASE64_NOT_FOUND;
|
|
1136
|
+
};
|
|
1137
|
+
this._canvasImage.src = params.src;
|
|
1138
|
+
this._ref = new Konva.Image({
|
|
1139
|
+
x: params.position.x,
|
|
1140
|
+
y: params.position.y,
|
|
1141
|
+
image: this._canvasImage,
|
|
1142
|
+
width: (_a = params.width) !== null && _a !== void 0 ? _a : 0,
|
|
1143
|
+
height: (_b = params.height) !== null && _b !== void 0 ? _b : 0,
|
|
1144
|
+
draggable: true
|
|
1145
|
+
});
|
|
1146
|
+
this._ref.on("transform", (e => {
|
|
1147
|
+
const attrs = e.target.attrs;
|
|
1148
|
+
if (attrs.rotation !== this._ref.rotation()) this._ref.rotation(attrs.rotation);
|
|
1149
|
+
const scaleByX = Math.abs(attrs.scaleX - 1) > 1e-5;
|
|
1150
|
+
const scaleByY = Math.abs(attrs.scaleY - 1) > 1e-5;
|
|
1151
|
+
let newWidth = this._ref.width();
|
|
1152
|
+
if (scaleByX) newWidth *= attrs.scaleX;
|
|
1153
|
+
let newHeight = this._ref.height();
|
|
1154
|
+
if (scaleByY) newHeight *= attrs.scaleY;
|
|
1155
|
+
if (e.evt.ctrlKey || e.evt.shiftKey) {
|
|
1156
|
+
if (scaleByX) {
|
|
1157
|
+
this._ref.width(newWidth);
|
|
1158
|
+
this._ref.height(newWidth * this._ratio);
|
|
1159
|
+
} else {
|
|
1160
|
+
this._ref.width(newHeight / this._ratio);
|
|
1161
|
+
this._ref.height(newHeight);
|
|
1162
|
+
}
|
|
1163
|
+
} else {
|
|
1164
|
+
if (scaleByX) {
|
|
1165
|
+
this._ref.width(newWidth);
|
|
1166
|
+
}
|
|
1167
|
+
if (scaleByY) {
|
|
1168
|
+
this._ref.height(newHeight);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
this._ref.scale({
|
|
1172
|
+
x: 1,
|
|
1173
|
+
y: 1
|
|
1174
|
+
});
|
|
1175
|
+
}));
|
|
1176
|
+
this._ref.id(this._ref._id.toString());
|
|
1177
|
+
}
|
|
1178
|
+
getSrc() {
|
|
1179
|
+
return this._canvasImage.src;
|
|
1180
|
+
}
|
|
1181
|
+
setSrc(src) {
|
|
1182
|
+
this._canvasImage.src = src;
|
|
1183
|
+
}
|
|
1184
|
+
getWidth() {
|
|
1185
|
+
return this._ref.width();
|
|
1186
|
+
}
|
|
1187
|
+
setWidth(w) {
|
|
1188
|
+
this._ref.width(w);
|
|
1189
|
+
this._ref.height(w * this._ratio);
|
|
1190
|
+
}
|
|
1191
|
+
getHeight() {
|
|
1192
|
+
return this._ref.height();
|
|
1193
|
+
}
|
|
1194
|
+
setHeight(h) {
|
|
1195
|
+
this._ref.height(h);
|
|
1196
|
+
this._ref.width(h / this._ratio);
|
|
1197
|
+
}
|
|
1198
|
+
ref() {
|
|
1199
|
+
return this._ref;
|
|
1200
|
+
}
|
|
1201
|
+
id() {
|
|
1202
|
+
return this._ref.id();
|
|
1203
|
+
}
|
|
1204
|
+
enableMouseEditing(value) {
|
|
1205
|
+
this._ref.draggable(value);
|
|
1206
|
+
}
|
|
1207
|
+
type() {
|
|
1208
|
+
return "Image";
|
|
1209
|
+
}
|
|
1210
|
+
getRotation() {
|
|
1211
|
+
return this._ref.rotation();
|
|
1212
|
+
}
|
|
1213
|
+
setRotation(degrees) {
|
|
1214
|
+
this._ref.rotation(degrees);
|
|
1215
|
+
}
|
|
1216
|
+
getZIndex() {
|
|
1217
|
+
return this._ref.zIndex();
|
|
1218
|
+
}
|
|
1219
|
+
setZIndex(zIndex) {
|
|
1220
|
+
this._ref.zIndex(zIndex);
|
|
1221
|
+
}
|
|
1222
|
+
delete() {
|
|
1223
|
+
this._ref.destroy();
|
|
1224
|
+
this._ref = null;
|
|
1225
|
+
}
|
|
1226
|
+
getPosition() {
|
|
1227
|
+
return this._ref.getPosition();
|
|
1228
|
+
}
|
|
1229
|
+
setPosition(x, y) {
|
|
1230
|
+
this._ref.setPosition({
|
|
1231
|
+
x: x,
|
|
1232
|
+
y: y
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
class KonvaCloud {
|
|
1238
|
+
constructor(params, ref = null) {
|
|
1239
|
+
var _a, _b, _c, _d;
|
|
1240
|
+
if (ref) {
|
|
1241
|
+
this._ref = ref;
|
|
1242
|
+
return;
|
|
1243
|
+
}
|
|
1244
|
+
if (!params) params = {};
|
|
1245
|
+
if (!params.position) params.position = {
|
|
1246
|
+
x: 100,
|
|
1247
|
+
y: 100
|
|
1248
|
+
};
|
|
1249
|
+
const arcRadius = 16;
|
|
1250
|
+
this._ref = new Konva.Shape({
|
|
1251
|
+
x: params.position.x,
|
|
1252
|
+
y: params.position.y,
|
|
1253
|
+
width: (_a = params.width) !== null && _a !== void 0 ? _a : 200,
|
|
1254
|
+
height: (_b = params.height) !== null && _b !== void 0 ? _b : 200,
|
|
1255
|
+
stroke: (_c = params.color) !== null && _c !== void 0 ? _c : "#ff0000",
|
|
1256
|
+
strokeWidth: (_d = params.lineWidth) !== null && _d !== void 0 ? _d : 4,
|
|
1257
|
+
draggable: true,
|
|
1258
|
+
strokeScaleEnabled: false,
|
|
1259
|
+
globalCompositeOperation: "source-over",
|
|
1260
|
+
sceneFunc: (context, shape) => {
|
|
1261
|
+
function calculateMidpoint(position, width, height) {
|
|
1262
|
+
const midX = position.x + width / 2;
|
|
1263
|
+
const midY = position.y + height / 2;
|
|
1264
|
+
return {
|
|
1265
|
+
x: midX,
|
|
1266
|
+
y: midY
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
const points = [ {
|
|
1270
|
+
x: 0,
|
|
1271
|
+
y: 0
|
|
1272
|
+
}, {
|
|
1273
|
+
x: 0 + this._ref.width(),
|
|
1274
|
+
y: 0
|
|
1275
|
+
}, {
|
|
1276
|
+
x: 0 + this._ref.width(),
|
|
1277
|
+
y: 0 + this._ref.height()
|
|
1278
|
+
}, {
|
|
1279
|
+
x: 0,
|
|
1280
|
+
y: 0 + this._ref.height()
|
|
1281
|
+
}, {
|
|
1282
|
+
x: 0,
|
|
1283
|
+
y: 0
|
|
1284
|
+
} ];
|
|
1285
|
+
const midPoint = calculateMidpoint({
|
|
1286
|
+
x: 0,
|
|
1287
|
+
y: 0
|
|
1288
|
+
}, this._ref.width(), this._ref.height());
|
|
1289
|
+
const baseArcLength = 30;
|
|
1290
|
+
context.beginPath();
|
|
1291
|
+
for (let iPoint = 0; iPoint < points.length - 1; iPoint++) {
|
|
1292
|
+
let approxArcLength = baseArcLength;
|
|
1293
|
+
const dx = points[iPoint + 1].x - points[iPoint].x;
|
|
1294
|
+
const dy = points[iPoint + 1].y - points[iPoint].y;
|
|
1295
|
+
const length = Math.sqrt(dx * dx + dy * dy);
|
|
1296
|
+
const arcCount = Math.floor(length / approxArcLength);
|
|
1297
|
+
const lengthMod = length % approxArcLength;
|
|
1298
|
+
approxArcLength = baseArcLength + arcCount / lengthMod;
|
|
1299
|
+
let pX = points[iPoint].x + dx / arcCount / 2;
|
|
1300
|
+
let pY = points[iPoint].y + dy / arcCount / 2;
|
|
1301
|
+
const pEndX = points[iPoint + 1].x;
|
|
1302
|
+
const pEndY = points[iPoint + 1].y;
|
|
1303
|
+
const endAngle = Math.atan((pEndY - pY) / (pEndX - pX));
|
|
1304
|
+
const startAngle = endAngle + Math.PI;
|
|
1305
|
+
const counterClockwise = pX > midPoint.x && pY > midPoint.y;
|
|
1306
|
+
for (let iArc = 0; iArc < arcCount; iArc++) {
|
|
1307
|
+
if (counterClockwise) {
|
|
1308
|
+
context.arc(pX, pY, arcRadius, endAngle, startAngle);
|
|
1309
|
+
} else {
|
|
1310
|
+
context.arc(pX, pY, arcRadius, startAngle, endAngle);
|
|
1311
|
+
}
|
|
1312
|
+
pX += dx / arcCount;
|
|
1313
|
+
pY += dy / arcCount;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
context.closePath();
|
|
1317
|
+
context.fillStrokeShape(shape);
|
|
1318
|
+
}
|
|
1319
|
+
});
|
|
1320
|
+
this._ref.className = "Cloud";
|
|
1321
|
+
this._ref.on("transform", (e => {
|
|
1322
|
+
const attrs = e.target.attrs;
|
|
1323
|
+
if (attrs.rotation !== this._ref.rotation()) this._ref.rotation(attrs.rotation);
|
|
1324
|
+
const scaleByX = Math.abs(attrs.scaleX - 1) > 1e-5;
|
|
1325
|
+
const scaleByY = Math.abs(attrs.scaleY - 1) > 1e-5;
|
|
1326
|
+
let newWidth = this._ref.width();
|
|
1327
|
+
if (scaleByX) newWidth *= attrs.scaleX;
|
|
1328
|
+
let newHeight = this._ref.height();
|
|
1329
|
+
if (scaleByY) newHeight *= attrs.scaleY;
|
|
1330
|
+
const minWidth = 100;
|
|
1331
|
+
const minHeight = 100;
|
|
1332
|
+
if (newWidth < minWidth) newWidth = minWidth;
|
|
1333
|
+
if (newHeight < minHeight) newHeight = minHeight;
|
|
1334
|
+
if (scaleByX) {
|
|
1335
|
+
this._ref.width(newWidth);
|
|
1336
|
+
}
|
|
1337
|
+
if (scaleByY) {
|
|
1338
|
+
this._ref.height(newHeight);
|
|
1339
|
+
}
|
|
1340
|
+
this._ref.scale({
|
|
1341
|
+
x: 1,
|
|
1342
|
+
y: 1
|
|
1343
|
+
});
|
|
1344
|
+
}));
|
|
1345
|
+
this._ref.getSelfRect = () => ({
|
|
1346
|
+
x: 0 - arcRadius,
|
|
1347
|
+
y: 0 - arcRadius,
|
|
1348
|
+
width: this._ref.width() + 2 * arcRadius,
|
|
1349
|
+
height: this._ref.height() + 2 * arcRadius
|
|
1350
|
+
});
|
|
1351
|
+
this._ref.id(this._ref._id.toString());
|
|
1352
|
+
}
|
|
1353
|
+
ref() {
|
|
1354
|
+
return this._ref;
|
|
1355
|
+
}
|
|
1356
|
+
id() {
|
|
1357
|
+
return this._ref.id();
|
|
1358
|
+
}
|
|
1359
|
+
enableMouseEditing(value) {
|
|
1360
|
+
this._ref.draggable(value);
|
|
1361
|
+
}
|
|
1362
|
+
type() {
|
|
1363
|
+
return "Cloud";
|
|
1364
|
+
}
|
|
1365
|
+
getColor() {
|
|
1366
|
+
return this._ref.stroke();
|
|
1367
|
+
}
|
|
1368
|
+
setColor(hex) {
|
|
1369
|
+
this._ref.stroke(hex);
|
|
1370
|
+
}
|
|
1371
|
+
getRotation() {
|
|
1372
|
+
return this._ref.rotation();
|
|
1373
|
+
}
|
|
1374
|
+
setRotation(degrees) {
|
|
1375
|
+
this._ref.rotation(degrees);
|
|
1376
|
+
}
|
|
1377
|
+
getZIndex() {
|
|
1378
|
+
return this._ref.zIndex();
|
|
1379
|
+
}
|
|
1380
|
+
setZIndex(zIndex) {
|
|
1381
|
+
this._ref.zIndex(zIndex);
|
|
1382
|
+
}
|
|
1383
|
+
delete() {
|
|
1384
|
+
this._ref.destroy();
|
|
1385
|
+
this._ref = null;
|
|
1386
|
+
}
|
|
1387
|
+
getPosition() {
|
|
1388
|
+
return this._ref.position();
|
|
1389
|
+
}
|
|
1390
|
+
setPosition(x, y) {
|
|
1391
|
+
this._ref.position({
|
|
1392
|
+
x: x,
|
|
1393
|
+
y: y
|
|
1394
|
+
});
|
|
1395
|
+
}
|
|
1396
|
+
getWidth() {
|
|
1397
|
+
return this._ref.width();
|
|
1398
|
+
}
|
|
1399
|
+
setWidth(w) {
|
|
1400
|
+
this._ref.width(w);
|
|
1401
|
+
}
|
|
1402
|
+
getHeigth() {
|
|
1403
|
+
return this._ref.height();
|
|
1404
|
+
}
|
|
1405
|
+
setHeight(h) {
|
|
1406
|
+
this._ref.height(h);
|
|
1407
|
+
}
|
|
1408
|
+
getLineWidth() {
|
|
1409
|
+
return this._ref.strokeWidth();
|
|
1410
|
+
}
|
|
1411
|
+
setLineWidth(size) {
|
|
1412
|
+
this._ref.strokeWidth(size);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
14
1415
|
|
|
15
|
-
|
|
1416
|
+
const MarkupMode2Konva = {
|
|
1417
|
+
SelectMarkup: {
|
|
1418
|
+
name: "SelectMarkup",
|
|
1419
|
+
initializer: null
|
|
1420
|
+
},
|
|
1421
|
+
Line: {
|
|
1422
|
+
name: "Line",
|
|
1423
|
+
initializer: (ref, params = null) => new KonvaLine(params, ref)
|
|
1424
|
+
},
|
|
1425
|
+
Text: {
|
|
1426
|
+
name: "Text",
|
|
1427
|
+
initializer: (ref, params = null) => new KonvaText(params, ref)
|
|
1428
|
+
},
|
|
1429
|
+
Rectangle: {
|
|
1430
|
+
name: "Rect",
|
|
1431
|
+
initializer: (ref, params = null) => new KonvaRectangle(params, ref)
|
|
1432
|
+
},
|
|
1433
|
+
Ellipse: {
|
|
1434
|
+
name: "Ellipse",
|
|
1435
|
+
initializer: (ref, params = null) => new KonvaEllipse(params, ref)
|
|
1436
|
+
},
|
|
1437
|
+
Arrow: {
|
|
1438
|
+
name: "Arrow",
|
|
1439
|
+
initializer: (ref, params = null) => new KonvaArrow(params, ref)
|
|
1440
|
+
},
|
|
1441
|
+
Image: {
|
|
1442
|
+
name: "Image",
|
|
1443
|
+
initializer: (ref, params = null) => new KonvaImage(params, ref)
|
|
1444
|
+
},
|
|
1445
|
+
Cloud: {
|
|
1446
|
+
name: "Cloud",
|
|
1447
|
+
initializer: (ref, params = null) => new KonvaCloud(params, ref)
|
|
1448
|
+
}
|
|
1449
|
+
};
|
|
16
1450
|
|
|
17
|
-
|
|
1451
|
+
class KonvaMarkup {
|
|
1452
|
+
constructor() {
|
|
1453
|
+
this._containerEvents = [];
|
|
1454
|
+
this._markupIsActive = false;
|
|
1455
|
+
this._markupColor = new MarkupColor(255, 0, 0);
|
|
1456
|
+
this.lineWidth = 4;
|
|
1457
|
+
this.lineType = "solid";
|
|
1458
|
+
this.fontSize = 34;
|
|
1459
|
+
this.changeActiveDragger = event => {
|
|
1460
|
+
const draggerName = event.data;
|
|
1461
|
+
this._markupContainer.className = this._container.className.split(" ").filter((x => !x.startsWith("oda-cursor-"))).filter((x => x)).concat(`oda-cursor-${draggerName.toLowerCase()}`).join(" ");
|
|
1462
|
+
this.removeTextInput();
|
|
1463
|
+
this.removeImageInput();
|
|
1464
|
+
this.enableEditMode(draggerName);
|
|
1465
|
+
};
|
|
1466
|
+
this.resizeContainer = entries => {
|
|
1467
|
+
const {width: width, height: height} = entries[0].contentRect;
|
|
1468
|
+
if (!width || !height) return;
|
|
1469
|
+
if (!this._konvaStage) return;
|
|
1470
|
+
this._konvaStage.width(width);
|
|
1471
|
+
this._konvaStage.height(height);
|
|
1472
|
+
};
|
|
1473
|
+
this.pan = event => {
|
|
1474
|
+
const newPos = {
|
|
1475
|
+
x: this._konvaStage.x() + event.dX,
|
|
1476
|
+
y: this._konvaStage.y() + event.dY
|
|
1477
|
+
};
|
|
1478
|
+
this._konvaStage.position(newPos);
|
|
1479
|
+
};
|
|
1480
|
+
this.zoomAt = event => {
|
|
1481
|
+
const newScale = this._konvaStage.scaleX() * event.data;
|
|
1482
|
+
this._konvaStage.scale({
|
|
1483
|
+
x: newScale,
|
|
1484
|
+
y: newScale
|
|
1485
|
+
});
|
|
1486
|
+
const newPos = {
|
|
1487
|
+
x: event.x - (event.x - this._konvaStage.x()) * event.data,
|
|
1488
|
+
y: event.y - (event.y - this._konvaStage.y()) * event.data
|
|
1489
|
+
};
|
|
1490
|
+
this._konvaStage.position(newPos);
|
|
1491
|
+
};
|
|
1492
|
+
this.redirectToViewer = event => {
|
|
1493
|
+
if (this._viewer) this._viewer.emit(event);
|
|
1494
|
+
};
|
|
1495
|
+
this.getRelativePointPosition = (point, node) => {
|
|
1496
|
+
const transform = node.getAbsoluteTransform().copy();
|
|
1497
|
+
transform.invert();
|
|
1498
|
+
return transform.point(point);
|
|
1499
|
+
};
|
|
1500
|
+
this.getRelativePointerPosition = node => this.getRelativePointPosition(node.getStage().getPointerPosition(), node);
|
|
1501
|
+
}
|
|
1502
|
+
initialize(container, containerEvents, viewer, worldTransformer) {
|
|
1503
|
+
if (!Konva) throw new Error('Markup error: Konva is not initialized. Forgot to add <script src="https://unpkg.com/konva@9/konva.min.js"><\/script> to your page?');
|
|
1504
|
+
this._viewer = viewer;
|
|
1505
|
+
this._worldTransformer = worldTransformer !== null && worldTransformer !== void 0 ? worldTransformer : new WorldTransform;
|
|
1506
|
+
this._container = container;
|
|
1507
|
+
this._containerEvents = containerEvents !== null && containerEvents !== void 0 ? containerEvents : [];
|
|
1508
|
+
this._markupContainer = document.createElement("div");
|
|
1509
|
+
this._markupContainer.id = "markup-container";
|
|
1510
|
+
this._markupContainer.style.position = "absolute";
|
|
1511
|
+
this._markupContainer.style.top = "0px";
|
|
1512
|
+
this._markupContainer.style.left = "0px";
|
|
1513
|
+
this._markupContainer.style.outline = "0px";
|
|
1514
|
+
this._markupContainer.style.pointerEvents = "none";
|
|
1515
|
+
const parentDiv = this._container.parentElement;
|
|
1516
|
+
parentDiv.appendChild(this._markupContainer);
|
|
1517
|
+
this._resizeObserver = new ResizeObserver(this.resizeContainer);
|
|
1518
|
+
this._resizeObserver.observe(parentDiv);
|
|
1519
|
+
this._markupColor.setColor(255, 0, 0);
|
|
1520
|
+
this.initializeKonva();
|
|
1521
|
+
if (this._viewer) {
|
|
1522
|
+
this._viewer.addEventListener("changeactivedragger", this.changeActiveDragger);
|
|
1523
|
+
this._viewer.addEventListener("pan", this.pan);
|
|
1524
|
+
this._viewer.addEventListener("zoomat", this.zoomAt);
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
dispose() {
|
|
1528
|
+
var _a, _b;
|
|
1529
|
+
if (this._viewer) {
|
|
1530
|
+
this._viewer.removeEventListener("zoomat", this.zoomAt);
|
|
1531
|
+
this._viewer.removeEventListener("pan", this.pan);
|
|
1532
|
+
this._viewer.removeEventListener("changeactivedragger", this.changeActiveDragger);
|
|
1533
|
+
}
|
|
1534
|
+
this.destroyKonva();
|
|
1535
|
+
(_a = this._resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
1536
|
+
this._resizeObserver = undefined;
|
|
1537
|
+
(_b = this._markupContainer) === null || _b === void 0 ? void 0 : _b.remove();
|
|
1538
|
+
this._markupContainer = undefined;
|
|
1539
|
+
this._container = undefined;
|
|
1540
|
+
this._viewer = undefined;
|
|
1541
|
+
this._worldTransformer = undefined;
|
|
1542
|
+
this._markupIsActive = false;
|
|
1543
|
+
}
|
|
1544
|
+
syncOverlay() {}
|
|
1545
|
+
clearOverlay() {
|
|
1546
|
+
this.removeTextInput();
|
|
1547
|
+
this.removeImageInput();
|
|
1548
|
+
this.clearSelected();
|
|
1549
|
+
this.getObjects().forEach((obj => obj.delete()));
|
|
1550
|
+
}
|
|
1551
|
+
getMarkupColor() {
|
|
1552
|
+
return this._markupColor.asRGB();
|
|
1553
|
+
}
|
|
1554
|
+
setMarkupColor(r, g, b) {
|
|
1555
|
+
this._markupColor.setColor(r, g, b);
|
|
1556
|
+
this._viewer.emit({
|
|
1557
|
+
type: "changemarkupcolor",
|
|
1558
|
+
data: {
|
|
1559
|
+
r: r,
|
|
1560
|
+
g: g,
|
|
1561
|
+
b: b
|
|
1562
|
+
}
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
colorizeAllMarkup(r, g, b) {
|
|
1566
|
+
const hexColor = new MarkupColor(r, g, b).asHex();
|
|
1567
|
+
this.getObjects().filter((obj => {
|
|
1568
|
+
var _a;
|
|
1569
|
+
return (_a = obj.setColor) === null || _a === void 0 ? void 0 : _a.call(obj, hexColor);
|
|
1570
|
+
}));
|
|
1571
|
+
}
|
|
1572
|
+
colorizeSelectedMarkups(r, g, b) {
|
|
1573
|
+
const hexColor = new MarkupColor(r, g, b).asHex();
|
|
1574
|
+
this.getSelectedObjects().filter((obj => {
|
|
1575
|
+
var _a;
|
|
1576
|
+
return (_a = obj.setColor) === null || _a === void 0 ? void 0 : _a.call(obj, hexColor);
|
|
1577
|
+
}));
|
|
1578
|
+
}
|
|
1579
|
+
setViewpoint(viewpoint) {
|
|
1580
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1581
|
+
this.clearSelected();
|
|
1582
|
+
this.removeTextInput();
|
|
1583
|
+
this.removeImageInput();
|
|
1584
|
+
this._konvaStage.scale({
|
|
1585
|
+
x: 1,
|
|
1586
|
+
y: 1
|
|
1587
|
+
});
|
|
1588
|
+
this._konvaStage.position({
|
|
1589
|
+
x: 0,
|
|
1590
|
+
y: 0
|
|
1591
|
+
});
|
|
1592
|
+
const markupColor = ((_a = viewpoint.custom_fields) === null || _a === void 0 ? void 0 : _a.markup_color) || {
|
|
1593
|
+
r: 255,
|
|
1594
|
+
g: 0,
|
|
1595
|
+
b: 0
|
|
1596
|
+
};
|
|
1597
|
+
this.setMarkupColor(markupColor.r, markupColor.g, markupColor.b);
|
|
1598
|
+
(_b = viewpoint.lines) === null || _b === void 0 ? void 0 : _b.forEach((line => {
|
|
1599
|
+
const linePoints = [];
|
|
1600
|
+
line.points.forEach((point => {
|
|
1601
|
+
const screenPoint = this._worldTransformer.worldToScreen(point);
|
|
1602
|
+
linePoints.push(screenPoint.x);
|
|
1603
|
+
linePoints.push(screenPoint.y);
|
|
1604
|
+
}));
|
|
1605
|
+
this.addLine(linePoints, line.color, line.type, line.width, line.id);
|
|
1606
|
+
}));
|
|
1607
|
+
(_c = viewpoint.texts) === null || _c === void 0 ? void 0 : _c.forEach((text => {
|
|
1608
|
+
const screenPoint = this._worldTransformer.worldToScreen(text.position);
|
|
1609
|
+
this.addText(text.text, screenPoint, text.angle, text.color, text.text_size, text.font_size, text.id);
|
|
1610
|
+
}));
|
|
1611
|
+
(_d = viewpoint.rectangles) === null || _d === void 0 ? void 0 : _d.forEach((rect => {
|
|
1612
|
+
const screenPoint = this._worldTransformer.worldToScreen(rect.position);
|
|
1613
|
+
this.addRectangle(screenPoint, rect.width, rect.height, rect.line_width, rect.color, rect.id);
|
|
1614
|
+
}));
|
|
1615
|
+
(_e = viewpoint.ellipses) === null || _e === void 0 ? void 0 : _e.forEach((ellipse => {
|
|
1616
|
+
const screenPoint = this._worldTransformer.worldToScreen(ellipse.position);
|
|
1617
|
+
this.addEllipse(screenPoint, ellipse.radius, ellipse.line_width, ellipse.color, ellipse.id);
|
|
1618
|
+
}));
|
|
1619
|
+
(_f = viewpoint.arrows) === null || _f === void 0 ? void 0 : _f.forEach((arrow => {
|
|
1620
|
+
const startPoint = this._worldTransformer.worldToScreen(arrow.start);
|
|
1621
|
+
const endPoint = this._worldTransformer.worldToScreen(arrow.end);
|
|
1622
|
+
this.addArrow(startPoint, endPoint, arrow.color, arrow.id);
|
|
1623
|
+
}));
|
|
1624
|
+
(_g = viewpoint.clouds) === null || _g === void 0 ? void 0 : _g.forEach((cloud => {
|
|
1625
|
+
const screenPoint = this._worldTransformer.worldToScreen(cloud.position);
|
|
1626
|
+
this.addCloud(screenPoint, cloud.width, cloud.height, cloud.line_width, cloud.color, cloud.id);
|
|
1627
|
+
}));
|
|
1628
|
+
(_h = viewpoint.images) === null || _h === void 0 ? void 0 : _h.forEach((image => {
|
|
1629
|
+
const screenPoint = this._worldTransformer.worldToScreen(image.position);
|
|
1630
|
+
this.addImage(screenPoint, image.src, image.width, image.height, image.id);
|
|
1631
|
+
}));
|
|
1632
|
+
}
|
|
1633
|
+
getViewpoint(viewpoint) {
|
|
1634
|
+
if (!viewpoint) viewpoint = {};
|
|
1635
|
+
viewpoint.lines = this.getMarkupLines();
|
|
1636
|
+
viewpoint.texts = this.getMarkupTexts();
|
|
1637
|
+
viewpoint.arrows = this.getMarkupArrows();
|
|
1638
|
+
viewpoint.clouds = this.getMarkupClouds();
|
|
1639
|
+
viewpoint.ellipses = this.getMarkupEllipses();
|
|
1640
|
+
viewpoint.images = this.getMarkupImages();
|
|
1641
|
+
viewpoint.rectangles = this.getMarkupRectangles();
|
|
1642
|
+
viewpoint.custom_fields = {
|
|
1643
|
+
markup_color: this.getMarkupColor()
|
|
1644
|
+
};
|
|
1645
|
+
viewpoint.snapshot = {
|
|
1646
|
+
data: this.combineMarkupWithDrawing()
|
|
1647
|
+
};
|
|
1648
|
+
return viewpoint;
|
|
1649
|
+
}
|
|
1650
|
+
enableEditMode(mode) {
|
|
1651
|
+
if (!mode || !MarkupMode2Konva[mode]) {
|
|
1652
|
+
this.clearSelected();
|
|
1653
|
+
this.removeTextInput();
|
|
1654
|
+
this.removeImageInput();
|
|
1655
|
+
this._markupContainer.style.pointerEvents = "none";
|
|
1656
|
+
this._markupIsActive = false;
|
|
1657
|
+
} else {
|
|
1658
|
+
this._markupMode = mode;
|
|
1659
|
+
this._markupContainer.style.pointerEvents = "all";
|
|
1660
|
+
this._markupIsActive = true;
|
|
1661
|
+
}
|
|
1662
|
+
return this;
|
|
1663
|
+
}
|
|
1664
|
+
createObject(type, params) {
|
|
1665
|
+
const konvaShape = MarkupMode2Konva[type];
|
|
1666
|
+
if (!konvaShape || !konvaShape.initializer) throw new Error(`Markup CreateObject - unsupported markup type ${type}`);
|
|
1667
|
+
const object = konvaShape.initializer(null, params);
|
|
1668
|
+
this.addObject(object);
|
|
1669
|
+
return object;
|
|
1670
|
+
}
|
|
1671
|
+
getObjects() {
|
|
1672
|
+
const objects = [];
|
|
1673
|
+
Object.keys(MarkupMode2Konva).forEach((type => {
|
|
1674
|
+
const konvaShape = MarkupMode2Konva[type];
|
|
1675
|
+
this.konvaLayerFind(type).forEach((ref => objects.push(konvaShape.initializer(ref))));
|
|
1676
|
+
}));
|
|
1677
|
+
return objects;
|
|
1678
|
+
}
|
|
1679
|
+
getSelectedObjects() {
|
|
1680
|
+
if (!this._konvaTransformer) return [];
|
|
1681
|
+
return this._konvaTransformer.nodes().map((ref => {
|
|
1682
|
+
const name = ref.className;
|
|
1683
|
+
const konvaShape = Object.values(MarkupMode2Konva).find((shape => shape.name === name));
|
|
1684
|
+
return konvaShape ? konvaShape.initializer(ref) : null;
|
|
1685
|
+
})).filter((x => x));
|
|
1686
|
+
}
|
|
1687
|
+
selectObjects(objects) {
|
|
1688
|
+
if (!this._konvaTransformer) return;
|
|
1689
|
+
const selectedObjs = this._konvaTransformer.nodes().concat(objects.map((x => x.ref())));
|
|
1690
|
+
this._konvaTransformer.nodes(selectedObjs);
|
|
1691
|
+
}
|
|
1692
|
+
clearSelected() {
|
|
1693
|
+
if (this._konvaTransformer) this._konvaTransformer.nodes([]);
|
|
1694
|
+
}
|
|
1695
|
+
addObject(object) {
|
|
1696
|
+
if (object.type() === "Image") this._groupImages.add(object.ref()); else if (object.type() === "Text") this._groupTexts.add(object.ref()); else this._groupGeometry.add(object.ref());
|
|
1697
|
+
}
|
|
1698
|
+
konvaLayerFind(type) {
|
|
1699
|
+
if (!this._konvaLayer) return [];
|
|
1700
|
+
const konvaShape = MarkupMode2Konva[type];
|
|
1701
|
+
if (!konvaShape || !konvaShape.initializer) return [];
|
|
1702
|
+
return this._konvaLayer.find(konvaShape.name).filter((ref => ref.parent === this._konvaLayer || ref.parent === this._groupImages || ref.parent === this._groupGeometry || ref.parent === this._groupTexts));
|
|
1703
|
+
}
|
|
1704
|
+
initializeKonva() {
|
|
1705
|
+
const stage = new Konva.Stage({
|
|
1706
|
+
container: this._markupContainer,
|
|
1707
|
+
width: this._container.clientWidth,
|
|
1708
|
+
height: this._container.clientHeight
|
|
1709
|
+
});
|
|
1710
|
+
this._konvaStage = stage;
|
|
1711
|
+
const layer = new Konva.Layer({
|
|
1712
|
+
pixelRation: window.devicePixelRatio
|
|
1713
|
+
});
|
|
1714
|
+
stage.add(layer);
|
|
1715
|
+
this._groupImages = new Konva.Group;
|
|
1716
|
+
layer.add(this._groupImages);
|
|
1717
|
+
this._groupGeometry = new Konva.Group;
|
|
1718
|
+
layer.add(this._groupGeometry);
|
|
1719
|
+
this._groupTexts = new Konva.Group;
|
|
1720
|
+
layer.add(this._groupTexts);
|
|
1721
|
+
this._konvaLayer = layer;
|
|
1722
|
+
const transformer = new Konva.Transformer({
|
|
1723
|
+
shouldOverdrawWholeArea: false,
|
|
1724
|
+
keepRatio: false,
|
|
1725
|
+
flipEnabled: false
|
|
1726
|
+
});
|
|
1727
|
+
layer.add(transformer);
|
|
1728
|
+
this._konvaTransformer = transformer;
|
|
1729
|
+
let isPaint = false;
|
|
1730
|
+
let lastLine;
|
|
1731
|
+
let mouseDownPos;
|
|
1732
|
+
let lastObj;
|
|
1733
|
+
stage.on("mousedown touchstart", (e => {
|
|
1734
|
+
if (!this._markupIsActive || e.target !== stage || this._markupMode === "Text" || this._markupMode === "Image") return;
|
|
1735
|
+
if (e.target === stage && transformer.nodes().length > 0) {
|
|
1736
|
+
transformer.nodes([]);
|
|
1737
|
+
return;
|
|
1738
|
+
}
|
|
1739
|
+
const pos = this.getRelativePointerPosition(stage);
|
|
1740
|
+
mouseDownPos = pos;
|
|
1741
|
+
isPaint = [ "Arrow", "Cloud", "Ellipse", "Line", "Rectangle" ].some((m => m === this._markupMode));
|
|
1742
|
+
if (this._markupMode === "Line") {
|
|
1743
|
+
lastLine = this.addLine([ pos.x, pos.y, pos.x, pos.y ]);
|
|
1744
|
+
}
|
|
1745
|
+
}));
|
|
1746
|
+
stage.on("mouseup touchend", (e => {
|
|
1747
|
+
if (!this._markupIsActive) return;
|
|
1748
|
+
if (isPaint) {
|
|
1749
|
+
const pos = this.getRelativePointerPosition(stage);
|
|
1750
|
+
const defParams = mouseDownPos && pos.x === mouseDownPos.x && pos.y === mouseDownPos.y;
|
|
1751
|
+
const startX = defParams ? mouseDownPos.x : Math.min(mouseDownPos.x, pos.x);
|
|
1752
|
+
const startY = defParams ? mouseDownPos.y : Math.min(mouseDownPos.y, pos.y);
|
|
1753
|
+
const dX = defParams ? 200 : Math.abs(mouseDownPos.x - pos.x);
|
|
1754
|
+
const dY = defParams ? 200 : Math.abs(mouseDownPos.y - pos.y);
|
|
1755
|
+
if (defParams) {
|
|
1756
|
+
if (this._markupMode === "Rectangle") {
|
|
1757
|
+
this.addRectangle({
|
|
1758
|
+
x: startX,
|
|
1759
|
+
y: startY
|
|
1760
|
+
}, dX, dY);
|
|
1761
|
+
} else if (this._markupMode === "Ellipse") {
|
|
1762
|
+
this.addEllipse({
|
|
1763
|
+
x: startX,
|
|
1764
|
+
y: startY
|
|
1765
|
+
}, {
|
|
1766
|
+
x: dX / 2,
|
|
1767
|
+
y: dY / 2
|
|
1768
|
+
});
|
|
1769
|
+
} else if (this._markupMode === "Arrow") {
|
|
1770
|
+
this.addArrow({
|
|
1771
|
+
x: mouseDownPos.x,
|
|
1772
|
+
y: mouseDownPos.y
|
|
1773
|
+
}, {
|
|
1774
|
+
x: defParams ? mouseDownPos.x + 200 : pos.x,
|
|
1775
|
+
y: defParams ? startY : pos.y
|
|
1776
|
+
});
|
|
1777
|
+
} else if (this._markupMode === "Cloud") {
|
|
1778
|
+
this.addCloud({
|
|
1779
|
+
x: startX,
|
|
1780
|
+
y: startY
|
|
1781
|
+
}, Math.max(100, dX), Math.max(100, dY));
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
lastObj = undefined;
|
|
1786
|
+
isPaint = false;
|
|
1787
|
+
}));
|
|
1788
|
+
stage.on("mousemove touchmove", (e => {
|
|
1789
|
+
if (!this._markupIsActive) return;
|
|
1790
|
+
if (!isPaint) {
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1793
|
+
const pos = this.getRelativePointerPosition(stage);
|
|
1794
|
+
const defParams = mouseDownPos && pos.x === mouseDownPos.x && pos.y === mouseDownPos.y;
|
|
1795
|
+
const startX = defParams ? mouseDownPos.x : Math.min(mouseDownPos.x, pos.x);
|
|
1796
|
+
const startY = defParams ? mouseDownPos.y : Math.min(mouseDownPos.y, pos.y);
|
|
1797
|
+
const dX = defParams ? 200 : Math.abs(mouseDownPos.x - pos.x);
|
|
1798
|
+
const dY = defParams ? 200 : Math.abs(mouseDownPos.y - pos.y);
|
|
1799
|
+
if (this._markupMode === "Line") {
|
|
1800
|
+
lastLine.addPoints([ {
|
|
1801
|
+
x: pos.x,
|
|
1802
|
+
y: pos.y
|
|
1803
|
+
} ]);
|
|
1804
|
+
} else if (this._markupMode === "Arrow") {
|
|
1805
|
+
if (lastObj) lastObj.setEndPoint(pos.x, pos.y); else lastObj = this.addArrow({
|
|
1806
|
+
x: mouseDownPos.x,
|
|
1807
|
+
y: mouseDownPos.y
|
|
1808
|
+
}, {
|
|
1809
|
+
x: pos.x,
|
|
1810
|
+
y: pos.y
|
|
1811
|
+
});
|
|
1812
|
+
} else if (this._markupMode === "Rectangle") {
|
|
1813
|
+
if (lastObj) {
|
|
1814
|
+
lastObj.setPosition(startX, startY);
|
|
1815
|
+
lastObj.setWidth(dX);
|
|
1816
|
+
lastObj.setHeight(dY);
|
|
1817
|
+
} else lastObj = this.addRectangle({
|
|
1818
|
+
x: startX,
|
|
1819
|
+
y: startY
|
|
1820
|
+
}, dX, dY);
|
|
1821
|
+
} else if (this._markupMode === "Ellipse") {
|
|
1822
|
+
if (lastObj) {
|
|
1823
|
+
lastObj.setPosition(startX, startY);
|
|
1824
|
+
lastObj.setRadiusX(dX);
|
|
1825
|
+
lastObj.setRadiusY(dY);
|
|
1826
|
+
} else lastObj = this.addEllipse({
|
|
1827
|
+
x: startX,
|
|
1828
|
+
y: startY
|
|
1829
|
+
}, {
|
|
1830
|
+
x: dX,
|
|
1831
|
+
y: dY
|
|
1832
|
+
});
|
|
1833
|
+
} else if (this._markupMode === "Cloud") {
|
|
1834
|
+
if (lastObj) {
|
|
1835
|
+
lastObj.setPosition(startX, startY);
|
|
1836
|
+
lastObj.setWidth(Math.max(100, dX));
|
|
1837
|
+
lastObj.setHeight(Math.max(100, dY));
|
|
1838
|
+
} else lastObj = this.addCloud({
|
|
1839
|
+
x: startX,
|
|
1840
|
+
y: startY
|
|
1841
|
+
}, dX, dY);
|
|
1842
|
+
}
|
|
1843
|
+
}));
|
|
1844
|
+
stage.on("click tap", (e => {
|
|
1845
|
+
if (!this._markupIsActive) return;
|
|
1846
|
+
if (e.target === stage) {
|
|
1847
|
+
if (this._markupMode === "Text") {
|
|
1848
|
+
if (this._textInputRef && this._textInputRef.value) this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle); else if (transformer.nodes().length === 0) {
|
|
1849
|
+
const pos = this.getRelativePointerPosition(stage);
|
|
1850
|
+
this.createTextInput(pos, e.evt.pageX, e.evt.pageY, 0, null);
|
|
1851
|
+
}
|
|
1852
|
+
} else if (this._markupMode === "Image") {
|
|
1853
|
+
if (this._imageInputRef && this._imageInputRef.value) this.addImage({
|
|
1854
|
+
x: this._imageInputPos.x,
|
|
1855
|
+
y: this._imageInputPos.y
|
|
1856
|
+
}, this._imageInputRef.value, 0, 0, this._imageInputRef.value); else if (transformer.nodes().length === 0) {
|
|
1857
|
+
const pos = this.getRelativePointerPosition(stage);
|
|
1858
|
+
this.createImageInput(pos);
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
transformer.nodes([]);
|
|
1862
|
+
return;
|
|
1863
|
+
}
|
|
1864
|
+
if (this._markupMode === "Text" || this._markupMode === "SelectMarkup") {
|
|
1865
|
+
if (e.target.className === "Text" && transformer.nodes().length === 1 && transformer.nodes()[0] === e.target) {
|
|
1866
|
+
if (this._textInputRef && this._textInputRef.value) this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle); else this.createTextInput({
|
|
1867
|
+
x: e.target.attrs.x,
|
|
1868
|
+
y: e.target.attrs.y
|
|
1869
|
+
}, e.evt.pageX, e.evt.pageY, e.target.attrs.rotation, e.target.attrs.text);
|
|
1870
|
+
return;
|
|
1871
|
+
} else {
|
|
1872
|
+
this.removeTextInput();
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
if (this._markupMode === "Image" || this._markupMode === "SelectMarkup") {
|
|
1876
|
+
if (e.target.className === "Image" && transformer.nodes().length === 1 && transformer.nodes()[0] === e.target) {
|
|
1877
|
+
if (this._imageInputRef && this._imageInputRef.value) this.addImage(this._imageInputPos, this._imageInputRef.value, 0, 0); else this.createImageInput({
|
|
1878
|
+
x: e.target.attrs.x,
|
|
1879
|
+
y: e.target.attrs.y
|
|
1880
|
+
});
|
|
1881
|
+
return;
|
|
1882
|
+
} else {
|
|
1883
|
+
this.removeImageInput();
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
if (transformer.nodes().filter((x => x.className === "Cloud" || x.className === "Image")).length > 0 || e.target.className === "Cloud" || e.target.className === "Image") {
|
|
1887
|
+
transformer.rotateEnabled(false);
|
|
1888
|
+
} else {
|
|
1889
|
+
transformer.rotateEnabled(true);
|
|
1890
|
+
}
|
|
1891
|
+
const metaPressed = e.evt.shiftKey || e.evt.ctrlKey || e.evt.metaKey;
|
|
1892
|
+
const isSelected = transformer.nodes().indexOf(e.target) >= 0;
|
|
1893
|
+
if (!metaPressed && !isSelected) {
|
|
1894
|
+
transformer.nodes([ e.target ]);
|
|
1895
|
+
} else if (metaPressed && isSelected) {
|
|
1896
|
+
const nodes = transformer.nodes().slice();
|
|
1897
|
+
nodes.splice(nodes.indexOf(e.target), 1);
|
|
1898
|
+
transformer.nodes(nodes);
|
|
1899
|
+
} else if (metaPressed && !isSelected) {
|
|
1900
|
+
const nodes = transformer.nodes().concat([ e.target ]);
|
|
1901
|
+
transformer.nodes(nodes);
|
|
1902
|
+
}
|
|
1903
|
+
}));
|
|
1904
|
+
const container = stage.container();
|
|
1905
|
+
container.tabIndex = 1;
|
|
1906
|
+
container.focus();
|
|
1907
|
+
container.addEventListener("keydown", (e => {
|
|
1908
|
+
if (!this._markupIsActive) return;
|
|
1909
|
+
if (e.code === "Delete") {
|
|
1910
|
+
this.getSelectedObjects().forEach((obj => obj.delete()));
|
|
1911
|
+
this.clearSelected();
|
|
1912
|
+
return;
|
|
1913
|
+
}
|
|
1914
|
+
e.preventDefault();
|
|
1915
|
+
}));
|
|
1916
|
+
}
|
|
1917
|
+
destroyKonva() {
|
|
1918
|
+
var _a;
|
|
1919
|
+
this.removeTextInput();
|
|
1920
|
+
this.removeImageInput();
|
|
1921
|
+
this.clearOverlay();
|
|
1922
|
+
(_a = this._konvaStage) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
1923
|
+
this._groupImages = undefined;
|
|
1924
|
+
this._groupGeometry = undefined;
|
|
1925
|
+
this._groupTexts = undefined;
|
|
1926
|
+
this._konvaLayer = undefined;
|
|
1927
|
+
this._konvaTransformer = undefined;
|
|
1928
|
+
this._konvaStage = undefined;
|
|
1929
|
+
}
|
|
1930
|
+
getMarkupLines() {
|
|
1931
|
+
const lines = [];
|
|
1932
|
+
this.konvaLayerFind("Line").forEach((ref => {
|
|
1933
|
+
const linePoints = ref.points();
|
|
1934
|
+
if (!linePoints) return;
|
|
1935
|
+
const worldPoints = [];
|
|
1936
|
+
const absoluteTransform = ref.getAbsoluteTransform();
|
|
1937
|
+
for (let i = 0; i < linePoints.length; i += 2) {
|
|
1938
|
+
const atPoint = absoluteTransform.point({
|
|
1939
|
+
x: linePoints[i],
|
|
1940
|
+
y: linePoints[i + 1]
|
|
1941
|
+
});
|
|
1942
|
+
const worldPoint = this._worldTransformer.screenToWorld(atPoint);
|
|
1943
|
+
worldPoints.push(worldPoint);
|
|
1944
|
+
}
|
|
1945
|
+
const konvaLine = new KonvaLine(null, ref);
|
|
1946
|
+
const line = {
|
|
1947
|
+
id: konvaLine.id(),
|
|
1948
|
+
points: worldPoints,
|
|
1949
|
+
color: konvaLine.getColor() || "#ff0000",
|
|
1950
|
+
type: konvaLine.getLineType() || this.lineType,
|
|
1951
|
+
width: konvaLine.getLineWidth() || this.lineWidth
|
|
1952
|
+
};
|
|
1953
|
+
lines.push(line);
|
|
1954
|
+
}));
|
|
1955
|
+
return lines;
|
|
1956
|
+
}
|
|
1957
|
+
getMarkupTexts() {
|
|
1958
|
+
const texts = [];
|
|
1959
|
+
this.konvaLayerFind("Text").forEach((ref => {
|
|
1960
|
+
const textSize = .02;
|
|
1961
|
+
const textScale = this._worldTransformer.getScale();
|
|
1962
|
+
const position = ref.position();
|
|
1963
|
+
const stageAbsoluteTransform = this._konvaStage.getAbsoluteTransform();
|
|
1964
|
+
const atPoint = stageAbsoluteTransform.point({
|
|
1965
|
+
x: position.x,
|
|
1966
|
+
y: position.y
|
|
1967
|
+
});
|
|
1968
|
+
const worldPoint = this._worldTransformer.screenToWorld(atPoint);
|
|
1969
|
+
const shape = new KonvaText(null, ref);
|
|
1970
|
+
const text = {
|
|
1971
|
+
id: shape.id(),
|
|
1972
|
+
position: worldPoint,
|
|
1973
|
+
text: shape.getText(),
|
|
1974
|
+
text_size: textSize * textScale.y,
|
|
1975
|
+
angle: shape.getRotation(),
|
|
1976
|
+
color: shape.getColor(),
|
|
1977
|
+
font_size: shape.getFontSize() * stageAbsoluteTransform.getMatrix()[0]
|
|
1978
|
+
};
|
|
1979
|
+
texts.push(text);
|
|
1980
|
+
}));
|
|
1981
|
+
return texts;
|
|
1982
|
+
}
|
|
1983
|
+
getMarkupRectangles() {
|
|
1984
|
+
const rectangles = [];
|
|
1985
|
+
this.konvaLayerFind("Rectangle").forEach((ref => {
|
|
1986
|
+
const position = ref.position();
|
|
1987
|
+
const stageAbsoluteTransform = this._konvaStage.getAbsoluteTransform();
|
|
1988
|
+
const atPoint = stageAbsoluteTransform.point({
|
|
1989
|
+
x: position.x,
|
|
1990
|
+
y: position.y
|
|
1991
|
+
});
|
|
1992
|
+
const worldPoint = this._worldTransformer.screenToWorld(atPoint);
|
|
1993
|
+
const scale = stageAbsoluteTransform.getMatrix()[0];
|
|
1994
|
+
const shape = new KonvaRectangle(null, ref);
|
|
1995
|
+
const rectangle = {
|
|
1996
|
+
id: shape.id(),
|
|
1997
|
+
position: worldPoint,
|
|
1998
|
+
width: shape.getWidth() * scale,
|
|
1999
|
+
height: shape.getHeigth() * scale,
|
|
2000
|
+
line_width: shape.getLineWidth(),
|
|
2001
|
+
color: shape.getColor()
|
|
2002
|
+
};
|
|
2003
|
+
rectangles.push(rectangle);
|
|
2004
|
+
}));
|
|
2005
|
+
return rectangles;
|
|
2006
|
+
}
|
|
2007
|
+
getMarkupEllipses() {
|
|
2008
|
+
const ellipses = [];
|
|
2009
|
+
this.konvaLayerFind("Ellipse").forEach((ref => {
|
|
2010
|
+
const position = ref.position();
|
|
2011
|
+
const stageAbsoluteTransform = this._konvaStage.getAbsoluteTransform();
|
|
2012
|
+
const atPoint = stageAbsoluteTransform.point({
|
|
2013
|
+
x: position.x,
|
|
2014
|
+
y: position.y
|
|
2015
|
+
});
|
|
2016
|
+
const worldPoint = this._worldTransformer.screenToWorld(atPoint);
|
|
2017
|
+
const scale = stageAbsoluteTransform.getMatrix()[0];
|
|
2018
|
+
const shape = new KonvaEllipse(null, ref);
|
|
2019
|
+
const ellipse = {
|
|
2020
|
+
id: shape.id(),
|
|
2021
|
+
position: worldPoint,
|
|
2022
|
+
radius: {
|
|
2023
|
+
x: ref.getRadiusX() * scale,
|
|
2024
|
+
y: ref.getRadiusY() * scale
|
|
2025
|
+
},
|
|
2026
|
+
line_width: shape.getLineWidth(),
|
|
2027
|
+
color: shape.getColor()
|
|
2028
|
+
};
|
|
2029
|
+
ellipses.push(ellipse);
|
|
2030
|
+
}));
|
|
2031
|
+
return ellipses;
|
|
2032
|
+
}
|
|
2033
|
+
getMarkupArrows() {
|
|
2034
|
+
const arrows = [];
|
|
2035
|
+
this.konvaLayerFind("Arrow").forEach((ref => {
|
|
2036
|
+
const absoluteTransform = ref.getAbsoluteTransform();
|
|
2037
|
+
const atStartPoint = absoluteTransform.point({
|
|
2038
|
+
x: ref.points()[0],
|
|
2039
|
+
y: ref.points()[1]
|
|
2040
|
+
});
|
|
2041
|
+
const worldStartPoint = this._worldTransformer.screenToWorld(atStartPoint);
|
|
2042
|
+
const atEndPoint = absoluteTransform.point({
|
|
2043
|
+
x: ref.points()[2],
|
|
2044
|
+
y: ref.points()[3]
|
|
2045
|
+
});
|
|
2046
|
+
const worldEndPoint = this._worldTransformer.screenToWorld(atEndPoint);
|
|
2047
|
+
const shape = new KonvaArrow(null, ref);
|
|
2048
|
+
const arrow = {
|
|
2049
|
+
id: shape.id(),
|
|
2050
|
+
start: worldStartPoint,
|
|
2051
|
+
end: worldEndPoint,
|
|
2052
|
+
color: shape.getColor()
|
|
2053
|
+
};
|
|
2054
|
+
arrows.push(arrow);
|
|
2055
|
+
}));
|
|
2056
|
+
return arrows;
|
|
2057
|
+
}
|
|
2058
|
+
getMarkupImages() {
|
|
2059
|
+
const images = [];
|
|
2060
|
+
this.konvaLayerFind("Image").forEach((ref => {
|
|
2061
|
+
const position = ref.position();
|
|
2062
|
+
const stageAbsoluteTransform = this._konvaStage.getAbsoluteTransform();
|
|
2063
|
+
const atPoint = stageAbsoluteTransform.point({
|
|
2064
|
+
x: position.x,
|
|
2065
|
+
y: position.y
|
|
2066
|
+
});
|
|
2067
|
+
const worldPoint = this._worldTransformer.screenToWorld(atPoint);
|
|
2068
|
+
const scale = stageAbsoluteTransform.getMatrix()[0];
|
|
2069
|
+
const shape = new KonvaImage(null, ref);
|
|
2070
|
+
const image = {
|
|
2071
|
+
id: shape.id(),
|
|
2072
|
+
position: worldPoint,
|
|
2073
|
+
src: shape.getSrc(),
|
|
2074
|
+
width: shape.getWidth() * scale,
|
|
2075
|
+
height: shape.getHeight() * scale
|
|
2076
|
+
};
|
|
2077
|
+
images.push(image);
|
|
2078
|
+
}));
|
|
2079
|
+
return images;
|
|
2080
|
+
}
|
|
2081
|
+
getMarkupClouds() {
|
|
2082
|
+
const clouds = [];
|
|
2083
|
+
this.konvaLayerFind("Cloud").forEach((ref => {
|
|
2084
|
+
const position = ref.position();
|
|
2085
|
+
const stageAbsoluteTransform = this._konvaStage.getAbsoluteTransform();
|
|
2086
|
+
const atPoint = stageAbsoluteTransform.point({
|
|
2087
|
+
x: position.x,
|
|
2088
|
+
y: position.y
|
|
2089
|
+
});
|
|
2090
|
+
const worldPoint = this._worldTransformer.screenToWorld(atPoint);
|
|
2091
|
+
const scale = stageAbsoluteTransform.getMatrix()[0];
|
|
2092
|
+
const shape = new KonvaCloud(null, ref);
|
|
2093
|
+
const cloud = {
|
|
2094
|
+
id: shape.id(),
|
|
2095
|
+
position: worldPoint,
|
|
2096
|
+
width: shape.getWidth() * scale,
|
|
2097
|
+
height: shape.getHeigth() * scale,
|
|
2098
|
+
line_width: shape.getLineWidth(),
|
|
2099
|
+
color: shape.getColor()
|
|
2100
|
+
};
|
|
2101
|
+
clouds.push(cloud);
|
|
2102
|
+
}));
|
|
2103
|
+
return clouds;
|
|
2104
|
+
}
|
|
2105
|
+
combineMarkupWithDrawing() {
|
|
2106
|
+
this.clearSelected();
|
|
2107
|
+
const tempCanvas = document.createElement("canvas");
|
|
2108
|
+
if (this._konvaStage) {
|
|
2109
|
+
tempCanvas.width = this._konvaStage.width();
|
|
2110
|
+
tempCanvas.height = this._konvaStage.height();
|
|
2111
|
+
const ctx = tempCanvas.getContext("2d");
|
|
2112
|
+
if (this._container instanceof HTMLCanvasElement) ctx.drawImage(this._container, 0, 0);
|
|
2113
|
+
ctx.drawImage(this._konvaStage.toCanvas({
|
|
2114
|
+
pixelRatio: window.devicePixelRatio
|
|
2115
|
+
}), 0, 0);
|
|
2116
|
+
}
|
|
2117
|
+
return tempCanvas.toDataURL("image/jpeg", .25);
|
|
2118
|
+
}
|
|
2119
|
+
addLine(linePoints, color, type, width, id) {
|
|
2120
|
+
if (!linePoints || linePoints.length === 0) return;
|
|
2121
|
+
const points = [];
|
|
2122
|
+
for (let i = 0; i < linePoints.length; i += 2) {
|
|
2123
|
+
points.push({
|
|
2124
|
+
x: linePoints[i],
|
|
2125
|
+
y: linePoints[i + 1]
|
|
2126
|
+
});
|
|
2127
|
+
}
|
|
2128
|
+
const konvaLine = new KonvaLine({
|
|
2129
|
+
points: points,
|
|
2130
|
+
type: type || this.lineType,
|
|
2131
|
+
width: width || this.lineWidth,
|
|
2132
|
+
color: color || this._markupColor.asHex(),
|
|
2133
|
+
id: id
|
|
2134
|
+
});
|
|
2135
|
+
this.addObject(konvaLine);
|
|
2136
|
+
return konvaLine;
|
|
2137
|
+
}
|
|
2138
|
+
createTextInput(pos, inputX, inputY, angle, text) {
|
|
2139
|
+
if (!this._textInputRef) {
|
|
2140
|
+
this._textInputPos = pos;
|
|
2141
|
+
this._textInputAngle = angle;
|
|
2142
|
+
this._textInputRef = document.createElement("textarea");
|
|
2143
|
+
this._textInputRef.style.zIndex = "9999";
|
|
2144
|
+
this._textInputRef.style.position = "absolute";
|
|
2145
|
+
this._textInputRef.style.display = "block";
|
|
2146
|
+
this._textInputRef.style.top = inputY + "px";
|
|
2147
|
+
this._textInputRef.style.left = inputX + "px";
|
|
2148
|
+
this._textInputRef.style.fontSize = `${this.fontSize}px`;
|
|
2149
|
+
this._textInputRef.style.color = `${this._markupColor.asHex()}`;
|
|
2150
|
+
this._textInputRef.style.fontFamily = "Calibri";
|
|
2151
|
+
this._textInputRef.onkeydown = event => {
|
|
2152
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
2153
|
+
event.preventDefault();
|
|
2154
|
+
this.addText(this._textInputRef.value, this._textInputPos, this._textInputAngle);
|
|
2155
|
+
}
|
|
2156
|
+
if (event.key === "Escape") {
|
|
2157
|
+
event.preventDefault();
|
|
2158
|
+
this.removeTextInput();
|
|
2159
|
+
}
|
|
2160
|
+
};
|
|
2161
|
+
if (text) this._textInputRef.value = text;
|
|
2162
|
+
document.body.appendChild(this._textInputRef);
|
|
2163
|
+
setTimeout((() => {
|
|
2164
|
+
this._textInputRef.focus();
|
|
2165
|
+
}), 50);
|
|
2166
|
+
} else {
|
|
2167
|
+
this.removeTextInput();
|
|
2168
|
+
}
|
|
2169
|
+
}
|
|
2170
|
+
removeTextInput() {
|
|
2171
|
+
var _a;
|
|
2172
|
+
(_a = this._textInputRef) === null || _a === void 0 ? void 0 : _a.remove();
|
|
2173
|
+
this._textInputRef = null;
|
|
2174
|
+
this._textInputPos = null;
|
|
2175
|
+
this._textInputAngle = 0;
|
|
2176
|
+
}
|
|
2177
|
+
createImageInput(pos) {
|
|
2178
|
+
if (!this._imageInputRef) {
|
|
2179
|
+
const convertBase64 = file => new Promise(((resolve, reject) => {
|
|
2180
|
+
const fileReader = new FileReader;
|
|
2181
|
+
fileReader.readAsDataURL(file);
|
|
2182
|
+
fileReader.onload = () => {
|
|
2183
|
+
resolve(fileReader.result);
|
|
2184
|
+
};
|
|
2185
|
+
fileReader.onerror = error => {
|
|
2186
|
+
reject(error);
|
|
2187
|
+
};
|
|
2188
|
+
}));
|
|
2189
|
+
this._imageInputPos = pos;
|
|
2190
|
+
this._imageInputRef = document.createElement("input");
|
|
2191
|
+
this._imageInputRef.style.display = "none";
|
|
2192
|
+
this._imageInputRef.type = "file";
|
|
2193
|
+
this._imageInputRef.accept = "image/png, image/jpeg";
|
|
2194
|
+
this._imageInputRef.onchange = async event => {
|
|
2195
|
+
const file = event.target.files[0];
|
|
2196
|
+
const base64 = await convertBase64(file);
|
|
2197
|
+
this.addImage({
|
|
2198
|
+
x: this._imageInputPos.x,
|
|
2199
|
+
y: this._imageInputPos.y
|
|
2200
|
+
}, base64.toString(), 0, 0);
|
|
2201
|
+
};
|
|
2202
|
+
this._imageInputRef.oncancel = event => {
|
|
2203
|
+
this.removeImageInput();
|
|
2204
|
+
};
|
|
2205
|
+
document.body.appendChild(this._imageInputRef);
|
|
2206
|
+
setTimeout((() => {
|
|
2207
|
+
this._imageInputRef.click();
|
|
2208
|
+
}), 50);
|
|
2209
|
+
} else {
|
|
2210
|
+
this.removeImageInput();
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
removeImageInput() {
|
|
2214
|
+
var _a;
|
|
2215
|
+
(_a = this._imageInputRef) === null || _a === void 0 ? void 0 : _a.remove();
|
|
2216
|
+
this._imageInputRef = null;
|
|
2217
|
+
this._imageInputPos = null;
|
|
2218
|
+
}
|
|
2219
|
+
addText(text, position, angle, color, textSize, fontSize, id) {
|
|
2220
|
+
var _a;
|
|
2221
|
+
if (!text) return;
|
|
2222
|
+
(_a = this.getSelectedObjects().at(0)) === null || _a === void 0 ? void 0 : _a.delete();
|
|
2223
|
+
this.clearSelected();
|
|
2224
|
+
this.removeTextInput();
|
|
2225
|
+
const tolerance = 1e-6;
|
|
2226
|
+
if (textSize && textSize > tolerance && (!fontSize || fontSize < tolerance)) {
|
|
2227
|
+
const size = .02;
|
|
2228
|
+
const scale = this._worldTransformer.getScale();
|
|
2229
|
+
fontSize = textSize / (scale.y / size) / 34;
|
|
2230
|
+
}
|
|
2231
|
+
const konvaText = new KonvaText({
|
|
2232
|
+
position: {
|
|
2233
|
+
x: position.x,
|
|
2234
|
+
y: position.y
|
|
2235
|
+
},
|
|
2236
|
+
text: text,
|
|
2237
|
+
rotation: angle,
|
|
2238
|
+
fontSize: fontSize || this.fontSize,
|
|
2239
|
+
color: color || this._markupColor.asHex(),
|
|
2240
|
+
id: id
|
|
2241
|
+
});
|
|
2242
|
+
this.addObject(konvaText);
|
|
2243
|
+
return konvaText;
|
|
2244
|
+
}
|
|
2245
|
+
addRectangle(position, width, height, lineWidth, color, id) {
|
|
2246
|
+
if (!position) return;
|
|
2247
|
+
const konvaRectangle = new KonvaRectangle({
|
|
2248
|
+
position: position,
|
|
2249
|
+
width: width,
|
|
2250
|
+
height: height,
|
|
2251
|
+
lineWidth: lineWidth || this.lineWidth,
|
|
2252
|
+
color: color || this._markupColor.asHex(),
|
|
2253
|
+
id: id
|
|
2254
|
+
});
|
|
2255
|
+
this.addObject(konvaRectangle);
|
|
2256
|
+
return konvaRectangle;
|
|
2257
|
+
}
|
|
2258
|
+
addEllipse(position, radius, lineWidth, color, id) {
|
|
2259
|
+
if (!position) return;
|
|
2260
|
+
const konvaEllipse = new KonvaEllipse({
|
|
2261
|
+
position: position,
|
|
2262
|
+
radius: radius,
|
|
2263
|
+
lineWidth: lineWidth,
|
|
2264
|
+
color: color || this._markupColor.asHex(),
|
|
2265
|
+
id: id
|
|
2266
|
+
});
|
|
2267
|
+
this.addObject(konvaEllipse);
|
|
2268
|
+
return konvaEllipse;
|
|
2269
|
+
}
|
|
2270
|
+
addArrow(start, end, color, id) {
|
|
2271
|
+
if (!start || !end) return;
|
|
2272
|
+
const konvaArrow = new KonvaArrow({
|
|
2273
|
+
start: start,
|
|
2274
|
+
end: end,
|
|
2275
|
+
color: color || this._markupColor.asHex(),
|
|
2276
|
+
id: id
|
|
2277
|
+
});
|
|
2278
|
+
this.addObject(konvaArrow);
|
|
2279
|
+
return konvaArrow;
|
|
2280
|
+
}
|
|
2281
|
+
addCloud(position, width, height, lineWidth, color, id) {
|
|
2282
|
+
if (!position || !width || !height) return;
|
|
2283
|
+
const konvaCloud = new KonvaCloud({
|
|
2284
|
+
position: position,
|
|
2285
|
+
width: width,
|
|
2286
|
+
height: height,
|
|
2287
|
+
color: color || this._markupColor.asHex(),
|
|
2288
|
+
lineWidth: lineWidth || this.lineWidth,
|
|
2289
|
+
id: id
|
|
2290
|
+
});
|
|
2291
|
+
this.addObject(konvaCloud);
|
|
2292
|
+
return konvaCloud;
|
|
2293
|
+
}
|
|
2294
|
+
addImage(position, src, width, height, id) {
|
|
2295
|
+
var _a;
|
|
2296
|
+
if (!position || !src) return;
|
|
2297
|
+
(_a = this.getSelectedObjects().at(0)) === null || _a === void 0 ? void 0 : _a.delete();
|
|
2298
|
+
this.clearSelected();
|
|
2299
|
+
this.removeImageInput();
|
|
2300
|
+
const konvaImage = new KonvaImage({
|
|
2301
|
+
position: position,
|
|
2302
|
+
src: src,
|
|
2303
|
+
width: width,
|
|
2304
|
+
height: height,
|
|
2305
|
+
maxWidth: this._konvaStage.width() - position.x,
|
|
2306
|
+
maxHeight: this._konvaStage.height() - position.y,
|
|
2307
|
+
id: id
|
|
2308
|
+
});
|
|
2309
|
+
this.addObject(konvaImage);
|
|
2310
|
+
return konvaImage;
|
|
2311
|
+
}
|
|
2312
|
+
}
|
|
18
2313
|
|
|
19
2314
|
class PlaneHelper extends Line {
|
|
20
2315
|
constructor(plane, size = 1, color = 16776960, offset = new Vector3) {
|
|
@@ -754,7 +3049,6 @@ class OrbitDragger {
|
|
|
754
3049
|
this.updateControls = () => {
|
|
755
3050
|
this.orbit.maxDistance = this.viewer.camera.far;
|
|
756
3051
|
this.orbit.minDistance = this.viewer.camera.near;
|
|
757
|
-
this.orbit.object = this.viewer.camera;
|
|
758
3052
|
this.orbit.target.copy(this.viewer.target);
|
|
759
3053
|
this.orbit.update();
|
|
760
3054
|
};
|
|
@@ -809,20 +3103,19 @@ class OrbitDragger {
|
|
|
809
3103
|
this.orbit.addEventListener("change", this.controlsChange);
|
|
810
3104
|
this.changed = false;
|
|
811
3105
|
this.viewer = viewer;
|
|
812
|
-
this.viewer.
|
|
3106
|
+
this.viewer.on("geometryend", this.updateControls);
|
|
813
3107
|
this.viewer.on("viewposition", this.updateControls);
|
|
814
|
-
this.viewer.
|
|
815
|
-
this.viewer.
|
|
816
|
-
this.viewer.
|
|
3108
|
+
this.viewer.on("zoom", this.updateControls);
|
|
3109
|
+
this.viewer.on("drawviewpoint", this.updateControls);
|
|
3110
|
+
this.viewer.on("contextmenu", this.stopContextMenu);
|
|
817
3111
|
this.updateControls();
|
|
818
3112
|
}
|
|
819
|
-
initialize() {}
|
|
820
3113
|
dispose() {
|
|
821
|
-
this.viewer.
|
|
3114
|
+
this.viewer.off("geometryend", this.updateControls);
|
|
822
3115
|
this.viewer.off("viewposition", this.updateControls);
|
|
823
|
-
this.viewer.
|
|
824
|
-
this.viewer.
|
|
825
|
-
this.viewer.
|
|
3116
|
+
this.viewer.off("zoom", this.updateControls);
|
|
3117
|
+
this.viewer.off("drawviewpoint", this.updateControls);
|
|
3118
|
+
this.viewer.off("contextmenu", this.stopContextMenu);
|
|
826
3119
|
this.orbit.removeEventListener("start", this.controlsStart);
|
|
827
3120
|
this.orbit.removeEventListener("change", this.controlsChange);
|
|
828
3121
|
this.orbit.dispose();
|
|
@@ -1600,43 +3893,45 @@ function createPreview(viewer, type = "image/jpeg", encoderOptions = .25) {
|
|
|
1600
3893
|
return viewer.canvas.toDataURL(type, encoderOptions);
|
|
1601
3894
|
}
|
|
1602
3895
|
|
|
1603
|
-
function
|
|
3896
|
+
function calcObjectDepth(object, depth) {
|
|
1604
3897
|
let res = depth;
|
|
1605
3898
|
object.children.forEach((x => {
|
|
1606
|
-
const objectDepth =
|
|
3899
|
+
const objectDepth = calcObjectDepth(x, depth + 1);
|
|
1607
3900
|
if (res < objectDepth) res = objectDepth;
|
|
1608
3901
|
}));
|
|
1609
3902
|
object.originalPosition = object.position.clone();
|
|
1610
|
-
object.originalCenter = (new Box3).setFromObject(object).getCenter(new Vector3);
|
|
1611
|
-
object.isExplodeLocked = depth > 2 && object.children.length === 0;
|
|
1612
3903
|
return res;
|
|
1613
3904
|
}
|
|
1614
3905
|
|
|
1615
|
-
function explodeScene(scene, scale = 0
|
|
3906
|
+
function explodeScene(scene, scale = 0) {
|
|
1616
3907
|
scale /= 100;
|
|
1617
|
-
if (!scene.
|
|
1618
|
-
const maxDepth = scene.
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
3908
|
+
if (!scene.maxDepth) scene.maxDepth = calcObjectDepth(scene, 1);
|
|
3909
|
+
const maxDepth = scene.maxDepth;
|
|
3910
|
+
let explodeDepth = scale * (maxDepth - 1) + 1;
|
|
3911
|
+
if (maxDepth === 1) explodeDepth = 1;
|
|
3912
|
+
function explodeObject(object, depth, parentCenter, parentOffset) {
|
|
3913
|
+
const objectBox = (new Box3).setFromObject(object);
|
|
3914
|
+
const objectCenter = objectBox.getCenter(new Vector3);
|
|
3915
|
+
const objectOffset = parentOffset.clone();
|
|
3916
|
+
if (depth > 0 && depth <= explodeDepth) {
|
|
3917
|
+
const offset = objectCenter.clone().sub(parentCenter).multiplyScalar(scale);
|
|
3918
|
+
objectOffset.add(offset);
|
|
3919
|
+
}
|
|
3920
|
+
object.children.forEach((object => explodeObject(object, depth + 1, objectCenter, objectOffset)));
|
|
3921
|
+
const originalPosition = object.originalPosition;
|
|
3922
|
+
object.position.copy(originalPosition);
|
|
3923
|
+
if (scale > 0) {
|
|
3924
|
+
const direction = objectCenter.sub(parentCenter).normalize();
|
|
3925
|
+
object.position.add(direction.add(objectOffset));
|
|
3926
|
+
}
|
|
3927
|
+
}
|
|
3928
|
+
const sceneExtents = (new Box3).setFromObject(scene);
|
|
3929
|
+
const sceneCenter = sceneExtents.getCenter(new Vector3);
|
|
3930
|
+
explodeObject(scene, 0, sceneCenter, new Vector3(0, 0, 0));
|
|
1635
3931
|
}
|
|
1636
3932
|
|
|
1637
3933
|
function explode(viewer, index = 0) {
|
|
1638
|
-
viewer.models.forEach((
|
|
1639
|
-
viewer.scene.updateMatrixWorld();
|
|
3934
|
+
viewer.models.forEach((gltf => explodeScene(gltf.scene, index)));
|
|
1640
3935
|
viewer.update();
|
|
1641
3936
|
viewer.emitEvent({
|
|
1642
3937
|
type: "explode",
|
|
@@ -1648,40 +3943,6 @@ function collect(viewer) {
|
|
|
1648
3943
|
explode(viewer, 0);
|
|
1649
3944
|
}
|
|
1650
3945
|
|
|
1651
|
-
function zoomTo(viewer, box) {
|
|
1652
|
-
if (box.isEmpty()) return;
|
|
1653
|
-
const center = box.getCenter(new Vector3);
|
|
1654
|
-
const sphere = box.getBoundingSphere(new Sphere);
|
|
1655
|
-
const rendererSize = viewer.renderer.getSize(new Vector2);
|
|
1656
|
-
const aspect = rendererSize.x / rendererSize.y;
|
|
1657
|
-
const camera = viewer.camera;
|
|
1658
|
-
if (camera.isPerspectiveCamera) {
|
|
1659
|
-
const offset = new Vector3(0, 0, 1);
|
|
1660
|
-
offset.applyQuaternion(camera.quaternion);
|
|
1661
|
-
offset.multiplyScalar(sphere.radius / Math.tan(MathUtils.DEG2RAD * camera.fov * .5));
|
|
1662
|
-
camera.position.copy(center).add(offset);
|
|
1663
|
-
camera.updateMatrixWorld();
|
|
1664
|
-
}
|
|
1665
|
-
if (camera.isOrthographicCamera) {
|
|
1666
|
-
camera.top = sphere.radius;
|
|
1667
|
-
camera.bottom = -sphere.radius;
|
|
1668
|
-
camera.left = camera.bottom * aspect;
|
|
1669
|
-
camera.right = camera.top * aspect;
|
|
1670
|
-
camera.zoom = 1;
|
|
1671
|
-
camera.updateProjectionMatrix();
|
|
1672
|
-
const offset = new Vector3(0, 0, 1);
|
|
1673
|
-
offset.applyQuaternion(camera.quaternion);
|
|
1674
|
-
offset.multiplyScalar(viewer.extents.getBoundingSphere(new Sphere).radius * 3);
|
|
1675
|
-
camera.position.copy(center).add(offset);
|
|
1676
|
-
camera.updateMatrixWorld();
|
|
1677
|
-
}
|
|
1678
|
-
viewer.target.copy(center);
|
|
1679
|
-
viewer.update();
|
|
1680
|
-
viewer.emitEvent({
|
|
1681
|
-
type: "zoom"
|
|
1682
|
-
});
|
|
1683
|
-
}
|
|
1684
|
-
|
|
1685
3946
|
const defaultViewPositions = {
|
|
1686
3947
|
top: new Vector3(0, 0, 1),
|
|
1687
3948
|
bottom: new Vector3(0, 0, -1),
|
|
@@ -1699,10 +3960,11 @@ function setDefaultViewPosition(viewer, position) {
|
|
|
1699
3960
|
const direction = defaultViewPositions[position] || defaultViewPositions["sw"];
|
|
1700
3961
|
const center = viewer.extents.getCenter(new Vector3);
|
|
1701
3962
|
const sphere = viewer.extents.getBoundingSphere(new Sphere);
|
|
1702
|
-
const
|
|
3963
|
+
const offet = direction.clone().multiplyScalar(sphere.radius);
|
|
1703
3964
|
const camera = viewer.camera;
|
|
1704
|
-
camera.position.copy(center).add(
|
|
3965
|
+
camera.position.copy(center).add(offet);
|
|
1705
3966
|
camera.lookAt(center);
|
|
3967
|
+
camera.updateProjectionMatrix();
|
|
1706
3968
|
camera.updateMatrixWorld();
|
|
1707
3969
|
viewer.target.copy(center);
|
|
1708
3970
|
viewer.update();
|
|
@@ -1710,7 +3972,7 @@ function setDefaultViewPosition(viewer, position) {
|
|
|
1710
3972
|
type: "viewposition",
|
|
1711
3973
|
data: position
|
|
1712
3974
|
});
|
|
1713
|
-
|
|
3975
|
+
viewer.executeCommand("zoomToExtents");
|
|
1714
3976
|
}
|
|
1715
3977
|
|
|
1716
3978
|
function getDefaultViewPositions() {
|
|
@@ -1720,14 +3982,14 @@ function getDefaultViewPositions() {
|
|
|
1720
3982
|
function getModels(viewer) {
|
|
1721
3983
|
return viewer.models.map((model => {
|
|
1722
3984
|
var _a;
|
|
1723
|
-
return ((_a = model.userData) === null || _a ===
|
|
3985
|
+
return ((_a = model.userData) === null || _a === void 0 ? void 0 : _a.handle) || "";
|
|
1724
3986
|
})).filter((handle => handle));
|
|
1725
3987
|
}
|
|
1726
3988
|
|
|
1727
3989
|
function getSelected(viewer) {
|
|
1728
3990
|
return viewer.selected.map((object => {
|
|
1729
3991
|
var _a;
|
|
1730
|
-
return (_a = object.userData) === null || _a ===
|
|
3992
|
+
return (_a = object.userData) === null || _a === void 0 ? void 0 : _a.handle;
|
|
1731
3993
|
})).filter((handle => handle));
|
|
1732
3994
|
}
|
|
1733
3995
|
|
|
@@ -1748,12 +4010,16 @@ function hideSelected(viewer) {
|
|
|
1748
4010
|
}
|
|
1749
4011
|
|
|
1750
4012
|
function isolateSelected(viewer) {
|
|
1751
|
-
const
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
object.
|
|
1755
|
-
|
|
1756
|
-
|
|
4013
|
+
const selectedSet = new Set(viewer.selected);
|
|
4014
|
+
function isolateObject(object, depth) {
|
|
4015
|
+
let canBeIsolated = true;
|
|
4016
|
+
object.children.forEach((object => {
|
|
4017
|
+
if (selectedSet.has(object)) canBeIsolated = false; else isolateObject(object, depth + 1);
|
|
4018
|
+
}));
|
|
4019
|
+
if (canBeIsolated && depth > 0) object.visible = false;
|
|
4020
|
+
return canBeIsolated;
|
|
4021
|
+
}
|
|
4022
|
+
isolateObject(viewer.scene, 0);
|
|
1757
4023
|
viewer.update();
|
|
1758
4024
|
viewer.emitEvent({
|
|
1759
4025
|
type: "isolate"
|
|
@@ -1802,7 +4068,7 @@ function setSelected(viewer, handles = []) {
|
|
|
1802
4068
|
const objects = [];
|
|
1803
4069
|
viewer.scene.traverseVisible((child => {
|
|
1804
4070
|
var _a;
|
|
1805
|
-
if (handleSet.has((_a = child.userData) === null || _a ===
|
|
4071
|
+
if (handleSet.has((_a = child.userData) === null || _a === void 0 ? void 0 : _a.handle)) objects.push(child);
|
|
1806
4072
|
}));
|
|
1807
4073
|
const selection = new SelectionComponent(viewer);
|
|
1808
4074
|
selection.clearSelection();
|
|
@@ -1825,7 +4091,18 @@ function showAll(viewer) {
|
|
|
1825
4091
|
}
|
|
1826
4092
|
|
|
1827
4093
|
function zoomToExtents(viewer) {
|
|
1828
|
-
|
|
4094
|
+
if (viewer.extents.isEmpty()) return;
|
|
4095
|
+
const center = viewer.extents.getCenter(new Vector3);
|
|
4096
|
+
const distance = viewer.extents.getBoundingSphere(new Sphere).radius;
|
|
4097
|
+
const delta = new Vector3(0, 0, 1);
|
|
4098
|
+
delta.applyQuaternion(viewer.camera.quaternion);
|
|
4099
|
+
delta.multiplyScalar(distance * 3);
|
|
4100
|
+
viewer.camera.position.copy(center).add(delta);
|
|
4101
|
+
viewer.target.copy(center);
|
|
4102
|
+
viewer.update();
|
|
4103
|
+
viewer.emitEvent({
|
|
4104
|
+
type: "zoom"
|
|
4105
|
+
});
|
|
1829
4106
|
}
|
|
1830
4107
|
|
|
1831
4108
|
function zoomToObjects(viewer, handles = []) {
|
|
@@ -1833,17 +4110,36 @@ function zoomToObjects(viewer, handles = []) {
|
|
|
1833
4110
|
const objects = [];
|
|
1834
4111
|
viewer.scene.traverseVisible((child => {
|
|
1835
4112
|
var _a;
|
|
1836
|
-
if (handleSet.has((_a = child.userData) === null || _a ===
|
|
4113
|
+
if (handleSet.has((_a = child.userData) === null || _a === void 0 ? void 0 : _a.handle)) objects.push(child);
|
|
1837
4114
|
}));
|
|
1838
4115
|
const extents = objects.reduce(((result, object) => result.expandByObject(object)), new Box3);
|
|
1839
|
-
|
|
1840
|
-
|
|
4116
|
+
const center = extents.getCenter(new Vector3);
|
|
4117
|
+
const distance = extents.getBoundingSphere(new Sphere).radius;
|
|
4118
|
+
const delta = new Vector3(0, 0, 1);
|
|
4119
|
+
delta.applyQuaternion(viewer.camera.quaternion);
|
|
4120
|
+
delta.multiplyScalar(distance * 3);
|
|
4121
|
+
viewer.camera.position.copy(center).add(delta);
|
|
4122
|
+
viewer.target.copy(center);
|
|
4123
|
+
viewer.update();
|
|
4124
|
+
viewer.emitEvent({
|
|
4125
|
+
type: "zoom"
|
|
4126
|
+
});
|
|
1841
4127
|
}
|
|
1842
4128
|
|
|
1843
4129
|
function zoomToSelected(viewer) {
|
|
1844
4130
|
const extents = viewer.selected.reduce(((result, object) => result.expandByObject(object)), new Box3);
|
|
1845
4131
|
if (extents.isEmpty()) extents.copy(viewer.extents);
|
|
1846
|
-
|
|
4132
|
+
const center = extents.getCenter(new Vector3);
|
|
4133
|
+
const distance = extents.getBoundingSphere(new Sphere).radius;
|
|
4134
|
+
const delta = new Vector3(0, 0, 1);
|
|
4135
|
+
delta.applyQuaternion(viewer.camera.quaternion);
|
|
4136
|
+
delta.multiplyScalar(distance * 3);
|
|
4137
|
+
viewer.camera.position.copy(center).add(delta);
|
|
4138
|
+
viewer.target.copy(center);
|
|
4139
|
+
viewer.update();
|
|
4140
|
+
viewer.emitEvent({
|
|
4141
|
+
type: "zoom"
|
|
4142
|
+
});
|
|
1847
4143
|
}
|
|
1848
4144
|
|
|
1849
4145
|
const commands = commandsRegistry("threejs");
|
|
@@ -1962,70 +4258,42 @@ class BackgroundComponent {
|
|
|
1962
4258
|
}
|
|
1963
4259
|
}
|
|
1964
4260
|
|
|
1965
|
-
class
|
|
4261
|
+
class DefaultPositionComponent {
|
|
1966
4262
|
constructor(viewer) {
|
|
1967
|
-
this.geometryEnd =
|
|
1968
|
-
const
|
|
1969
|
-
const
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
this.viewer.
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
this.viewer.camera = sceneCamera.clone();
|
|
1977
|
-
this.viewer.camera.up.set(0, 0, 1);
|
|
1978
|
-
this.viewer.camera.scale.set(1, 1, 1);
|
|
1979
|
-
}
|
|
1980
|
-
const camera = this.viewer.camera;
|
|
1981
|
-
if (camera.isPerspectiveCamera) {
|
|
1982
|
-
camera.aspect = aspect;
|
|
1983
|
-
camera.near = extentsSize / 100;
|
|
1984
|
-
camera.far = extentsSize * 100;
|
|
1985
|
-
camera.updateProjectionMatrix();
|
|
1986
|
-
}
|
|
1987
|
-
if (camera.isOrthographicCamera) {
|
|
1988
|
-
camera.left = camera.bottom * aspect;
|
|
1989
|
-
camera.right = camera.top * aspect;
|
|
1990
|
-
camera.near = 0;
|
|
1991
|
-
camera.far = extentsSize * 100;
|
|
1992
|
-
camera.updateProjectionMatrix();
|
|
1993
|
-
}
|
|
1994
|
-
if (!sceneCamera) {
|
|
1995
|
-
this.viewer.executeCommand("setDefaultViewPosition");
|
|
1996
|
-
}
|
|
4263
|
+
this.geometryEnd = event => {
|
|
4264
|
+
const box = this.viewer.extents;
|
|
4265
|
+
const size = box.getSize(new Vector3).length();
|
|
4266
|
+
this.viewer.camera.near = size / 100;
|
|
4267
|
+
this.viewer.camera.far = size * 100;
|
|
4268
|
+
this.viewer.camera.updateMatrixWorld();
|
|
4269
|
+
this.viewer.camera.updateProjectionMatrix();
|
|
4270
|
+
this.viewer.executeCommand("setDefaultViewPosition", "sw");
|
|
4271
|
+
this.viewer.executeCommand("zoomToExtents");
|
|
1997
4272
|
};
|
|
1998
4273
|
this.viewer = viewer;
|
|
1999
|
-
this.viewer.addEventListener("
|
|
4274
|
+
this.viewer.addEventListener("geometryend", this.geometryEnd);
|
|
2000
4275
|
}
|
|
2001
4276
|
dispose() {
|
|
2002
|
-
this.viewer.removeEventListener("
|
|
4277
|
+
this.viewer.removeEventListener("geometryend", this.geometryEnd);
|
|
2003
4278
|
}
|
|
2004
4279
|
}
|
|
2005
4280
|
|
|
2006
4281
|
class ExtentsComponent {
|
|
2007
4282
|
constructor(viewer) {
|
|
2008
4283
|
this.syncExtents = () => {
|
|
2009
|
-
const extents = new Box3;
|
|
2010
|
-
this.viewer.scene.traverseVisible((object => !object.children.length && extents.expandByObject(object)));
|
|
4284
|
+
const extents = this.viewer.models.reduce(((result, gltf) => result.expandByObject(gltf.scene)), new Box3);
|
|
2011
4285
|
this.viewer.extents.copy(extents);
|
|
2012
4286
|
this.viewer.target.copy(extents.getCenter(new Vector3));
|
|
2013
4287
|
};
|
|
2014
4288
|
this.viewer = viewer;
|
|
2015
|
-
this.viewer.addEventListener("
|
|
4289
|
+
this.viewer.addEventListener("geometryend", this.syncExtents);
|
|
2016
4290
|
this.viewer.addEventListener("clear", this.syncExtents);
|
|
2017
4291
|
this.viewer.on("explode", this.syncExtents);
|
|
2018
|
-
this.viewer.on("isolate", this.syncExtents);
|
|
2019
|
-
this.viewer.on("hide", this.syncExtents);
|
|
2020
|
-
this.viewer.on("showall", this.syncExtents);
|
|
2021
4292
|
}
|
|
2022
4293
|
dispose() {
|
|
2023
|
-
this.viewer.removeEventListener("
|
|
4294
|
+
this.viewer.removeEventListener("geometryend", this.syncExtents);
|
|
2024
4295
|
this.viewer.removeEventListener("clear", this.syncExtents);
|
|
2025
4296
|
this.viewer.off("explode", this.syncExtents);
|
|
2026
|
-
this.viewer.off("isolate", this.syncExtents);
|
|
2027
|
-
this.viewer.off("hide", this.syncExtents);
|
|
2028
|
-
this.viewer.off("showall", this.syncExtents);
|
|
2029
4297
|
}
|
|
2030
4298
|
}
|
|
2031
4299
|
|
|
@@ -2065,17 +4333,8 @@ class ResizeCanvasComponent {
|
|
|
2065
4333
|
this.resizeViewer = entries => {
|
|
2066
4334
|
const {width: width, height: height} = entries[0].contentRect;
|
|
2067
4335
|
if (!width || !height) return;
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
if (camera.isPerspectiveCamera) {
|
|
2071
|
-
camera.aspect = aspect;
|
|
2072
|
-
camera.updateProjectionMatrix();
|
|
2073
|
-
}
|
|
2074
|
-
if (camera.isOrthographicCamera) {
|
|
2075
|
-
camera.left = camera.bottom * aspect;
|
|
2076
|
-
camera.right = camera.top * aspect;
|
|
2077
|
-
camera.updateProjectionMatrix();
|
|
2078
|
-
}
|
|
4336
|
+
this.viewer.camera.aspect = width / height;
|
|
4337
|
+
this.viewer.camera.updateProjectionMatrix();
|
|
2079
4338
|
this.viewer.renderer.setSize(width, height, true);
|
|
2080
4339
|
this.viewer.update(true);
|
|
2081
4340
|
this.viewer.emitEvent({
|
|
@@ -2176,10 +4435,6 @@ class WCSHelper extends Object3D {
|
|
|
2176
4435
|
|
|
2177
4436
|
class WCSHelperComponent {
|
|
2178
4437
|
constructor(viewer) {
|
|
2179
|
-
this.geometryEnd = () => {
|
|
2180
|
-
this.wcsHelper.dispose();
|
|
2181
|
-
this.wcsHelper = new WCSHelper(this.viewer.camera);
|
|
2182
|
-
};
|
|
2183
4438
|
this.viewerRender = () => {
|
|
2184
4439
|
if (!this.viewer.options.showWCS) return;
|
|
2185
4440
|
if (this.viewer.extents.isEmpty()) return;
|
|
@@ -2187,13 +4442,9 @@ class WCSHelperComponent {
|
|
|
2187
4442
|
};
|
|
2188
4443
|
this.wcsHelper = new WCSHelper(viewer.camera);
|
|
2189
4444
|
this.viewer = viewer;
|
|
2190
|
-
this.viewer.addEventListener("databasechunk", this.geometryEnd);
|
|
2191
|
-
this.viewer.addEventListener("drawviewpoint", this.geometryEnd);
|
|
2192
4445
|
this.viewer.addEventListener("render", this.viewerRender);
|
|
2193
4446
|
}
|
|
2194
4447
|
dispose() {
|
|
2195
|
-
this.viewer.removeEventListener("databasechunk", this.geometryEnd);
|
|
2196
|
-
this.viewer.removeEventListener("drawviewpoint", this.geometryEnd);
|
|
2197
4448
|
this.viewer.removeEventListener("render", this.viewerRender);
|
|
2198
4449
|
this.wcsHelper.dispose();
|
|
2199
4450
|
}
|
|
@@ -2207,12 +4458,12 @@ components.registerComponent("LightComponent", (viewer => new LightComponent(vie
|
|
|
2207
4458
|
|
|
2208
4459
|
components.registerComponent("BackgroundComponent", (viewer => new BackgroundComponent(viewer)));
|
|
2209
4460
|
|
|
2210
|
-
components.registerComponent("CameraComponent", (viewer => new CameraComponent(viewer)));
|
|
2211
|
-
|
|
2212
4461
|
components.registerComponent("ResizeCanvasComponent", (viewer => new ResizeCanvasComponent(viewer)));
|
|
2213
4462
|
|
|
2214
4463
|
components.registerComponent("RenderLoopComponent", (viewer => new RenderLoopComponent(viewer)));
|
|
2215
4464
|
|
|
4465
|
+
components.registerComponent("DefaultPositionComponent", (viewer => new DefaultPositionComponent(viewer)));
|
|
4466
|
+
|
|
2216
4467
|
components.registerComponent("SelectionComponent", (viewer => new SelectionComponent(viewer)));
|
|
2217
4468
|
|
|
2218
4469
|
components.registerComponent("WCSHelperComponent", (viewer => new WCSHelperComponent(viewer)));
|
|
@@ -2240,7 +4491,7 @@ class GLTFLoadingManager extends LoadingManager {
|
|
|
2240
4491
|
this.setURLModifier((url => {
|
|
2241
4492
|
const key = decodeURI(url).replace(this.path, "").replace(this.resourcePath, "").replace(/^(\.?\/)/, "");
|
|
2242
4493
|
const dataURL = this.dataURLs.get(key);
|
|
2243
|
-
return dataURL !== null && dataURL !==
|
|
4494
|
+
return dataURL !== null && dataURL !== void 0 ? dataURL : url;
|
|
2244
4495
|
}));
|
|
2245
4496
|
}
|
|
2246
4497
|
dispose() {
|
|
@@ -2248,6 +4499,45 @@ class GLTFLoadingManager extends LoadingManager {
|
|
|
2248
4499
|
}
|
|
2249
4500
|
}
|
|
2250
4501
|
|
|
4502
|
+
class EventEmitter2 {
|
|
4503
|
+
constructor() {
|
|
4504
|
+
this._listeners = {};
|
|
4505
|
+
}
|
|
4506
|
+
addEventListener(type, listener) {
|
|
4507
|
+
if (this._listeners[type] === undefined) this._listeners[type] = [];
|
|
4508
|
+
this._listeners[type].push(listener);
|
|
4509
|
+
return this;
|
|
4510
|
+
}
|
|
4511
|
+
removeEventListener(type, listener) {
|
|
4512
|
+
if (this._listeners[type] === undefined) return this;
|
|
4513
|
+
const listeners = this._listeners[type].filter((x => x !== listener));
|
|
4514
|
+
if (listeners.length !== 0) this._listeners[type] = listeners; else delete this._listeners[type];
|
|
4515
|
+
return this;
|
|
4516
|
+
}
|
|
4517
|
+
removeAllListeners(type) {
|
|
4518
|
+
if (type) delete this._listeners[type]; else this._listeners = {};
|
|
4519
|
+
return this;
|
|
4520
|
+
}
|
|
4521
|
+
emitEvent(event) {
|
|
4522
|
+
if (this._listeners[event.type] === undefined) return false;
|
|
4523
|
+
const invoke = this._listeners[event.type].slice();
|
|
4524
|
+
invoke.forEach((listener => listener.call(this, event)));
|
|
4525
|
+
return true;
|
|
4526
|
+
}
|
|
4527
|
+
on(type, listener) {
|
|
4528
|
+
return this.addEventListener(type, listener);
|
|
4529
|
+
}
|
|
4530
|
+
off(type, listener) {
|
|
4531
|
+
return this.removeEventListener(type, listener);
|
|
4532
|
+
}
|
|
4533
|
+
emit(type, ...args) {
|
|
4534
|
+
if (typeof type === "string") return this.emitEvent({
|
|
4535
|
+
type: type,
|
|
4536
|
+
args: args
|
|
4537
|
+
}); else if (typeof type === "object") return this.emitEvent(type); else return false;
|
|
4538
|
+
}
|
|
4539
|
+
}
|
|
4540
|
+
|
|
2251
4541
|
class Viewer extends EventEmitter2 {
|
|
2252
4542
|
constructor(client) {
|
|
2253
4543
|
super();
|
|
@@ -2264,7 +4554,7 @@ class Viewer extends EventEmitter2 {
|
|
|
2264
4554
|
this.renderTime = 0;
|
|
2265
4555
|
this.render = this.render.bind(this);
|
|
2266
4556
|
this.update = this.update.bind(this);
|
|
2267
|
-
this._markup = new
|
|
4557
|
+
this._markup = new KonvaMarkup;
|
|
2268
4558
|
}
|
|
2269
4559
|
get options() {
|
|
2270
4560
|
return this._options;
|
|
@@ -2285,8 +4575,7 @@ class Viewer extends EventEmitter2 {
|
|
|
2285
4575
|
const rect = canvas.parentElement.getBoundingClientRect();
|
|
2286
4576
|
const width = rect.width || 1;
|
|
2287
4577
|
const height = rect.height || 1;
|
|
2288
|
-
|
|
2289
|
-
this.camera = new PerspectiveCamera(45, aspect, .01, 1e3);
|
|
4578
|
+
this.camera = new PerspectiveCamera(45, width / height, .01, 1e3);
|
|
2290
4579
|
this.camera.up.set(0, 0, 1);
|
|
2291
4580
|
this.renderer = new WebGLRenderer({
|
|
2292
4581
|
canvas: canvas,
|
|
@@ -2299,7 +4588,7 @@ class Viewer extends EventEmitter2 {
|
|
|
2299
4588
|
this.canvas = canvas;
|
|
2300
4589
|
this.canvasEvents.forEach((x => canvas.addEventListener(x, this.canvaseventlistener)));
|
|
2301
4590
|
this._markup.initialize(this.canvas, this.canvasEvents, this, this);
|
|
2302
|
-
for (
|
|
4591
|
+
for (let name of components.getComponents().keys()) {
|
|
2303
4592
|
this._components.push(components.createComponent(name, this));
|
|
2304
4593
|
}
|
|
2305
4594
|
this.syncOptions();
|
|
@@ -2360,7 +4649,7 @@ class Viewer extends EventEmitter2 {
|
|
|
2360
4649
|
this.renderer.autoClear = false;
|
|
2361
4650
|
this.renderer.render(this.helpers, this.camera);
|
|
2362
4651
|
this.renderer.clippingPlanes = clippingPlanes;
|
|
2363
|
-
(_b = (_a = this._activeDragger) === null || _a ===
|
|
4652
|
+
(_b = (_a = this._activeDragger) === null || _a === void 0 ? void 0 : _a.updatePreview) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
2364
4653
|
const deltaTime = (time - this.renderTime) / 1e3;
|
|
2365
4654
|
this.renderTime = time;
|
|
2366
4655
|
this.emitEvent({
|
|
@@ -2550,7 +4839,7 @@ class Viewer extends EventEmitter2 {
|
|
|
2550
4839
|
newDragger = draggers.createDragger(name, this);
|
|
2551
4840
|
if (newDragger) {
|
|
2552
4841
|
this._activeDragger = newDragger;
|
|
2553
|
-
(_b = (_a = this._activeDragger).initialize) === null || _b ===
|
|
4842
|
+
(_b = (_a = this._activeDragger).initialize) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
2554
4843
|
}
|
|
2555
4844
|
}
|
|
2556
4845
|
const canvas = this.canvas;
|
|
@@ -2625,66 +4914,38 @@ class Viewer extends EventEmitter2 {
|
|
|
2625
4914
|
var _a, _b, _c;
|
|
2626
4915
|
if (!this.renderer) return;
|
|
2627
4916
|
const getVector3FromPoint3d = ({x: x, y: y, z: z}) => new Vector3(x, y, z);
|
|
2628
|
-
const
|
|
2629
|
-
if (
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
this.camera
|
|
2634
|
-
this.camera.top = orthogonal_camera.field_height / 2;
|
|
2635
|
-
this.camera.bottom = -orthogonal_camera.field_height / 2;
|
|
2636
|
-
this.camera.left = this.camera.bottom * aspect;
|
|
2637
|
-
this.camera.right = this.camera.top * aspect;
|
|
2638
|
-
this.camera.near = 0;
|
|
2639
|
-
this.camera.far = extentsSize * 100;
|
|
2640
|
-
this.camera.zoom = orthogonal_camera.view_to_world_scale;
|
|
2641
|
-
this.camera.updateProjectionMatrix();
|
|
2642
|
-
this.camera.up.copy(getVector3FromPoint3d(orthogonal_camera.up_vector));
|
|
2643
|
-
this.camera.position.copy(getVector3FromPoint3d(orthogonal_camera.view_point));
|
|
2644
|
-
this.camera.lookAt(getVector3FromPoint3d(orthogonal_camera.direction).add(this.camera.position));
|
|
4917
|
+
const setPerspectiveCamera = camera => {
|
|
4918
|
+
if (camera) {
|
|
4919
|
+
this.camera.up.copy(getVector3FromPoint3d(camera.up_vector));
|
|
4920
|
+
this.camera.fov = camera.field_of_view;
|
|
4921
|
+
this.camera.position.copy(getVector3FromPoint3d(camera.view_point));
|
|
4922
|
+
this.camera.lookAt(getVector3FromPoint3d(camera.direction).add(this.camera.position));
|
|
2645
4923
|
this.camera.updateMatrixWorld();
|
|
2646
|
-
}
|
|
2647
|
-
};
|
|
2648
|
-
const setPerspectiveCamera = perspective_camera => {
|
|
2649
|
-
if (perspective_camera) {
|
|
2650
|
-
const extentsSize = this.extents.getBoundingSphere(new Sphere).radius * 2;
|
|
2651
|
-
const rendererSize = this.renderer.getSize(new Vector2);
|
|
2652
|
-
const aspect = rendererSize.x / rendererSize.y;
|
|
2653
|
-
this.camera = new PerspectiveCamera;
|
|
2654
|
-
this.camera.fov = perspective_camera.field_of_view;
|
|
2655
|
-
this.camera.aspect = aspect;
|
|
2656
|
-
this.camera.near = extentsSize / 100;
|
|
2657
|
-
this.camera.far = extentsSize * 100;
|
|
2658
4924
|
this.camera.updateProjectionMatrix();
|
|
2659
|
-
this.camera.up.copy(getVector3FromPoint3d(perspective_camera.up_vector));
|
|
2660
|
-
this.camera.position.copy(getVector3FromPoint3d(perspective_camera.view_point));
|
|
2661
|
-
this.camera.lookAt(getVector3FromPoint3d(perspective_camera.direction).add(this.camera.position));
|
|
2662
|
-
this.camera.updateMatrixWorld();
|
|
2663
4925
|
}
|
|
2664
4926
|
};
|
|
2665
4927
|
const setClippingPlanes = clipping_planes => {
|
|
2666
|
-
clipping_planes === null || clipping_planes ===
|
|
4928
|
+
clipping_planes === null || clipping_planes === void 0 ? void 0 : clipping_planes.forEach((clipping_plane => {
|
|
2667
4929
|
const plane = new Plane;
|
|
2668
4930
|
plane.setFromNormalAndCoplanarPoint(getVector3FromPoint3d(clipping_plane.direction), getVector3FromPoint3d(clipping_plane.location));
|
|
2669
4931
|
this.renderer.clippingPlanes.push(plane);
|
|
2670
4932
|
}));
|
|
2671
4933
|
};
|
|
2672
4934
|
const setSelection = selection => {
|
|
2673
|
-
|
|
4935
|
+
this.setSelected(selection === null || selection === void 0 ? void 0 : selection.map((component => component.handle)));
|
|
2674
4936
|
};
|
|
2675
|
-
const draggerName = (_a = this._activeDragger) === null || _a ===
|
|
4937
|
+
const draggerName = (_a = this._activeDragger) === null || _a === void 0 ? void 0 : _a.name;
|
|
2676
4938
|
this.setActiveDragger();
|
|
2677
4939
|
this.clearSlices();
|
|
2678
4940
|
this.clearOverlay();
|
|
2679
4941
|
this.clearSelected();
|
|
2680
4942
|
this.showAll();
|
|
2681
4943
|
this.explode();
|
|
2682
|
-
setOrthogonalCamera(viewpoint.orthogonal_camera);
|
|
2683
4944
|
setPerspectiveCamera(viewpoint.perspective_camera);
|
|
2684
4945
|
setClippingPlanes(viewpoint.clipping_planes);
|
|
2685
4946
|
setSelection(viewpoint.selection);
|
|
2686
4947
|
this._markup.setViewpoint(viewpoint);
|
|
2687
|
-
this.target = getVector3FromPoint3d((_c = (_b = viewpoint.custom_fields) === null || _b ===
|
|
4948
|
+
this.target = getVector3FromPoint3d((_c = (_b = viewpoint.custom_fields) === null || _b === void 0 ? void 0 : _b.camera_target) !== null && _c !== void 0 ? _c : this.target);
|
|
2688
4949
|
this.setActiveDragger(draggerName);
|
|
2689
4950
|
this.emitEvent({
|
|
2690
4951
|
type: "drawviewpoint",
|
|
@@ -2699,24 +4960,12 @@ class Viewer extends EventEmitter2 {
|
|
|
2699
4960
|
y: y,
|
|
2700
4961
|
z: z
|
|
2701
4962
|
});
|
|
2702
|
-
const
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
field_height: this.camera["top"] - this.camera["bottom"],
|
|
2709
|
-
view_to_world_scale: this.camera.zoom
|
|
2710
|
-
}; else return undefined;
|
|
2711
|
-
};
|
|
2712
|
-
const getPerspectiveCamera = () => {
|
|
2713
|
-
if (this.camera["isPerspectiveCamera"]) return {
|
|
2714
|
-
view_point: getPoint3dFromVector3(this.camera.position),
|
|
2715
|
-
direction: getPoint3dFromVector3(this.camera.getWorldDirection(new Vector3)),
|
|
2716
|
-
up_vector: getPoint3dFromVector3(this.camera.up),
|
|
2717
|
-
field_of_view: this.camera["fov"]
|
|
2718
|
-
}; else return undefined;
|
|
2719
|
-
};
|
|
4963
|
+
const getPerspectiveCamera = () => ({
|
|
4964
|
+
view_point: getPoint3dFromVector3(this.camera.position),
|
|
4965
|
+
direction: getPoint3dFromVector3(this.camera.getWorldDirection(new Vector3)),
|
|
4966
|
+
up_vector: getPoint3dFromVector3(this.camera.up),
|
|
4967
|
+
field_of_view: this.camera.fov
|
|
4968
|
+
});
|
|
2720
4969
|
const getClippingPlanes = () => {
|
|
2721
4970
|
const clipping_planes = [];
|
|
2722
4971
|
this.renderer.clippingPlanes.forEach((plane => {
|
|
@@ -2734,7 +4983,6 @@ class Viewer extends EventEmitter2 {
|
|
|
2734
4983
|
const viewpoint = {
|
|
2735
4984
|
custom_fields: {}
|
|
2736
4985
|
};
|
|
2737
|
-
viewpoint.orthogonal_camera = getOrthogonalCamera();
|
|
2738
4986
|
viewpoint.perspective_camera = getPerspectiveCamera();
|
|
2739
4987
|
viewpoint.clipping_planes = getClippingPlanes();
|
|
2740
4988
|
viewpoint.selection = getSelection();
|
|
@@ -2749,5 +4997,5 @@ class Viewer extends EventEmitter2 {
|
|
|
2749
4997
|
}
|
|
2750
4998
|
}
|
|
2751
4999
|
|
|
2752
|
-
export { Viewer, commands, components, draggers };
|
|
5000
|
+
export { CANVAS_EVENTS, CanvasEvents, Component, Dragger, KonvaMarkup as Markup, Options, Viewer, commands, commandsRegistry, components, componentsRegistry, defaultOptions, draggers, draggersRegistry };
|
|
2753
5001
|
//# sourceMappingURL=viewer-three.module.js.map
|