@xeokit/xeokit-sdk 2.6.55 → 2.6.57

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.
Files changed (32) hide show
  1. package/dist/xeokit-sdk.cjs.js +1369 -1771
  2. package/dist/xeokit-sdk.es.js +1367 -1772
  3. package/dist/xeokit-sdk.es5.js +709 -719
  4. package/dist/xeokit-sdk.min.cjs.js +5 -5
  5. package/dist/xeokit-sdk.min.es.js +5 -5
  6. package/dist/xeokit-sdk.min.es5.js +4 -4
  7. package/package.json +1 -1
  8. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurement.js +155 -415
  9. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +1 -1
  10. package/src/plugins/AnnotationsPlugin/Annotation.js +7 -5
  11. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.js +236 -750
  12. package/src/plugins/StoreyViewsPlugin/StoreyViewsPlugin.js +51 -0
  13. package/src/plugins/TreeViewPlugin/RenderService.js +2 -1
  14. package/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js +5 -1
  15. package/src/plugins/ZonesPlugin/ZonesPlugin.js +15 -79
  16. package/src/plugins/lib/html/Dot.js +14 -41
  17. package/src/plugins/lib/html/Label.js +10 -37
  18. package/src/plugins/lib/html/MenuEvent.js +74 -0
  19. package/src/plugins/lib/html/Wire.js +20 -47
  20. package/src/plugins/lib/ui/index.js +370 -12
  21. package/src/viewer/Viewer.js +9 -0
  22. package/src/viewer/index.js +1 -0
  23. package/src/viewer/scene/CameraControl/lib/handlers/MousePanRotateDollyHandler.js +1 -1
  24. package/src/viewer/scene/CameraControl/lib/handlers/TouchPanRotateAndDollyHandler.js +2 -1
  25. package/src/viewer/scene/marker/Marker.js +20 -23
  26. package/src/viewer/scene/model/SceneModelEntity.js +5 -0
  27. package/src/viewer/utils/index.js +1 -0
  28. package/src/viewer/utils/os.js +8 -1
  29. package/types/viewer/scene/models/PerformanceModel/index.d.ts +0 -1
  30. package/types/viewer/scene/models/SceneModel.d.ts +0 -3
  31. package/types/viewer/scene/models/SceneModelEntity.d.ts +6 -0
  32. package/types/viewer/scene/nodes/Node.d.ts +1 -1
@@ -308,6 +308,43 @@ class StoreyViewsPlugin extends Plugin {
308
308
  this.modelStoreys[modelId][storeyId] = storey;
309
309
  }
310
310
  }
311
+ this._clipBoundingBoxes();
312
+ }
313
+
314
+ _clipBoundingBoxes() {
315
+ const storeysList = this.storeysList;
316
+ const metaScene = this.viewer.metaScene;
317
+ const camera = this.viewer.camera;
318
+ const worldUp = camera.worldUp;
319
+ const xUp = worldUp[0] > worldUp[1] && worldUp[0] > worldUp[2];
320
+ const yUp = !xUp && worldUp[1] > worldUp[0] && worldUp[1] > worldUp[2];
321
+ const zUp = !xUp && !yUp && worldUp[2] > worldUp[0] && worldUp[2] > worldUp[1];
322
+
323
+ let bbIndex;
324
+
325
+ if(xUp) bbIndex = 0;
326
+ else if(yUp) bbIndex = 1;
327
+ else bbIndex = 2;
328
+
329
+ for (let i = 0, len = storeysList.length; i < len; i++) {
330
+
331
+ const storeyMetaObjectCur = metaScene.metaObjects[storeysList[i].storeyId];
332
+ const elevationCur = storeyMetaObjectCur.attributes.elevation;
333
+
334
+ if(isNaN(elevationCur)) return;
335
+
336
+ const bb = storeysList[i].storeyAABB;
337
+ bb[bbIndex] = Math.max(bb[1], parseFloat(elevationCur));
338
+
339
+ if (i > 0) {
340
+ const storeyMetaObjectNext = metaScene.metaObjects[storeysList[i - 1].storeyId];
341
+ const elevationNext = storeyMetaObjectNext.attributes.elevation;
342
+ bb[4] = Math.min(bb[bbIndex + 3], parseFloat(elevationNext));
343
+ }
344
+
345
+ this.storeys[storeysList[i].storeyId].storeyAABB = bb;
346
+ }
347
+
311
348
  }
312
349
 
313
350
  _deregisterModelStoreys(modelId) {
@@ -504,6 +541,7 @@ class StoreyViewsPlugin extends Plugin {
504
541
  * @param {Number} [options.width=300] Image width in pixels. Height will be automatically determined from this, if not given.
505
542
  * @param {Number} [options.height=300] Image height in pixels, as an alternative to width. Width will be automatically determined from this, if not given.
506
543
  * @param {String} [options.format="png"] Image format. Accepted values are "png" and "jpeg".
544
+ * @param {Boolean} [options.captureSectionPlanes=false] Whether the storey map is sliced or not.
507
545
  * @returns {StoreyMap} The StoreyMap.
508
546
  */
509
547
  createStoreyMap(storeyId, options = {}) {
@@ -520,6 +558,7 @@ class StoreyViewsPlugin extends Plugin {
520
558
  const aabb = (this._fitStoreyMaps) ? storey.storeyAABB : storey.modelAABB;
521
559
  const aspect = Math.abs((aabb[5] - aabb[2]) / (aabb[3] - aabb[0]));
522
560
  const padding = options.padding || 0;
561
+ const captureSectionPlanes = !!options.captureSectionPlanes;
523
562
 
524
563
  let width;
525
564
  let height;
@@ -551,6 +590,9 @@ class StoreyViewsPlugin extends Plugin {
551
590
  this.showStoreyObjects(storeyId, utils.apply(options, {
552
591
  hideOthers: true
553
592
  }));
593
+
594
+ if (captureSectionPlanes)
595
+ this._toggleSectionPlanes(false);
554
596
 
555
597
  this._arrangeStoreyMapCamera(storey);
556
598
 
@@ -562,10 +604,19 @@ class StoreyViewsPlugin extends Plugin {
562
604
 
563
605
  this._objectsMemento.restoreObjects(scene, mask);
564
606
  this._cameraMemento.restoreCamera(scene);
607
+ if (captureSectionPlanes)
608
+ this._toggleSectionPlanes(true);
565
609
 
566
610
  return new StoreyMap(storeyId, src, format, width, height, padding);
567
611
  }
568
612
 
613
+ _toggleSectionPlanes(visible) {
614
+ const planes = this.viewer.scene.sectionPlanes;
615
+ for (const key in planes) {
616
+ planes[key].active = visible;
617
+ }
618
+ }
619
+
569
620
  _arrangeStoreyMapCamera(storey) {
570
621
  const viewer = this.viewer;
571
622
  const scene = viewer.scene;
@@ -1,3 +1,4 @@
1
+ import { addContextMenuListener } from "../lib/html/MenuEvent.js";
1
2
  /**
2
3
  * @desc A {@link TreeViewPlugin} render class.
3
4
  *
@@ -49,7 +50,7 @@ export class RenderService {
49
50
  nodeElement.appendChild(span);
50
51
 
51
52
  if (contextmenuHandler) {
52
- span.oncontextmenu = contextmenuHandler;
53
+ addContextMenuListener(span, contextmenuHandler)
53
54
  }
54
55
 
55
56
  if (titleClickHandler) {
@@ -427,7 +427,7 @@ parsers[ParserV11.version] = ParserV11;
427
427
  *
428
428
  * ````javascript
429
429
  * const sceneModel = xktLoader.load({
430
- * manifestSrc: "https://xeokit.github.io/xeokit-sdk/assets/models/models/xkt/Schependomlaan.xkt",
430
+ * src: "https://xeokit.github.io/xeokit-sdk/assets/models/models/xkt/Schependomlaan.xkt",
431
431
  * id: "myModel",
432
432
  * });
433
433
  * ````
@@ -1165,6 +1165,10 @@ class XKTLoaderPlugin extends Plugin {
1165
1165
  }
1166
1166
 
1167
1167
  function getBaseDirectory(filePath) {
1168
+ if (filePath.indexOf('?') > -1) {
1169
+ filePath = filePath.split('?')[0];
1170
+ }
1171
+
1168
1172
  const pathArray = filePath.split('/');
1169
1173
  pathArray.pop(); // Remove the file name or the last segment of the path
1170
1174
  return pathArray.join('/') + '/';
@@ -2,12 +2,10 @@ import {Plugin} from "../../viewer/Plugin.js";
2
2
  import {Component} from "../../viewer/scene/Component.js";
3
3
  import {buildBoxGeometry} from "../../viewer/scene/geometry/builders/buildBoxGeometry.js";
4
4
  import {ReadableGeometry} from "../../viewer/scene/geometry/ReadableGeometry.js";
5
- import {Marker} from "../../viewer/scene/marker/Marker.js";
6
5
  import {PhongMaterial} from "../../viewer/scene/materials/PhongMaterial.js";
7
6
  import {math} from "../../viewer/scene/math/math.js";
8
7
  import {Mesh} from "../../viewer/scene/mesh/Mesh.js";
9
- import {Dot} from "../lib/html/Dot.js";
10
- import {activateDraggableDots, Dot3D, touchPointSelector, transformToNode} from "../../../src/plugins/lib/ui/index.js";
8
+ import {activateDraggableDots, Dot3D, Wire3D, touchPointSelector, transformToNode} from "../../../src/plugins/lib/ui/index.js";
11
9
 
12
10
  const hex2rgb = function(color) {
13
11
  const rgb = idx => parseInt(color.substr(idx + 1, 2), 16) / 255;
@@ -118,107 +116,45 @@ const triangulateEarClipping = function(planeCoords) {
118
116
  };
119
117
 
120
118
  const marker3D = function(scene, color) {
121
- const canvas = scene.canvas.canvas;
122
-
123
- const markerParent = canvas.parentNode;
124
- const markerDiv = document.createElement("div");
125
- markerParent.insertBefore(markerDiv, canvas);
126
-
127
- let size = 5;
128
- markerDiv.style.background = color;
129
- markerDiv.style.border = "2px solid white";
130
- markerDiv.style.margin = "0 0";
131
- markerDiv.style.zIndex = "100";
132
- markerDiv.style.position = "absolute";
133
- markerDiv.style.pointerEvents = "none";
134
- markerDiv.style.display = "none";
135
-
136
- const marker = new Marker(scene, {});
137
-
138
- const px = x => x + "px";
139
- const update = function() {
140
- const pos = marker.canvasPos.slice();
141
- transformToNode(canvas, markerParent, pos);
142
- markerDiv.style.left = px(pos[0] - 3 - size / 2);
143
- markerDiv.style.top = px(pos[1] - 3 - size / 2);
144
- markerDiv.style.borderRadius = px(size * 2);
145
- markerDiv.style.width = px(size);
146
- markerDiv.style.height = px(size);
147
- };
148
- const onViewMatrix = scene.camera.on("viewMatrix", update);
149
- const onProjMatrix = scene.camera.on("projMatrix", update);
119
+ const marker = new Dot3D(scene, {}, scene.canvas.canvas.parentNode, {
120
+ borderColor: "white",
121
+ fillColor: color,
122
+ zIndex: 100
123
+ });
150
124
 
151
125
  return {
152
126
  update: function(worldPos) {
153
127
  if (worldPos)
154
128
  {
155
129
  marker.worldPos = worldPos;
156
- update();
157
130
  }
158
- markerDiv.style.display = worldPos ? "" : "none";
159
- },
160
-
161
- setHighlighted: function(h) {
162
- size = h ? 10 : 5;
163
- update();
131
+ marker.setVisible(!!worldPos);
164
132
  },
165
133
 
166
- getCanvasPos: () => marker.canvasPos,
167
-
168
- getWorldPos: () => marker.worldPos,
169
-
170
- destroy: function() {
171
- markerDiv.parentNode.removeChild(markerDiv);
172
- scene.camera.off(onViewMatrix);
173
- scene.camera.off(onProjMatrix);
174
- marker.destroy();
175
- }
134
+ setHighlighted: h => marker.setHighlighted(h),
135
+ getCanvasPos: () => marker.canvasPos,
136
+ getWorldPos: () => marker.worldPos,
137
+ destroy: () => marker.destroy()
176
138
  };
177
139
  };
178
140
 
179
- import {Wire} from "../lib/html/Wire.js";
180
-
181
141
  const wire3D = function(scene, color, startWorldPos) {
182
- const canvas = scene.canvas.canvas;
183
-
184
- const startMarker = new Marker(scene, {});
185
- startMarker.worldPos = startWorldPos;
186
- const endMarker = new Marker(scene, {});
187
- const wireParent = canvas.ownerDocument.body;
188
- const wire = new Wire(wireParent, {
142
+ const wire = new Wire3D(scene, scene.canvas.canvas.ownerDocument.body, {
189
143
  color: color,
190
144
  thickness: 1,
191
145
  thicknessClickable: 6
192
146
  });
193
147
  wire.setVisible(false);
194
-
195
- const updatePos = function() {
196
- const p0 = startMarker.canvasPos.slice();
197
- const p1 = endMarker.canvasPos.slice();
198
- transformToNode(canvas, wireParent, p0);
199
- transformToNode(canvas, wireParent, p1);
200
- wire.setStartAndEnd(p0[0], p0[1], p1[0], p1[1]);
201
- };
202
- const onViewMatrix = scene.camera.on("viewMatrix", updatePos);
203
- const onProjMatrix = scene.camera.on("projMatrix", updatePos);
204
-
205
148
  return {
206
- update: function(endWorldPos) {
149
+ update: endWorldPos => {
207
150
  if (endWorldPos)
208
151
  {
209
- endMarker.worldPos = endWorldPos;
210
- updatePos();
152
+ wire.setEnds(startWorldPos, endWorldPos);
211
153
  }
212
154
  wire.setVisible(!!endWorldPos);
213
155
  },
214
156
 
215
- destroy: function() {
216
- scene.camera.off(onViewMatrix);
217
- scene.camera.off(onProjMatrix);
218
- startMarker.destroy();
219
- endMarker.destroy();
220
- wire.destroy();
221
- }
157
+ destroy: () => wire.destroy()
222
158
  };
223
159
  };
224
160
 
@@ -1,4 +1,4 @@
1
- import { os } from "../../../viewer/utils/os.js";
1
+ import { addContextMenuListener } from "./MenuEvent.js";
2
2
  /** @private */
3
3
  class Dot {
4
4
 
@@ -116,41 +116,10 @@ class Dot {
116
116
  }
117
117
 
118
118
  if (cfg.onContextMenu) {
119
- if(os.isIphoneSafari()){
120
- dotClickable.addEventListener('touchstart', (event) => {
121
- event.preventDefault();
122
- if(this._timeout){
123
- clearTimeout(this._timeout);
124
- this._timeout = null;
125
- }
126
- this._timeout = setTimeout(() => {
127
- event.clientX = event.touches[0].clientX;
128
- event.clientY = event.touches[0].clientY;
129
- cfg.onContextMenu(event, this);
130
- clearTimeout(this._timeout);
131
- this._timeout = null;
132
- }, 500);
133
- })
134
-
135
- dotClickable.addEventListener('touchend', (event) => {
136
- event.preventDefault();
137
- //stops short touches from calling the timeout
138
- if(this._timeout) {
139
- clearTimeout(this._timeout);
140
- this._timeout = null;
141
- }
142
- } )
143
-
144
- }
145
- else {
146
- dotClickable.addEventListener('contextmenu', (event) => {
147
- console.log(event);
148
- cfg.onContextMenu(event, this);
149
- event.preventDefault();
150
- event.stopPropagation();
151
- console.log("Label context menu")
152
- });
119
+ const contextMenuCallback = (event) => {
120
+ cfg.onContextMenu(event, this);
153
121
  }
122
+ addContextMenuListener(dotClickable, contextMenuCallback);
154
123
 
155
124
  }
156
125
 
@@ -163,12 +132,12 @@ class Dot {
163
132
  this._x = x;
164
133
  this._y = y;
165
134
  var dotStyle = this._dot.style;
166
- dotStyle["left"] = (Math.round(x) - 4) + 'px';
167
- dotStyle["top"] = (Math.round(y) - 4) + 'px';
135
+ dotStyle["left"] = (Math.round(x) - 6) + 'px';
136
+ dotStyle["top"] = (Math.round(y) - 6) + 'px';
168
137
 
169
138
  var dotClickableStyle = this._dotClickable.style;
170
- dotClickableStyle["left"] = (Math.round(x) - 9) + 'px';
171
- dotClickableStyle["top"] = (Math.round(y) - 9) + 'px';
139
+ dotClickableStyle["left"] = (Math.round(x) - 14) + 'px';
140
+ dotClickableStyle["top"] = (Math.round(y) - 14) + 'px';
172
141
  }
173
142
 
174
143
  setFillColor(color) {
@@ -183,12 +152,16 @@ class Dot {
183
152
  this._dot.style.opacity = opacity;
184
153
  }
185
154
 
155
+ _updateVisibility() {
156
+ this._dot.style.visibility = this._dotClickable.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
157
+ }
158
+
186
159
  setVisible(visible) {
187
160
  if (this._visible === visible) {
188
161
  return;
189
162
  }
190
163
  this._visible = !!visible;
191
- this._dot.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
164
+ this._updateVisibility();
192
165
  }
193
166
 
194
167
  setCulled(culled) {
@@ -196,7 +169,7 @@ class Dot {
196
169
  return;
197
170
  }
198
171
  this._culled = !!culled;
199
- this._dot.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
172
+ this._updateVisibility();
200
173
  }
201
174
 
202
175
  setClickable(clickable) {
@@ -1,4 +1,4 @@
1
- import { os } from "../../../viewer/utils/os.js";
1
+ import { addContextMenuListener } from "./MenuEvent.js";
2
2
  /** @private */
3
3
  class Label {
4
4
 
@@ -86,41 +86,10 @@ class Label {
86
86
  }
87
87
 
88
88
  if (cfg.onContextMenu) {
89
- if(os.isIphoneSafari()){
90
- label.addEventListener('touchstart', (event) => {
91
- event.preventDefault();
92
- if(this._timeout){
93
- clearTimeout(this._timeout);
94
- this._timeout = null;
95
- }
96
- this._timeout = setTimeout(() => {
97
- event.clientX = event.touches[0].clientX;
98
- event.clientY = event.touches[0].clientY;
99
- cfg.onContextMenu(event, this);
100
- clearTimeout(this._timeout);
101
- this._timeout = null;
102
- }, 500);
103
- })
104
-
105
- label.addEventListener('touchend', (event) => {
106
- event.preventDefault();
107
- //stops short touches from calling the timeout
108
- if(this._timeout) {
109
- clearTimeout(this._timeout);
110
- this._timeout = null;
111
- }
112
- } )
113
-
114
- }
115
- else {
116
- label.addEventListener('contextmenu', (event) => {
117
- console.log(event);
118
- cfg.onContextMenu(event, this);
119
- event.preventDefault();
120
- event.stopPropagation();
121
- console.log("Label context menu")
122
- });
89
+ const contextMenuCallback = (event) => {
90
+ cfg.onContextMenu(event, this);
123
91
  }
92
+ addContextMenuListener(label, contextMenuCallback);
124
93
 
125
94
  }
126
95
  }
@@ -167,12 +136,16 @@ class Label {
167
136
  this._label.style.opacity = opacity;
168
137
  }
169
138
 
139
+ _updateVisibility() {
140
+ this._label.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
141
+ }
142
+
170
143
  setVisible(visible) {
171
144
  if (this._visible === visible) {
172
145
  return;
173
146
  }
174
147
  this._visible = !!visible;
175
- this._label.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
148
+ this._updateVisibility();
176
149
  }
177
150
 
178
151
  setCulled(culled) {
@@ -180,7 +153,7 @@ class Label {
180
153
  return;
181
154
  }
182
155
  this._culled = !!culled;
183
- this._label.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
156
+ this._updateVisibility();
184
157
  }
185
158
 
186
159
  setHighlighted(highlighted) {
@@ -0,0 +1,74 @@
1
+ import { os } from "../../../viewer/utils/os.js";
2
+
3
+ export function addContextMenuListener(elem, callback) {
4
+ if (!elem || !callback) return;
5
+
6
+ let timeout = null;
7
+ const longPressTimer = 500;
8
+ const MOVE_THRESHOLD = 3;
9
+ let startX, startY;
10
+
11
+ const touchStartHandler = (event) => {
12
+ event.preventDefault();
13
+ const touch = event.touches[0];
14
+ startX = touch.clientX;
15
+ startY = touch.clientY;
16
+
17
+ if (timeout) {
18
+ clearTimeout(timeout);
19
+ timeout = null;
20
+ }
21
+
22
+ timeout = setTimeout(() => {
23
+ event.clientX = touch.clientX;
24
+ event.clientY = touch.clientY;
25
+ callback(event);
26
+ clearTimeout(timeout);
27
+ timeout = null;
28
+ }, longPressTimer);
29
+ };
30
+
31
+ const touchMoveHandler = (event) => {
32
+ if (!timeout) return;
33
+ const touch = event.touches[0];
34
+ const deltaX = Math.abs(touch.clientX - startX);
35
+ const deltaY = Math.abs(touch.clientY - startY);
36
+
37
+ if (deltaX > MOVE_THRESHOLD || deltaY > MOVE_THRESHOLD) {
38
+ clearTimeout(timeout);
39
+ timeout = null;
40
+ }
41
+ };
42
+
43
+ const touchEndHandler = (event) => {
44
+ event.preventDefault();
45
+ if (timeout) {
46
+ clearTimeout(timeout);
47
+ timeout = null;
48
+ }
49
+ };
50
+
51
+ const contextMenuHandler = (event) => {
52
+ callback(event);
53
+ event.preventDefault();
54
+ event.stopPropagation();
55
+ };
56
+
57
+ if (os.isIphoneSafari()) {
58
+ elem.addEventListener('touchstart', touchStartHandler);
59
+ elem.addEventListener('touchmove', touchMoveHandler);
60
+ elem.addEventListener('touchend', touchEndHandler);
61
+ } else {
62
+ elem.addEventListener('contextmenu', contextMenuHandler);
63
+ }
64
+
65
+ return function removeContextMenuListener() {
66
+ if (os.isIphoneSafari()) {
67
+ elem.removeEventListener('touchstart', touchStartHandler);
68
+ elem.removeEventListener('touchmove', touchMoveHandler);
69
+ elem.removeEventListener('touchend', touchEndHandler);
70
+ } else {
71
+ elem.removeEventListener('contextmenu', contextMenuHandler);
72
+ }
73
+ };
74
+ }
@@ -1,4 +1,4 @@
1
- import { os } from "../../../viewer/utils/os.js";
1
+ import { addContextMenuListener } from "./MenuEvent.js";
2
2
  /** @private */
3
3
  class Wire {
4
4
 
@@ -115,41 +115,10 @@ class Wire {
115
115
  }
116
116
 
117
117
  if (cfg.onContextMenu) {
118
- if(os.isIphoneSafari()){
119
- wireClickable.addEventListener('touchstart', (event) => {
120
- event.preventDefault();
121
- if(this._timeout){
122
- clearTimeout(this._timeout);
123
- this._timeout = null;
124
- }
125
- this._timeout = setTimeout(() => {
126
- event.clientX = event.touches[0].clientX;
127
- event.clientY = event.touches[0].clientY;
128
- cfg.onContextMenu(event, this);
129
- clearTimeout(this._timeout);
130
- this._timeout = null;
131
- }, 500);
132
- })
133
-
134
- wireClickable.addEventListener('touchend', (event) => {
135
- event.preventDefault();
136
- //stops short touches from calling the timeout
137
- if(this._timeout) {
138
- clearTimeout(this._timeout);
139
- this._timeout = null;
140
- }
141
- } )
142
-
143
- }
144
- else {
145
- wireClickable.addEventListener('contextmenu', (event) => {
146
- console.log(event);
147
- cfg.onContextMenu(event, this);
148
- event.preventDefault();
149
- event.stopPropagation();
150
- console.log("Label context menu")
151
- });
118
+ const contextMenuCallback = (event) => {
119
+ cfg.onContextMenu(event, this);
152
120
  }
121
+ addContextMenuListener(wireClickable, contextMenuCallback);
153
122
 
154
123
  }
155
124
 
@@ -174,21 +143,21 @@ class Wire {
174
143
  wireStyle["width"] = Math.round(length) + 'px';
175
144
  wireStyle["left"] = Math.round(this._x1) + 'px';
176
145
  wireStyle["top"] = Math.round(this._y1) + 'px';
177
- wireStyle['-webkit-transform'] = 'rotate(' + angle + 'deg)';
178
- wireStyle['-moz-transform'] = 'rotate(' + angle + 'deg)';
179
- wireStyle['-ms-transform'] = 'rotate(' + angle + 'deg)';
180
- wireStyle['-o-transform'] = 'rotate(' + angle + 'deg)';
181
- wireStyle['transform'] = 'rotate(' + angle + 'deg)';
146
+ wireStyle['-webkit-transform'] =
147
+ wireStyle['-moz-transform'] =
148
+ wireStyle['-ms-transform'] =
149
+ wireStyle['-o-transform'] =
150
+ wireStyle['transform'] = 'rotate(' + angle + 'deg) translate(-' + this._thickness + 'px, -' + this._thickness + 'px)';
182
151
 
183
152
  var wireClickableStyle = this._wireClickable.style;
184
153
  wireClickableStyle["width"] = Math.round(length) + 'px';
185
154
  wireClickableStyle["left"] = Math.round(this._x1) + 'px';
186
155
  wireClickableStyle["top"] = Math.round(this._y1) + 'px';
187
- wireClickableStyle['-webkit-transform'] = 'rotate(' + angle + 'deg)';
188
- wireClickableStyle['-moz-transform'] = 'rotate(' + angle + 'deg)';
189
- wireClickableStyle['-ms-transform'] = 'rotate(' + angle + 'deg)';
190
- wireClickableStyle['-o-transform'] = 'rotate(' + angle + 'deg)';
191
- wireClickableStyle['transform'] = 'rotate(' + angle + 'deg)';
156
+ wireClickableStyle['-webkit-transform'] =
157
+ wireClickableStyle['-moz-transform'] =
158
+ wireClickableStyle['-ms-transform'] =
159
+ wireClickableStyle['-o-transform'] =
160
+ wireClickableStyle['transform'] = 'rotate(' + angle + 'deg) translate(-' + this._thicknessClickable + 'px, -' + this._thicknessClickable + 'px)';
192
161
  }
193
162
 
194
163
  setStartAndEnd(x1, y1, x2, y2) {
@@ -208,12 +177,16 @@ class Wire {
208
177
  this._wire.style.opacity = opacity;
209
178
  }
210
179
 
180
+ _updateVisibility() {
181
+ this._wire.style.visibility = this._wireClickable.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
182
+ }
183
+
211
184
  setVisible(visible) {
212
185
  if (this._visible === visible) {
213
186
  return;
214
187
  }
215
188
  this._visible = !!visible;
216
- this._wire.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
189
+ this._updateVisibility();
217
190
  }
218
191
 
219
192
  setCulled(culled) {
@@ -221,7 +194,7 @@ class Wire {
221
194
  return;
222
195
  }
223
196
  this._culled = !!culled;
224
- this._wire.style.visibility = this._visible && !this._culled ? "visible" : "hidden";
197
+ this._updateVisibility();
225
198
  }
226
199
 
227
200
  setClickable(clickable) {