@vertexvis/viewer 0.20.1-testing.1 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/cjs/index.cjs.js +3 -2
  2. package/dist/cjs/index.cjs.js.map +1 -1
  3. package/dist/cjs/{controller-0155a10a.js → model-2105e63b.js} +85 -1
  4. package/dist/cjs/model-2105e63b.js.map +1 -0
  5. package/dist/cjs/vertex-viewer-box-query-tool.cjs.entry.js +7 -87
  6. package/dist/cjs/vertex-viewer-box-query-tool.cjs.entry.js.map +1 -1
  7. package/dist/cjs/vertex-viewer.cjs.entry.js +90 -24
  8. package/dist/cjs/vertex-viewer.cjs.entry.js.map +1 -1
  9. package/dist/collection/components/viewer-box-query-tool/viewer-box-query-tool.js +23 -1
  10. package/dist/collection/components/viewer-box-query-tool/viewer-box-query-tool.js.map +1 -1
  11. package/dist/collection/lib/interactions/multiPointerInteractionHandler.js +4 -2
  12. package/dist/collection/lib/interactions/multiPointerInteractionHandler.js.map +1 -1
  13. package/dist/collection/lib/interactions/multiTouchInteractionHandler.js +79 -17
  14. package/dist/collection/lib/interactions/multiTouchInteractionHandler.js.map +1 -1
  15. package/dist/collection/lib/interactions/touchInteractionHandler.js +4 -5
  16. package/dist/collection/lib/interactions/touchInteractionHandler.js.map +1 -1
  17. package/dist/collection/lib/volume-intersection/index.js +1 -0
  18. package/dist/collection/lib/volume-intersection/index.js.map +1 -1
  19. package/dist/collection/lib/window.js +7 -0
  20. package/dist/collection/lib/window.js.map +1 -0
  21. package/dist/components/index.js +1 -1
  22. package/dist/components/model2.js +165 -128
  23. package/dist/components/model2.js.map +1 -1
  24. package/dist/components/model3.js +157 -0
  25. package/dist/components/model3.js.map +1 -0
  26. package/dist/components/vertex-viewer-box-query-tool.js +4 -86
  27. package/dist/components/vertex-viewer-box-query-tool.js.map +1 -1
  28. package/dist/components/vertex-viewer-pin-tool.js +1 -1
  29. package/dist/components/vertex-viewer.js +91 -25
  30. package/dist/components/vertex-viewer.js.map +1 -1
  31. package/dist/components/viewer-pin-group.js +1 -1
  32. package/dist/components/viewer-pin-label-line.js +1 -1
  33. package/dist/components/viewer-pin-label.js +1 -1
  34. package/dist/esm/index.js +1 -1
  35. package/dist/esm/index.mjs +1 -1
  36. package/dist/esm/{controller-f0d7a836.js → model-4ba9fc30.js} +85 -2
  37. package/dist/esm/model-4ba9fc30.js.map +1 -0
  38. package/dist/esm/vertex-viewer-box-query-tool.entry.js +6 -86
  39. package/dist/esm/vertex-viewer-box-query-tool.entry.js.map +1 -1
  40. package/dist/esm/vertex-viewer.entry.js +91 -25
  41. package/dist/esm/vertex-viewer.entry.js.map +1 -1
  42. package/dist/types/components/viewer-box-query-tool/viewer-box-query-tool.d.ts +5 -1
  43. package/dist/types/components.d.ts +8 -0
  44. package/dist/types/lib/interactions/multiTouchInteractionHandler.d.ts +7 -2
  45. package/dist/types/lib/interactions/touchInteractionHandler.d.ts +1 -0
  46. package/dist/types/lib/volume-intersection/index.d.ts +1 -0
  47. package/dist/types/lib/window.d.ts +1 -0
  48. package/dist/viewer/index.esm.js +1 -1
  49. package/dist/viewer/index.esm.js.map +1 -1
  50. package/dist/viewer/p-12a301e0.entry.js +5 -0
  51. package/dist/viewer/p-12a301e0.entry.js.map +1 -0
  52. package/dist/viewer/p-4c4019b2.entry.js +5 -0
  53. package/dist/viewer/p-4c4019b2.entry.js.map +1 -0
  54. package/dist/viewer/p-ee0c9d33.js +5 -0
  55. package/dist/viewer/p-ee0c9d33.js.map +1 -0
  56. package/dist/viewer/viewer.esm.js +1 -1
  57. package/package.json +7 -7
  58. package/readme.md +4 -4
  59. package/dist/cjs/controller-0155a10a.js.map +0 -1
  60. package/dist/components/controller3.js +0 -111
  61. package/dist/components/controller3.js.map +0 -1
  62. package/dist/esm/controller-f0d7a836.js.map +0 -1
  63. package/dist/viewer/p-b50678f0.js +0 -5
  64. package/dist/viewer/p-b50678f0.js.map +0 -1
  65. package/dist/viewer/p-c6e12cf7.entry.js +0 -5
  66. package/dist/viewer/p-c6e12cf7.entry.js.map +0 -1
  67. package/dist/viewer/p-cfa05845.entry.js +0 -5
  68. package/dist/viewer/p-cfa05845.entry.js.map +0 -1
@@ -19,7 +19,7 @@ const streamAttributes = require('./streamAttributes-cffe0c85.js');
19
19
  const entities = require('./entities-551add54.js');
20
20
  const markup = require('./markup-7e0954cf.js');
21
21
  const viewport = require('./viewport-99139b8f.js');
22
- const controller$2 = require('./controller-0155a10a.js');
22
+ const model$1 = require('./model-2105e63b.js');
23
23
  require('./browser.esm-cd2f8925.js');
24
24
  require('./errors-992cc111.js');
25
25
  require('./representation_pb-772aa32b.js');
@@ -149,7 +149,8 @@ exports.ArrowMarkup = markup.ArrowMarkup;
149
149
  exports.CircleMarkup = markup.CircleMarkup;
150
150
  exports.FreeformMarkup = markup.FreeformMarkup;
151
151
  exports.Viewport = viewport.Viewport;
152
- exports.VolumeIntersectionQueryController = controller$2.VolumeIntersectionQueryController;
152
+ exports.VolumeIntersectionQueryController = model$1.VolumeIntersectionQueryController;
153
+ exports.VolumeIntersectionQueryModel = model$1.VolumeIntersectionQueryModel;
153
154
  exports.TransformationDelta = transformationDelta;
154
155
 
155
156
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"file":"index.cjs.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,MAAM,UAAU,GAAG,MAAM,CAAC;AAEjC;;;;;;SAMgB,6BAA6B,CAC3C,IAAqB;EAErB,MAAM,oBAAoB,GAAGA,kBAAO,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAChE,MAAM,oBAAoB,GAAGA,kBAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;EAEhE,MAAM,YAAY,GAChBA,kBAAO,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;IAC9CA,kBAAO,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;MAC1C,oBAAoB;MACpB,oBAAoB,CAAC;EAE3B,OAAOA,kBAAO,CAAC,SAAS,CAACA,kBAAO,CAAC,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;SAUgB,qBAAqB,CACnC,OAAwB,EACxB,OAAwB;EAExB,MAAM,GAAG,GAAGA,kBAAO,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;;EAE1C,IAAI,GAAG,GAAG,UAAU,EAAE;IACpB,MAAM,aAAa,GAAG,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAE7D,MAAM,UAAU,GAAGC,qBAAU,CAAC,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACpE,OAAOC,kBAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;GACzC;;OAEI,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE;IAC3B,OAAOA,kBAAO,CAAC,YAAY,EAAE,CAAC;GAC/B;;OAEI;IACH,MAAM,KAAK,GAAGF,kBAAO,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,aAAa,GAAGA,kBAAO,CAAC,SAAS,CAACA,kBAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACzE,OAAOE,kBAAO,CAAC,YAAY,CACzBD,qBAAU,CAAC,aAAa,CAAC,aAAa,EAAE,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CACzD,CAAC;GACH;AACH,CAAC;AAED;;;;;;;;;;;;;SAagB,0BAA0B,CACxC,OAAwB,EACxB,SAA0B,EAC1B,OAAwB,EACxB,SAA0B;EAE1B,MAAM,cAAc,GAAG,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;EAE/D,MAAM,sBAAsB,GAAGC,kBAAO,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;EAClE,OAAOA,kBAAO,CAAC,QAAQ,CACrBA,kBAAO,CAAC,QAAQ,CAAC,sBAAsB,EAAE,cAAc,CAAC,EACxDA,kBAAO,CAAC,eAAe,CAACF,kBAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CACnD,CAAC;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","names":["Vector3","Quaternion","Matrix4"],"sources":["./src/lib/transforms/transformation-delta.ts"],"sourcesContent":["import { Matrix4, Quaternion, Vector3 } from '@vertexvis/geometry';\n\nexport const ALMOST_ONE = 0.9999;\n\n/**\n * For any single normal vector, there are an infinite number of potential orthogonal vectors. This function will\n * calculate a single vector evaluating the length of two candidates, and picking the one with the higher squared magnitude\n * @param normal\n * @returns\n */\nexport function calculateOrthogonalCoordinate(\n norm: Vector3.Vector3\n): Vector3.Vector3 {\n const orthogonalCandidate0 = Vector3.create(0, norm.z, -norm.y);\n const orthogonalCandidate1 = Vector3.create(-norm.z, 0, norm.x);\n\n const theChosenOne =\n Vector3.magnitudeSquared(orthogonalCandidate0) >\n Vector3.magnitudeSquared(orthogonalCandidate1)\n ? orthogonalCandidate0\n : orthogonalCandidate1;\n\n return Vector3.normalize(Vector3.cross(norm, theChosenOne));\n}\n\n/**\n * Computes the rotation matrix for two normals. If both normals are neither parallel or anti-parallel,\n * this will compute the rotation matrix delta based on the angle from both normals.\n * If the normals are anti-parallel, the identity matrix will be returned, as no rotation is necessary in this case.\n * If the normals are parallel, an axis direction based on a chosen orthogonal vector will be used\n * to compute the rotation matrix to rotate the plane 180 degrees.\n * @param normal1\n * @param normal2\n * @returns an anti-parallel rotation Matrix4 betwen the given normals\n */\nexport function computeRotationMatrix(\n normal1: Vector3.Vector3,\n normal2: Vector3.Vector3\n): Matrix4.Matrix4 {\n const dot = Vector3.dot(normal1, normal2);\n // the angle is almost 0 in this case.\n if (dot > ALMOST_ONE) {\n const axisDirection = calculateOrthogonalCoordinate(normal1);\n\n const quaternion = Quaternion.fromAxisAngle(axisDirection, Math.PI);\n return Matrix4.makeRotation(quaternion);\n }\n // the angle is almost 180 in this case.\n else if (dot <= -ALMOST_ONE) {\n return Matrix4.makeIdentity();\n }\n // the angle is between 0 & 180\n else {\n const angle = Vector3.angleTo(normal2, normal1);\n const axisDirection = Vector3.normalize(Vector3.cross(normal1, normal2));\n return Matrix4.makeRotation(\n Quaternion.fromAxisAngle(axisDirection, angle + Math.PI)\n );\n }\n}\n\n/**\n * Computes the translation & rotation matrix delta between two world positions and two normals.\n * such that the computed translation matrix will be the delta between position 1 and position 2,\n * and the rotation will be rotated to be anti-parallel.\n *\n * @param normal1\n * @param position1\n * @param normal2\n * @param position2\n *\n * @returns Matrix4 translation matrix delta from position1 to\n * position2 & an anti-parallel rotation delta.\n */\nexport function computeTransformationDelta(\n normal1: Vector3.Vector3,\n position1: Vector3.Vector3,\n normal2: Vector3.Vector3,\n position2: Vector3.Vector3\n): Matrix4.Matrix4 {\n const rotationMatrix = computeRotationMatrix(normal1, normal2);\n\n const translationDeltaMatrix = Matrix4.makeTranslation(position2);\n return Matrix4.multiply(\n Matrix4.multiply(translationDeltaMatrix, rotationMatrix),\n Matrix4.makeTranslation(Vector3.negate(position1))\n );\n}\n"],"version":3}
1
+ {"file":"index.cjs.js","mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,MAAM,UAAU,GAAG,MAAM,CAAC;AAEjC;;;;;;SAMgB,6BAA6B,CAC3C,IAAqB;EAErB,MAAM,oBAAoB,GAAGA,kBAAO,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAChE,MAAM,oBAAoB,GAAGA,kBAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;EAEhE,MAAM,YAAY,GAChBA,kBAAO,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;IAC9CA,kBAAO,CAAC,gBAAgB,CAAC,oBAAoB,CAAC;MAC1C,oBAAoB;MACpB,oBAAoB,CAAC;EAE3B,OAAOA,kBAAO,CAAC,SAAS,CAACA,kBAAO,CAAC,KAAK,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;SAUgB,qBAAqB,CACnC,OAAwB,EACxB,OAAwB;EAExB,MAAM,GAAG,GAAGA,kBAAO,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;;EAE1C,IAAI,GAAG,GAAG,UAAU,EAAE;IACpB,MAAM,aAAa,GAAG,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAE7D,MAAM,UAAU,GAAGC,qBAAU,CAAC,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACpE,OAAOC,kBAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;GACzC;;OAEI,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE;IAC3B,OAAOA,kBAAO,CAAC,YAAY,EAAE,CAAC;GAC/B;;OAEI;IACH,MAAM,KAAK,GAAGF,kBAAO,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,MAAM,aAAa,GAAGA,kBAAO,CAAC,SAAS,CAACA,kBAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IACzE,OAAOE,kBAAO,CAAC,YAAY,CACzBD,qBAAU,CAAC,aAAa,CAAC,aAAa,EAAE,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CACzD,CAAC;GACH;AACH,CAAC;AAED;;;;;;;;;;;;;SAagB,0BAA0B,CACxC,OAAwB,EACxB,SAA0B,EAC1B,OAAwB,EACxB,SAA0B;EAE1B,MAAM,cAAc,GAAG,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;EAE/D,MAAM,sBAAsB,GAAGC,kBAAO,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;EAClE,OAAOA,kBAAO,CAAC,QAAQ,CACrBA,kBAAO,CAAC,QAAQ,CAAC,sBAAsB,EAAE,cAAc,CAAC,EACxDA,kBAAO,CAAC,eAAe,CAACF,kBAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CACnD,CAAC;AACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","names":["Vector3","Quaternion","Matrix4"],"sources":["./src/lib/transforms/transformation-delta.ts"],"sourcesContent":["import { Matrix4, Quaternion, Vector3 } from '@vertexvis/geometry';\n\nexport const ALMOST_ONE = 0.9999;\n\n/**\n * For any single normal vector, there are an infinite number of potential orthogonal vectors. This function will\n * calculate a single vector evaluating the length of two candidates, and picking the one with the higher squared magnitude\n * @param normal\n * @returns\n */\nexport function calculateOrthogonalCoordinate(\n norm: Vector3.Vector3\n): Vector3.Vector3 {\n const orthogonalCandidate0 = Vector3.create(0, norm.z, -norm.y);\n const orthogonalCandidate1 = Vector3.create(-norm.z, 0, norm.x);\n\n const theChosenOne =\n Vector3.magnitudeSquared(orthogonalCandidate0) >\n Vector3.magnitudeSquared(orthogonalCandidate1)\n ? orthogonalCandidate0\n : orthogonalCandidate1;\n\n return Vector3.normalize(Vector3.cross(norm, theChosenOne));\n}\n\n/**\n * Computes the rotation matrix for two normals. If both normals are neither parallel or anti-parallel,\n * this will compute the rotation matrix delta based on the angle from both normals.\n * If the normals are anti-parallel, the identity matrix will be returned, as no rotation is necessary in this case.\n * If the normals are parallel, an axis direction based on a chosen orthogonal vector will be used\n * to compute the rotation matrix to rotate the plane 180 degrees.\n * @param normal1\n * @param normal2\n * @returns an anti-parallel rotation Matrix4 betwen the given normals\n */\nexport function computeRotationMatrix(\n normal1: Vector3.Vector3,\n normal2: Vector3.Vector3\n): Matrix4.Matrix4 {\n const dot = Vector3.dot(normal1, normal2);\n // the angle is almost 0 in this case.\n if (dot > ALMOST_ONE) {\n const axisDirection = calculateOrthogonalCoordinate(normal1);\n\n const quaternion = Quaternion.fromAxisAngle(axisDirection, Math.PI);\n return Matrix4.makeRotation(quaternion);\n }\n // the angle is almost 180 in this case.\n else if (dot <= -ALMOST_ONE) {\n return Matrix4.makeIdentity();\n }\n // the angle is between 0 & 180\n else {\n const angle = Vector3.angleTo(normal2, normal1);\n const axisDirection = Vector3.normalize(Vector3.cross(normal1, normal2));\n return Matrix4.makeRotation(\n Quaternion.fromAxisAngle(axisDirection, angle + Math.PI)\n );\n }\n}\n\n/**\n * Computes the translation & rotation matrix delta between two world positions and two normals.\n * such that the computed translation matrix will be the delta between position 1 and position 2,\n * and the rotation will be rotated to be anti-parallel.\n *\n * @param normal1\n * @param position1\n * @param normal2\n * @param position2\n *\n * @returns Matrix4 translation matrix delta from position1 to\n * position2 & an anti-parallel rotation delta.\n */\nexport function computeTransformationDelta(\n normal1: Vector3.Vector3,\n position1: Vector3.Vector3,\n normal2: Vector3.Vector3,\n position2: Vector3.Vector3\n): Matrix4.Matrix4 {\n const rotationMatrix = computeRotationMatrix(normal1, normal2);\n\n const translationDeltaMatrix = Matrix4.makeTranslation(position2);\n return Matrix4.multiply(\n Matrix4.multiply(translationDeltaMatrix, rotationMatrix),\n Matrix4.makeTranslation(Vector3.negate(position1))\n );\n}\n"],"version":3}
@@ -5,6 +5,7 @@
5
5
 
6
6
  const bundle_esm = require('./bundle.esm-9ac09780.js');
7
7
  const browser_esm = require('./browser.esm-cd2f8925.js');
8
+ const bundle_esm$1 = require('./bundle.esm-f02fac92.js');
8
9
 
9
10
  class VolumeIntersectionQueryController {
10
11
  constructor(model, viewer) {
@@ -108,6 +109,89 @@ class VolumeIntersectionQueryController {
108
109
  }
109
110
  }
110
111
 
112
+ class VolumeIntersectionQueryModel {
113
+ constructor(mode) {
114
+ this.mode = mode;
115
+ this.dragStarted = new browser_esm.EventDispatcher();
116
+ this.dragComplete = new browser_esm.EventDispatcher();
117
+ this.dragCancelled = new browser_esm.EventDispatcher();
118
+ this.screenBoundsChanged = new browser_esm.EventDispatcher();
119
+ }
120
+ setStartPoint(point) {
121
+ this.startPoint = point;
122
+ this.dragStarted.emit();
123
+ }
124
+ setEndPoint(point) {
125
+ if (this.startPoint != null &&
126
+ bundle_esm$1.point.distance(this.startPoint, point) >= 2) {
127
+ this.endPoint = point;
128
+ this.updateQueryType();
129
+ this.screenBoundsChanged.emit(this.getQueryDetails());
130
+ }
131
+ }
132
+ setMode(mode) {
133
+ this.mode = mode;
134
+ }
135
+ complete() {
136
+ if (this.startPoint != null && this.endPoint != null) {
137
+ this.screenBoundsChanged.emit(undefined);
138
+ this.dragComplete.emit(this.getQueryDetails());
139
+ this.reset();
140
+ }
141
+ }
142
+ cancel() {
143
+ this.screenBoundsChanged.emit(undefined);
144
+ this.dragCancelled.emit();
145
+ this.reset();
146
+ }
147
+ reset() {
148
+ this.startPoint = undefined;
149
+ this.endPoint = undefined;
150
+ this.type = undefined;
151
+ }
152
+ getScreenBounds() {
153
+ return this.startPoint != null && this.endPoint != null
154
+ ? bundle_esm$1.rectangle.fromPoints(this.startPoint, this.endPoint)
155
+ : undefined;
156
+ }
157
+ getType() {
158
+ return this.type;
159
+ }
160
+ onScreenBoundsChanged(listener) {
161
+ return this.screenBoundsChanged.on(listener);
162
+ }
163
+ onDragStarted(listener) {
164
+ return this.dragStarted.on(listener);
165
+ }
166
+ onDragComplete(listener) {
167
+ return this.dragComplete.on(listener);
168
+ }
169
+ onDragCancelled(listener) {
170
+ return this.dragCancelled.on(listener);
171
+ }
172
+ getQueryDetails() {
173
+ if (this.startPoint != null && this.endPoint != null && this.type != null) {
174
+ return {
175
+ screenBounds: bundle_esm$1.rectangle.fromPoints(this.startPoint, this.endPoint),
176
+ type: this.type,
177
+ };
178
+ }
179
+ else {
180
+ throw new Error('Failed to create query details, the start and end points must be set.');
181
+ }
182
+ }
183
+ updateQueryType() {
184
+ var _a;
185
+ if (this.startPoint != null && this.endPoint != null) {
186
+ const directionalType = bundle_esm$1.point.subtract(this.endPoint, this.startPoint).x > 0
187
+ ? 'exclusive'
188
+ : 'inclusive';
189
+ this.type = (_a = this.mode) !== null && _a !== void 0 ? _a : directionalType;
190
+ }
191
+ }
192
+ }
193
+
111
194
  exports.VolumeIntersectionQueryController = VolumeIntersectionQueryController;
195
+ exports.VolumeIntersectionQueryModel = VolumeIntersectionQueryModel;
112
196
 
113
- //# sourceMappingURL=controller-0155a10a.js.map
197
+ //# sourceMappingURL=model-2105e63b.js.map
@@ -0,0 +1 @@
1
+ {"file":"model-2105e63b.js","mappings":"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","names":["EventDispatcher","StreamRequestError","Point","Rectangle"],"sources":["./src/lib/volume-intersection/controller.ts","./src/lib/volume-intersection/model.ts"],"sourcesContent":["import { Point } from '@vertexvis/geometry';\nimport { StreamRequestError } from '@vertexvis/stream-api';\nimport { Disposable, EventDispatcher, Listener } from '@vertexvis/utils';\n\nimport {\n SceneItemOperationsBuilder,\n TerminalItemOperationBuilder,\n} from '../scenes';\nimport { SceneItemQueryExecutor } from '../scenes/queries';\nimport { VolumeIntersectionQueryModel } from './model';\n\nexport type OperationTransform = (\n builder: SceneItemOperationsBuilder\n) => TerminalItemOperationBuilder;\nexport type AdditionalTransform = (\n executor: SceneItemQueryExecutor\n) => TerminalItemOperationBuilder;\n\nexport interface CompleteExecutionDetails {\n aborted: boolean;\n}\n\nexport class VolumeIntersectionQueryController {\n private previousViewerCameraControls?: boolean;\n private operationTransform: OperationTransform;\n private additionalTransforms: AdditionalTransform[] = [];\n private operationInFlight = false;\n private operationAborted = false;\n\n private executeStarted = new EventDispatcher<void>();\n private executeComplete = new EventDispatcher<CompleteExecutionDetails>();\n private executeAborted = new EventDispatcher<StreamRequestError>();\n\n public constructor(\n private model: VolumeIntersectionQueryModel,\n private viewer: HTMLVertexViewerElement\n ) {\n this.additionalTransforms = [(op) => op.where((q) => q.all()).deselect()];\n this.operationTransform = (builder) => builder.select();\n }\n\n public setStartPoint(point: Point.Point): void {\n this.previousViewerCameraControls = this.viewer.cameraControls;\n this.viewer.cameraControls = false;\n\n this.model.setStartPoint(point);\n }\n\n public setEndPoint(point: Point.Point): void {\n this.model.setEndPoint(point);\n }\n\n /**\n * Updates the operation that will be applied based on the volume intersection\n * query. Defaults to `(builder) => builder.select()`, which will select any\n * of the results of the query.\n */\n public setOperationTransform(operationTransform: OperationTransform): void {\n this.operationTransform = operationTransform;\n }\n\n /**\n * Updates any additional operations that should be performed independent of\n * the volume intersection query. This can be used to perform an operation on\n * the entirety of the scene prior to the operation on the result of the\n * volume intersection query.\n * Defaults to `[(op) => op.where((q) => q.all()).deselect()]`, which will\n * clear any prior selection before the default selection.\n */\n public setAdditionalTransforms(\n additionalTransforms: AdditionalTransform[]\n ): void {\n this.additionalTransforms = additionalTransforms;\n }\n\n public onExecuteStarted(listener: Listener<void>): Disposable {\n return this.executeStarted.on(listener);\n }\n\n public onExecuteComplete(\n listener: Listener<CompleteExecutionDetails>\n ): Disposable {\n return this.executeComplete.on(listener);\n }\n\n public onExecuteAborted(listener: Listener<StreamRequestError>): Disposable {\n return this.executeAborted.on(listener);\n }\n\n public async execute(): Promise<void> {\n const screenBounds = this.model.getScreenBounds();\n const type = this.model.getType();\n\n if (screenBounds != null && !this.operationInFlight) {\n this.model.complete();\n\n try {\n this.operationInFlight = true;\n this.executeStarted.emit();\n\n const additionalTransforms = (\n op: SceneItemQueryExecutor\n ): SceneItemOperationsBuilder[] =>\n this.additionalTransforms.map((t) => t(op)).flat();\n const operationTransforms = (\n op: SceneItemQueryExecutor\n ): SceneItemOperationsBuilder[] =>\n [\n this.operationTransform(\n op.where((q) =>\n q.withVolumeIntersection(screenBounds, type === 'exclusive')\n )\n ),\n ].flat();\n\n const scene = await this.viewer.scene();\n await scene\n .items((op) => [\n ...additionalTransforms(op),\n ...operationTransforms(op),\n ])\n .execute();\n } catch (e) {\n if (\n e instanceof StreamRequestError &&\n e.summary?.toLocaleLowerCase().includes('operation aborted')\n ) {\n this.executeAborted.emit(e);\n this.operationAborted = true;\n } else {\n console.error('Failed to perform volume intersection query', e);\n throw e;\n }\n } finally {\n this.viewer.cameraControls = this.previousViewerCameraControls ?? true;\n this.previousViewerCameraControls = undefined;\n this.operationInFlight = false;\n this.executeComplete.emit({\n aborted: this.operationAborted,\n });\n this.operationAborted = false;\n }\n } else if (this.operationInFlight) {\n this.model.cancel();\n\n throw new Error(\n `Unable to perform volume intersection query as there is already one in-flight.`\n );\n } else {\n this.model.cancel();\n\n this.viewer.cameraControls = this.previousViewerCameraControls ?? true;\n }\n }\n}\n","import { Point, Rectangle } from '@vertexvis/geometry';\nimport { Disposable, EventDispatcher, Listener } from '@vertexvis/utils';\n\nimport { VolumeIntersectionQueryMode } from '../../components/viewer-box-query-tool/types';\n\nexport type QueryType = 'inclusive' | 'exclusive';\n\nexport interface VolumeIntersectionQueryDetails {\n screenBounds: Rectangle.Rectangle;\n type: QueryType;\n}\n\nexport class VolumeIntersectionQueryModel {\n private startPoint?: Point.Point;\n private endPoint?: Point.Point;\n private type?: QueryType;\n\n private dragStarted = new EventDispatcher<void>();\n private dragComplete = new EventDispatcher<VolumeIntersectionQueryDetails>();\n private dragCancelled = new EventDispatcher<void>();\n\n private screenBoundsChanged = new EventDispatcher<\n VolumeIntersectionQueryDetails | undefined\n >();\n\n public constructor(private mode?: VolumeIntersectionQueryMode) {}\n\n public setStartPoint(point: Point.Point): void {\n this.startPoint = point;\n\n this.dragStarted.emit();\n }\n\n public setEndPoint(point: Point.Point): void {\n if (\n this.startPoint != null &&\n Point.distance(this.startPoint, point) >= 2\n ) {\n this.endPoint = point;\n\n this.updateQueryType();\n this.screenBoundsChanged.emit(this.getQueryDetails());\n }\n }\n\n public setMode(mode?: VolumeIntersectionQueryMode): void {\n this.mode = mode;\n }\n\n public complete(): void {\n if (this.startPoint != null && this.endPoint != null) {\n this.screenBoundsChanged.emit(undefined);\n this.dragComplete.emit(this.getQueryDetails());\n this.reset();\n }\n }\n\n public cancel(): void {\n this.screenBoundsChanged.emit(undefined);\n this.dragCancelled.emit();\n this.reset();\n }\n\n public reset(): void {\n this.startPoint = undefined;\n this.endPoint = undefined;\n this.type = undefined;\n }\n\n public getScreenBounds(): Rectangle.Rectangle | undefined {\n return this.startPoint != null && this.endPoint != null\n ? Rectangle.fromPoints(this.startPoint, this.endPoint)\n : undefined;\n }\n\n public getType(): QueryType | undefined {\n return this.type;\n }\n\n public onScreenBoundsChanged(\n listener: Listener<VolumeIntersectionQueryDetails | undefined>\n ): Disposable {\n return this.screenBoundsChanged.on(listener);\n }\n\n public onDragStarted(listener: Listener<void>): Disposable {\n return this.dragStarted.on(listener);\n }\n\n public onDragComplete(\n listener: Listener<VolumeIntersectionQueryDetails>\n ): Disposable {\n return this.dragComplete.on(listener);\n }\n\n public onDragCancelled(listener: Listener<void>): Disposable {\n return this.dragCancelled.on(listener);\n }\n\n private getQueryDetails(): VolumeIntersectionQueryDetails {\n if (this.startPoint != null && this.endPoint != null && this.type != null) {\n return {\n screenBounds: Rectangle.fromPoints(this.startPoint, this.endPoint),\n type: this.type,\n };\n } else {\n throw new Error(\n 'Failed to create query details, the start and end points must be set.'\n );\n }\n }\n\n private updateQueryType(): void {\n if (this.startPoint != null && this.endPoint != null) {\n const directionalType =\n Point.subtract(this.endPoint, this.startPoint).x > 0\n ? 'exclusive'\n : 'inclusive';\n\n this.type = this.mode ?? directionalType;\n }\n }\n}\n"],"version":3}
@@ -6,12 +6,12 @@
6
6
  Object.defineProperty(exports, '__esModule', { value: true });
7
7
 
8
8
  const index = require('./index-665745dd.js');
9
- const controller = require('./controller-0155a10a.js');
9
+ const model = require('./model-2105e63b.js');
10
10
  const cursors = require('./cursors-83749fa9.js');
11
11
  const dom = require('./dom-96a021e3.js');
12
- const bundle_esm = require('./bundle.esm-f02fac92.js');
13
- const browser_esm = require('./browser.esm-cd2f8925.js');
14
12
  require('./bundle.esm-9ac09780.js');
13
+ require('./bundle.esm-f02fac92.js');
14
+ require('./browser.esm-cd2f8925.js');
15
15
 
16
16
  class VolumeIntersectionQueryInteractionHandler {
17
17
  constructor(controller) {
@@ -93,93 +93,12 @@ class VolumeIntersectionQueryInteractionHandler {
93
93
  }
94
94
  }
95
95
 
96
- class VolumeIntersectionQueryModel {
97
- constructor(mode) {
98
- this.mode = mode;
99
- this.dragStarted = new browser_esm.EventDispatcher();
100
- this.dragComplete = new browser_esm.EventDispatcher();
101
- this.dragCancelled = new browser_esm.EventDispatcher();
102
- this.screenBoundsChanged = new browser_esm.EventDispatcher();
103
- }
104
- setStartPoint(point) {
105
- this.startPoint = point;
106
- this.dragStarted.emit();
107
- }
108
- setEndPoint(point) {
109
- if (this.startPoint != null &&
110
- bundle_esm.point.distance(this.startPoint, point) >= 2) {
111
- this.endPoint = point;
112
- this.updateQueryType();
113
- this.screenBoundsChanged.emit(this.getQueryDetails());
114
- }
115
- }
116
- setMode(mode) {
117
- this.mode = mode;
118
- }
119
- complete() {
120
- if (this.startPoint != null && this.endPoint != null) {
121
- this.screenBoundsChanged.emit(undefined);
122
- this.dragComplete.emit(this.getQueryDetails());
123
- this.reset();
124
- }
125
- }
126
- cancel() {
127
- this.screenBoundsChanged.emit(undefined);
128
- this.dragCancelled.emit();
129
- this.reset();
130
- }
131
- reset() {
132
- this.startPoint = undefined;
133
- this.endPoint = undefined;
134
- this.type = undefined;
135
- }
136
- getScreenBounds() {
137
- return this.startPoint != null && this.endPoint != null
138
- ? bundle_esm.rectangle.fromPoints(this.startPoint, this.endPoint)
139
- : undefined;
140
- }
141
- getType() {
142
- return this.type;
143
- }
144
- onScreenBoundsChanged(listener) {
145
- return this.screenBoundsChanged.on(listener);
146
- }
147
- onDragStarted(listener) {
148
- return this.dragStarted.on(listener);
149
- }
150
- onDragComplete(listener) {
151
- return this.dragComplete.on(listener);
152
- }
153
- onDragCancelled(listener) {
154
- return this.dragCancelled.on(listener);
155
- }
156
- getQueryDetails() {
157
- if (this.startPoint != null && this.endPoint != null && this.type != null) {
158
- return {
159
- screenBounds: bundle_esm.rectangle.fromPoints(this.startPoint, this.endPoint),
160
- type: this.type,
161
- };
162
- }
163
- else {
164
- throw new Error('Failed to create query details, the start and end points must be set.');
165
- }
166
- }
167
- updateQueryType() {
168
- var _a;
169
- if (this.startPoint != null && this.endPoint != null) {
170
- const directionalType = bundle_esm.point.subtract(this.endPoint, this.startPoint).x > 0
171
- ? 'exclusive'
172
- : 'inclusive';
173
- this.type = (_a = this.mode) !== null && _a !== void 0 ? _a : directionalType;
174
- }
175
- }
176
- }
177
-
178
96
  const viewerBoxQueryToolCss = ":host{--viewer-box-query-outline-exclusive-color:#0099cc;--viewer-box-query-outline-exclusive-border-style:solid;--viewer-box-query-outline-inclusive-color:#00cc00;--viewer-box-query-outline-inclusive-border-style:dashed;--viewer-box-query-outline-border-radius:0.25rem;--viewer-box-query-outline-fill-opacity:0.25}.bounds{position:absolute}.outline{position:absolute;top:0;left:0;width:100%;height:100%;box-sizing:border-box;border-radius:var(--viewer-box-query-outline-border-radius)}:host([exclusive=\"true\"]) .outline{border:3px var(--viewer-box-query-outline-exclusive-border-style) var(--viewer-box-query-outline-exclusive-color)}:host([inclusive=\"true\"]) .outline{border:3px var(--viewer-box-query-outline-inclusive-border-style) var(--viewer-box-query-outline-inclusive-color)}.fill{position:absolute;top:0;left:0;width:100%;height:100%;opacity:var(--viewer-box-query-outline-fill-opacity);border-radius:var(--viewer-box-query-outline-border-radius)}:host([exclusive=\"true\"]) .fill{background-color:var(--viewer-box-query-outline-exclusive-color)}:host([inclusive=\"true\"]) .fill{background-color:var(--viewer-box-query-outline-inclusive-color)}";
179
97
 
180
98
  const ViewerBoxQueryTool = class {
181
99
  constructor(hostRef) {
182
100
  index.registerInstance(this, hostRef);
101
+ this.controllerChanged = index.createEvent(this, "controllerChanged", 7);
183
102
  /**
184
103
  * The default operation to perform when a drag has completed and the intersection
185
104
  * query will be run. Defaults to `clearAndSelect`, and can be changed to `select` or `deselect`.
@@ -199,7 +118,7 @@ const ViewerBoxQueryTool = class {
199
118
  }
200
119
  componentWillLoad() {
201
120
  var _a;
202
- this.model = (_a = this.model) !== null && _a !== void 0 ? _a : new VolumeIntersectionQueryModel(this.mode);
121
+ this.model = (_a = this.model) !== null && _a !== void 0 ? _a : new model.VolumeIntersectionQueryModel(this.mode);
203
122
  this.screenBoundsChangedDisposable = this.model.onScreenBoundsChanged(this.handleScreenBoundsChanged);
204
123
  this.handleViewerChanged(this.viewer);
205
124
  this.handleControllerChange(this.controller);
@@ -219,7 +138,7 @@ const ViewerBoxQueryTool = class {
219
138
  handleViewerChanged(newViewer) {
220
139
  this.deregisterInteractionHandler();
221
140
  if (this.model != null && newViewer != null) {
222
- this.controller = new controller.VolumeIntersectionQueryController(this.model, newViewer);
141
+ this.controller = new model.VolumeIntersectionQueryController(this.model, newViewer);
223
142
  this.handleDefaultOperationChange(this.operationType);
224
143
  this.registerInteractionHandler(this.controller, newViewer);
225
144
  }
@@ -256,6 +175,7 @@ const ViewerBoxQueryTool = class {
256
175
  (_b = this.operationCompleteDisposable) === null || _b === void 0 ? void 0 : _b.dispose();
257
176
  this.operationStartedDisposable = controller === null || controller === void 0 ? void 0 : controller.onExecuteStarted(this.handleExecuteStarted);
258
177
  this.operationStartedDisposable = controller === null || controller === void 0 ? void 0 : controller.onExecuteComplete(this.handleExecuteComplete);
178
+ this.controllerChanged.emit(this.controller);
259
179
  }
260
180
  /**
261
181
  * @ignore
@@ -1 +1 @@
1
- {"file":"vertex-viewer-box-query-tool.entry.cjs.js","mappings":";;;;;;;;;;;;;;;MAQa,yCAAyC;EAWpD,YAA2B,UAA6C;IAA7C,eAAU,GAAV,UAAU,CAAmC;IACtE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEnD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;GACrB;EAEM,UAAU,CAAC,OAAoB,EAAE,GAAmB;IACzD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACvB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IAEf,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;IACnE,IAAI,CAAC,kBAAkB,EAAE,CAAC;GAC3B;EAEM,OAAO;;IACZ,MAAA,IAAI,CAAC,OAAO,0CAAE,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;IACvE,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3D,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5D,MAAA,IAAI,CAAC,yBAAyB,0CAAE,OAAO,EAAE,CAAC;IAC1C,MAAA,IAAI,CAAC,oBAAoB,0CAAE,OAAO,EAAE,CAAC;IAErC,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;IACzB,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC;IACrB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;GACrB;EAEM,OAAO;IACZ,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;GACtB;EAEM,MAAM;IACX,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;GACrB;EAEO,eAAe,CAAC,KAAmB;;IACzC,IACE,IAAI,CAAC,OAAO;MACZ,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC;MACrC,CAAC,IAAI,CAAC,aAAa,EACnB;MACA,IAAI,CAAC,aAAa,GAAG,MAAA,IAAI,CAAC,OAAO,0CAAE,qBAAqB,EAAE,CAAC;MAC3D,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;MAC1B,IAAI,CAAC,UAAU,CAAC,aAAa,CAC3BA,0BAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,CAClD,CAAC;MAEF,MAAM,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;MACxD,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;KAC1D;GACF;EAEO,UAAU,CAAC,KAAmB;IACpC,IAAI,IAAI,CAAC,OAAO,EAAE;MAChB,IAAI,CAAC,UAAU,CAAC,WAAW,CACzBA,0BAAsB,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,CAClD,CAAC;KACH;GACF;EAEO,MAAM,aAAa;;IACzB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;IAE3B,MAAM,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3D,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAE5D,MAAA,IAAI,CAAC,yBAAyB,0CAAE,OAAO,EAAE,CAAC;IAC1C,IAAI,IAAI,CAAC,OAAO,EAAE;MAChB,IAAI,CAAC,aAAa,EAAE,CAAC;MACrB,IAAI;QACF,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;OACjC;cAAS;QACR,MAAA,IAAI,CAAC,oBAAoB,0CAAE,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC,kBAAkB,EAAE,CAAC;OAC3B;KACF;GACF;EAEO,yBAAyB,CAAC,KAAmB;IACnD,OAAO,KAAK,CAAC,OAAO,KAAK,CAAC,CAAC;GAC5B;EAEO,kBAAkB;;IACxB,MAAA,IAAI,CAAC,yBAAyB,0CAAE,OAAO,EAAE,CAAC;IAC1C,IAAI,CAAC,yBAAyB,GAAG,MAAA,IAAI,CAAC,GAAG,0CAAE,SAAS,CAACC,sBAAc,CAAC,CAAC;GACtE;EAEO,aAAa;;IACnB,MAAA,IAAI,CAAC,oBAAoB,0CAAE,OAAO,EAAE,CAAC;IACrC,IAAI,CAAC,oBAAoB,GAAG,MAAA,IAAI,CAAC,GAAG,0CAAE,SAAS,CAAC,MAAM,CAAC,CAAC;GACzD;;;MClGU,4BAA4B;EAavC,YAA2B,IAAkC;IAAlC,SAAI,GAAJ,IAAI,CAA8B;IARrD,gBAAW,GAAG,IAAIC,2BAAe,EAAQ,CAAC;IAC1C,iBAAY,GAAG,IAAIA,2BAAe,EAAkC,CAAC;IACrE,kBAAa,GAAG,IAAIA,2BAAe,EAAQ,CAAC;IAE5C,wBAAmB,GAAG,IAAIA,2BAAe,EAE9C,CAAC;GAE6D;EAE1D,aAAa,CAAC,KAAkB;IACrC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;IAExB,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;GACzB;EAEM,WAAW,CAAC,KAAkB;IACnC,IACE,IAAI,CAAC,UAAU,IAAI,IAAI;MACvBC,gBAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,EAC3C;MACA,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;MAEtB,IAAI,CAAC,eAAe,EAAE,CAAC;MACvB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;KACvD;GACF;EAEM,OAAO,CAAC,IAAkC;IAC/C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;GAClB;EAEM,QAAQ;IACb,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE;MACpD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;MACzC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;MAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;KACd;GACF;EAEM,MAAM;IACX,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;GACd;EAEM,KAAK;IACV,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;GACvB;EAEM,eAAe;IACpB,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI;QACnDC,oBAAS,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC;QACpD,SAAS,CAAC;GACf;EAEM,OAAO;IACZ,OAAO,IAAI,CAAC,IAAI,CAAC;GAClB;EAEM,qBAAqB,CAC1B,QAA8D;IAE9D,OAAO,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;GAC9C;EAEM,aAAa,CAAC,QAAwB;IAC3C,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;GACtC;EAEM,cAAc,CACnB,QAAkD;IAElD,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;GACvC;EAEM,eAAe,CAAC,QAAwB;IAC7C,OAAO,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;GACxC;EAEO,eAAe;IACrB,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE;MACzE,OAAO;QACL,YAAY,EAAEA,oBAAS,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC;QAClE,IAAI,EAAE,IAAI,CAAC,IAAI;OAChB,CAAC;KACH;SAAM;MACL,MAAM,IAAI,KAAK,CACb,uEAAuE,CACxE,CAAC;KACH;GACF;EAEO,eAAe;;IACrB,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE;MACpD,MAAM,eAAe,GACnBD,gBAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;UAChD,WAAW;UACX,WAAW,CAAC;MAElB,IAAI,CAAC,IAAI,GAAG,MAAA,IAAI,CAAC,IAAI,mCAAI,eAAe,CAAC;KAC1C;GACF;;;ACzHH,MAAM,qBAAqB,GAAG,yoCAAyoC;;MC0B1pC,kBAAkB;EAkE7B;;;;;;;;;;;;;;IA9BO,kBAAa,GAAgC,gBAAgB,CAAC;IA+BnE,IAAI,CAAC,yBAAyB,GAAG,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3E,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;GACpE;EAEM,iBAAiB;;IACtB,IAAI,CAAC,KAAK,GAAG,MAAA,IAAI,CAAC,KAAK,mCAAI,IAAI,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEvE,IAAI,CAAC,6BAA6B,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CACnE,IAAI,CAAC,yBAAyB,CAC/B,CAAC;IAEF,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC7C,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;GACvD;EAEM,oBAAoB;;IACzB,MAAA,IAAI,CAAC,KAAK,0CAAE,KAAK,EAAE,CAAC;IACpB,MAAA,IAAI,CAAC,6BAA6B,0CAAE,OAAO,EAAE,CAAC;IAC9C,MAAA,IAAI,CAAC,0BAA0B,0CAAE,OAAO,EAAE,CAAC;IAC3C,MAAA,IAAI,CAAC,2BAA2B,0CAAE,OAAO,EAAE,CAAC;IAC5C,IAAI,CAAC,4BAA4B,EAAE,CAAC;GACrC;;;;EAMS,mBAAmB,CAAC,SAAmC;IAC/D,IAAI,CAAC,4BAA4B,EAAE,CAAC;IAEpC,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI,EAAE;MAC3C,IAAI,CAAC,UAAU,GAAG,IAAIE,4CAAiC,CACrD,IAAI,CAAC,KAAK,EACV,SAAS,CACV,CAAC;MACF,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;MACtD,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;KAC7D;GACF;;;;EAMS,4BAA4B,CACpC,oBAAiD;IAEjD,QAAQ,oBAAoB;MAC1B,KAAK,gBAAgB;QACnB,IAAI,CAAC,iCAAiC,EAAE,CAAC;QACzC,MAAM;MACR,KAAK,QAAQ;QACX,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACjC,MAAM;MACR,KAAK,UAAU;QACb,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACnC,MAAM;KACT;GACF;;;;EAMS,gBAAgB,CAAC,WAAyC;;IAClE,MAAA,IAAI,CAAC,KAAK,0CAAE,OAAO,CAAC,WAAW,CAAC,CAAC;GAClC;;;;EAMS,sBAAsB,CAC9B,UAA8C;;IAE9C,MAAA,IAAI,CAAC,0BAA0B,0CAAE,OAAO,EAAE,CAAC;IAC3C,MAAA,IAAI,CAAC,2BAA2B,0CAAE,OAAO,EAAE,CAAC;IAE5C,IAAI,CAAC,0BAA0B,GAAG,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,gBAAgB,CAC5D,IAAI,CAAC,oBAAoB,CAC1B,CAAC;IACF,IAAI,CAAC,0BAA0B,GAAG,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,iBAAiB,CAC7D,IAAI,CAAC,qBAAqB,CAC3B,CAAC;GACH;;;;EAKS,MAAM;IACd,QACEC,QAACC,UAAI,QACHD,qCACG,IAAI,CAAC,OAAO,IAAI,IAAI,KACnBA,iBACE,KAAK,EAAC,QAAQ,EACd,KAAK,EAAE;QACL,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI;QACxC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,IAAI;QACvC,KAAK,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI;QAC7C,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,IAAI;OAChD,IAEDA,kBAAM,IAAI,EAAC,QAAQ,IACjBA,iBAAK,KAAK,EAAC,SAAS,GAAO,EAC3BA,iBAAK,KAAK,EAAC,MAAM,GAAO,CACnB,CACH,CACP,CACmB,CACjB,EACP;GACH;EAEO,yBAAyB,CAC/B,OAAwC;IAExC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAEvB,IAAI,CAAC,mBAAmB,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,CAAC,CAAC;GACzC;EAEO,oBAAoB;;IAC1B,MAAA,IAAI,CAAC,kBAAkB,0CAAE,OAAO,EAAE,CAAC;GACpC;EAEO,qBAAqB;;IAC3B,MAAA,IAAI,CAAC,kBAAkB,0CAAE,MAAM,EAAE,CAAC;GACnC;EAEO,MAAM,0BAA0B,CACtC,UAA6C,EAC7C,MAA+B;IAE/B,IAAI,CAAC,kBAAkB,GAAG,IAAI,yCAAyC,CACrE,UAAU,CACX,CAAC;IACF,IAAI,CAAC,4BAA4B,GAAG,MAAM,MAAM,CAAC,0BAA0B,CACzE,IAAI,CAAC,kBAAkB,CACxB,CAAC;GACH;EAEO,4BAA4B;;IAClC,MAAA,IAAI,CAAC,4BAA4B,0CAAE,OAAO,EAAE,CAAC;IAC7C,MAAA,IAAI,CAAC,kBAAkB,0CAAE,OAAO,EAAE,CAAC;IACnC,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC;GACrC;EAEO,mBAAmB,CAAC,IAAgB;IAC1C,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE,GAAG,IAAI,KAAK,WAAW,EAAE,CAAC,CAAC;IACjE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE,GAAG,IAAI,KAAK,WAAW,EAAE,CAAC,CAAC;GAClE;EAEO,iCAAiC;;IACvC,MAAA,IAAI,CAAC,UAAU,0CAAE,qBAAqB,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtE,MAAA,IAAI,CAAC,UAAU,0CAAE,uBAAuB,CAAC;MACvC,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,QAAQ,EAAE;KACrD,CAAC,CAAC;GACJ;EAEO,yBAAyB;;IAC/B,MAAA,IAAI,CAAC,UAAU,0CAAE,qBAAqB,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtE,MAAA,IAAI,CAAC,UAAU,0CAAE,uBAAuB,CAAC,EAAE,CAAC,CAAC;GAC9C;EAEO,2BAA2B;;IACjC,MAAA,IAAI,CAAC,UAAU,0CAAE,qBAAqB,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACxE,MAAA,IAAI,CAAC,UAAU,0CAAE,uBAAuB,CAAC,EAAE,CAAC,CAAC;GAC9C;;;;;;;;;;;;;","names":["getMouseClientPosition","boxQueryCursor","EventDispatcher","Point","Rectangle","VolumeIntersectionQueryController","h","Host"],"sources":["./src/lib/volume-intersection/interactions.ts","./src/lib/volume-intersection/model.ts","./src/components/viewer-box-query-tool/viewer-box-query-tool.css?tag=vertex-viewer-box-query-tool&encapsulation=shadow","./src/components/viewer-box-query-tool/viewer-box-query-tool.tsx"],"sourcesContent":["import { Disposable } from '@vertexvis/utils';\n\nimport { boxQueryCursor } from '../cursors';\nimport { getMouseClientPosition } from '../dom';\nimport { InteractionApi } from '../interactions';\nimport { InteractionHandler } from '../interactions/interactionHandler';\nimport { VolumeIntersectionQueryController } from './controller';\n\nexport class VolumeIntersectionQueryInteractionHandler\n implements InteractionHandler\n{\n private element?: HTMLElement;\n private api?: InteractionApi;\n private isInteracting?: boolean;\n private enabled?: boolean;\n private elementBounds?: DOMRect;\n private crosshairCursorDisposable?: Disposable;\n private waitCursorDisposable?: Disposable;\n\n public constructor(private controller: VolumeIntersectionQueryController) {\n this.handleDragBegin = this.handleDragBegin.bind(this);\n this.handleDrag = this.handleDrag.bind(this);\n this.handleDragEnd = this.handleDragEnd.bind(this);\n\n this.enabled = true;\n }\n\n public initialize(element: HTMLElement, api: InteractionApi): void {\n this.element = element;\n this.api = api;\n\n this.element.addEventListener('pointerdown', this.handleDragBegin);\n this.addCrosshairCursor();\n }\n\n public dispose(): void {\n this.element?.removeEventListener('pointerdown', this.handleDragBegin);\n window.removeEventListener('pointermove', this.handleDrag);\n window.removeEventListener('pointerup', this.handleDragEnd);\n this.crosshairCursorDisposable?.dispose();\n this.waitCursorDisposable?.dispose();\n\n this.element = undefined;\n this.api = undefined;\n this.enabled = true;\n }\n\n public disable(): void {\n this.enabled = false;\n }\n\n public enable(): void {\n this.enabled = true;\n }\n\n private handleDragBegin(event: PointerEvent): void {\n if (\n this.enabled &&\n this.isPrimaryMouseButtonClick(event) &&\n !this.isInteracting\n ) {\n this.elementBounds = this.element?.getBoundingClientRect();\n this.isInteracting = true;\n this.controller.setStartPoint(\n getMouseClientPosition(event, this.elementBounds)\n );\n\n window.addEventListener('pointermove', this.handleDrag);\n window.addEventListener('pointerup', this.handleDragEnd);\n }\n }\n\n private handleDrag(event: PointerEvent): void {\n if (this.enabled) {\n this.controller.setEndPoint(\n getMouseClientPosition(event, this.elementBounds)\n );\n }\n }\n\n private async handleDragEnd(): Promise<void> {\n this.isInteracting = false;\n\n window.removeEventListener('pointermove', this.handleDrag);\n window.removeEventListener('pointerup', this.handleDragEnd);\n\n this.crosshairCursorDisposable?.dispose();\n if (this.enabled) {\n this.addWaitCursor();\n try {\n await this.controller.execute();\n } finally {\n this.waitCursorDisposable?.dispose();\n this.addCrosshairCursor();\n }\n }\n }\n\n private isPrimaryMouseButtonClick(event: PointerEvent): boolean {\n return event.buttons === 1;\n }\n\n private addCrosshairCursor(): void {\n this.crosshairCursorDisposable?.dispose();\n this.crosshairCursorDisposable = this.api?.addCursor(boxQueryCursor);\n }\n\n private addWaitCursor(): void {\n this.waitCursorDisposable?.dispose();\n this.waitCursorDisposable = this.api?.addCursor('wait');\n }\n}\n","import { Point, Rectangle } from '@vertexvis/geometry';\nimport { Disposable, EventDispatcher, Listener } from '@vertexvis/utils';\n\nimport { VolumeIntersectionQueryMode } from '../../components/viewer-box-query-tool/types';\n\nexport type QueryType = 'inclusive' | 'exclusive';\n\nexport interface VolumeIntersectionQueryDetails {\n screenBounds: Rectangle.Rectangle;\n type: QueryType;\n}\n\nexport class VolumeIntersectionQueryModel {\n private startPoint?: Point.Point;\n private endPoint?: Point.Point;\n private type?: QueryType;\n\n private dragStarted = new EventDispatcher<void>();\n private dragComplete = new EventDispatcher<VolumeIntersectionQueryDetails>();\n private dragCancelled = new EventDispatcher<void>();\n\n private screenBoundsChanged = new EventDispatcher<\n VolumeIntersectionQueryDetails | undefined\n >();\n\n public constructor(private mode?: VolumeIntersectionQueryMode) {}\n\n public setStartPoint(point: Point.Point): void {\n this.startPoint = point;\n\n this.dragStarted.emit();\n }\n\n public setEndPoint(point: Point.Point): void {\n if (\n this.startPoint != null &&\n Point.distance(this.startPoint, point) >= 2\n ) {\n this.endPoint = point;\n\n this.updateQueryType();\n this.screenBoundsChanged.emit(this.getQueryDetails());\n }\n }\n\n public setMode(mode?: VolumeIntersectionQueryMode): void {\n this.mode = mode;\n }\n\n public complete(): void {\n if (this.startPoint != null && this.endPoint != null) {\n this.screenBoundsChanged.emit(undefined);\n this.dragComplete.emit(this.getQueryDetails());\n this.reset();\n }\n }\n\n public cancel(): void {\n this.screenBoundsChanged.emit(undefined);\n this.dragCancelled.emit();\n this.reset();\n }\n\n public reset(): void {\n this.startPoint = undefined;\n this.endPoint = undefined;\n this.type = undefined;\n }\n\n public getScreenBounds(): Rectangle.Rectangle | undefined {\n return this.startPoint != null && this.endPoint != null\n ? Rectangle.fromPoints(this.startPoint, this.endPoint)\n : undefined;\n }\n\n public getType(): QueryType | undefined {\n return this.type;\n }\n\n public onScreenBoundsChanged(\n listener: Listener<VolumeIntersectionQueryDetails | undefined>\n ): Disposable {\n return this.screenBoundsChanged.on(listener);\n }\n\n public onDragStarted(listener: Listener<void>): Disposable {\n return this.dragStarted.on(listener);\n }\n\n public onDragComplete(\n listener: Listener<VolumeIntersectionQueryDetails>\n ): Disposable {\n return this.dragComplete.on(listener);\n }\n\n public onDragCancelled(listener: Listener<void>): Disposable {\n return this.dragCancelled.on(listener);\n }\n\n private getQueryDetails(): VolumeIntersectionQueryDetails {\n if (this.startPoint != null && this.endPoint != null && this.type != null) {\n return {\n screenBounds: Rectangle.fromPoints(this.startPoint, this.endPoint),\n type: this.type,\n };\n } else {\n throw new Error(\n 'Failed to create query details, the start and end points must be set.'\n );\n }\n }\n\n private updateQueryType(): void {\n if (this.startPoint != null && this.endPoint != null) {\n const directionalType =\n Point.subtract(this.endPoint, this.startPoint).x > 0\n ? 'exclusive'\n : 'inclusive';\n\n this.type = this.mode ?? directionalType;\n }\n }\n}\n",":host {\n /**\n * @prop --viewer-box-query-outline-exclusive-color: A CSS color that\n * specifies the color of box for an exclusive query. This will\n * be used in combination with `--viewer-box-query-outline-fill-opacity`\n * for the background color of the box. Defaults to `#0099cc`.\n */\n --viewer-box-query-outline-exclusive-color: #0099cc;\n /**\n * @prop --viewer-box-query-outline-exclusive-border-style: A border\n * style that specifies the type of border to display around the box for an\n * exclusive query. Defaults to `solid`.\n */\n --viewer-box-query-outline-exclusive-border-style: solid;\n /**\n * @prop --viewer-box-query-outline-inclusive-color: A CSS color that\n * specifies the color of box for an inclusive query. This will\n * be used in combination with `--viewer-box-query-outline-fill-opacity`\n * for the background color of the box. Defaults to `#00cc00`.\n */\n --viewer-box-query-outline-inclusive-color: #00cc00;\n /**\n * @prop --viewer-box-query-outline-inclusive-border-style: A border\n * style that specifies the type of border to display around the box for an\n * inclusive query. Defaults to `dashed`.\n */\n --viewer-box-query-outline-inclusive-border-style: dashed;\n /**\n * @prop --viewer-box-query-outline-border-radius: A CSS length that\n * specifies the border radius of the drawn box. Defaults to `0.25rem`.\n */\n --viewer-box-query-outline-border-radius: 0.25rem;\n /**\n * @prop--viewer-box-query-outline-fill-opacity: A number between \n * 0 and 1 that specifies the opacity of the background of the drawn box.\n * Defaults to `0.25`.\n */\n --viewer-box-query-outline-fill-opacity: 0.25;\n}\n\n.bounds {\n position: absolute;\n}\n\n.outline {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n border-radius: var(--viewer-box-query-outline-border-radius);\n}\n\n:host([exclusive=\"true\"]) .outline {\n border: 3px var(--viewer-box-query-outline-exclusive-border-style) var(--viewer-box-query-outline-exclusive-color);\n}\n\n:host([inclusive=\"true\"]) .outline {\n border: 3px var(--viewer-box-query-outline-inclusive-border-style) var(--viewer-box-query-outline-inclusive-color);\n}\n\n.fill {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n opacity: var(--viewer-box-query-outline-fill-opacity);\n border-radius: var(--viewer-box-query-outline-border-radius);\n}\n\n:host([exclusive=\"true\"]) .fill {\n background-color: var(--viewer-box-query-outline-exclusive-color);\n}\n\n:host([inclusive=\"true\"]) .fill {\n background-color: var(--viewer-box-query-outline-inclusive-color);\n}","import { Component, Element, h, Host, Prop, State, Watch } from '@stencil/core';\nimport { Disposable } from '@vertexvis/utils';\n\nimport { VolumeIntersectionQueryController } from '../../lib/volume-intersection/controller';\nimport { VolumeIntersectionQueryInteractionHandler } from '../../lib/volume-intersection/interactions';\nimport {\n QueryType,\n VolumeIntersectionQueryDetails,\n VolumeIntersectionQueryModel,\n} from '../../lib/volume-intersection/model';\nimport {\n VolumeIntersectionQueryMode,\n VolumeIntersectionQueryType,\n} from './types';\n\n/**\n * The `ViewerBoxQueryTool` allows for the drawing of a \"box\" on screen to represent\n * a query for items in a specific area of the viewer. This tool then allows for an\n * operation to be performed on the items contained (exclusive) by the box or both\n * contained by and intersecting with (inclusive) the box.\n */\n@Component({\n tag: 'vertex-viewer-box-query-tool',\n styleUrl: 'viewer-box-query-tool.css',\n shadow: true,\n})\nexport class ViewerBoxQueryTool {\n /**\n * The viewer that this component is bound to. This is automatically assigned\n * if added to the light-dom of a parent viewer element.\n */\n @Prop()\n public viewer?: HTMLVertexViewerElement;\n\n /**\n * The controller that is responsible for performing operations using the\n * volume intersection query defined by the drawn box and updating the model.\n */\n @Prop({ mutable: true })\n public controller?: VolumeIntersectionQueryController;\n\n /**\n * The model that contains the points representing the corners of the box\n * displayed on screen, the type of the query to be performed, and methods\n * for setting these values.\n */\n @Prop({ mutable: true })\n public model?: VolumeIntersectionQueryModel;\n\n /**\n * The default operation to perform when a drag has completed and the intersection\n * query will be run. Defaults to `clearAndSelect`, and can be changed to `select` or `deselect`.\n *\n * `clearAndSelect` will clear all existing selection, and select the results of the query.\n * `select` will maintain existing selection, and select the results of the query.\n * `deselect` will maintain existing selection, and deselect the results of the query.\n *\n * The operation behavior for this intersection query tool can also be changed by\n * providing a custom implementation of the `VolumeIntersectionQueryController`, or\n * by using the `setOperationTransform` method of the default controller.\n */\n @Prop()\n public operationType: VolumeIntersectionQueryType = 'clearAndSelect';\n\n /**\n * An optional value to specify a singular mode of intersection query. This value\n * defaults to `undefined`, which will indicate that both `exclusive` and `inclusive`\n * queries should be made, with `inclusive` being represented by a left to right\n * drag behavior and `exclusive` being represented by a right to left drag.\n *\n * Setting this value to `inclusive` will cause dragging left to right and left to right\n * to result in an `inclusive` query, and the box will only be styled for `inclusive` queries.\n *\n * Setting this value to `exclusive` will cause dragging left to right and left to right\n * to result in an `exclusive` query, and the box will only be styled for `exclusive` queries.\n */\n @Prop()\n public mode?: VolumeIntersectionQueryMode;\n\n @State()\n private details?: VolumeIntersectionQueryDetails;\n\n @Element()\n private hostEl!: HTMLVertexViewerBoxQueryToolElement;\n\n private interactionHandler?: VolumeIntersectionQueryInteractionHandler;\n private interactionHandlerDisposable?: Disposable;\n\n private operationStartedDisposable?: Disposable;\n private operationCompleteDisposable?: Disposable;\n private screenBoundsChangedDisposable?: Disposable;\n\n public constructor() {\n this.handleScreenBoundsChanged = this.handleScreenBoundsChanged.bind(this);\n this.handleExecuteStarted = this.handleExecuteStarted.bind(this);\n this.handleExecuteComplete = this.handleExecuteComplete.bind(this);\n }\n\n public componentWillLoad(): void {\n this.model = this.model ?? new VolumeIntersectionQueryModel(this.mode);\n\n this.screenBoundsChangedDisposable = this.model.onScreenBoundsChanged(\n this.handleScreenBoundsChanged\n );\n\n this.handleViewerChanged(this.viewer);\n this.handleControllerChange(this.controller);\n this.handleDefaultOperationChange(this.operationType);\n }\n\n public disconnectedCallback(): void {\n this.model?.reset();\n this.screenBoundsChangedDisposable?.dispose();\n this.operationStartedDisposable?.dispose();\n this.operationCompleteDisposable?.dispose();\n this.deregisterInteractionHandler();\n }\n\n /**\n * @ignore\n */\n @Watch('viewer')\n protected handleViewerChanged(newViewer?: HTMLVertexViewerElement): void {\n this.deregisterInteractionHandler();\n\n if (this.model != null && newViewer != null) {\n this.controller = new VolumeIntersectionQueryController(\n this.model,\n newViewer\n );\n this.handleDefaultOperationChange(this.operationType);\n this.registerInteractionHandler(this.controller, newViewer);\n }\n }\n\n /**\n * @ignore\n */\n @Watch('operationType')\n protected handleDefaultOperationChange(\n updatedOperationType: VolumeIntersectionQueryType\n ): void {\n switch (updatedOperationType) {\n case 'clearAndSelect':\n this.setDefaultClearAndSelectOperation();\n break;\n case 'select':\n this.setDefaultSelectOperation();\n break;\n case 'deselect':\n this.setDefaultDeselectOperation();\n break;\n }\n }\n\n /**\n * @ignore\n */\n @Watch('mode')\n protected handleModeChange(updatedMode?: VolumeIntersectionQueryMode): void {\n this.model?.setMode(updatedMode);\n }\n\n /**\n * @ignore\n */\n @Watch('controller')\n protected handleControllerChange(\n controller?: VolumeIntersectionQueryController\n ): void {\n this.operationStartedDisposable?.dispose();\n this.operationCompleteDisposable?.dispose();\n\n this.operationStartedDisposable = controller?.onExecuteStarted(\n this.handleExecuteStarted\n );\n this.operationStartedDisposable = controller?.onExecuteComplete(\n this.handleExecuteComplete\n );\n }\n\n /**\n * @ignore\n */\n protected render(): h.JSX.IntrinsicElements {\n return (\n <Host>\n <vertex-viewer-layer>\n {this.details != null && (\n <div\n class=\"bounds\"\n style={{\n left: `${this.details.screenBounds.x}px`,\n top: `${this.details.screenBounds.y}px`,\n width: `${this.details.screenBounds.width}px`,\n height: `${this.details.screenBounds.height}px`,\n }}\n >\n <slot name=\"bounds\">\n <div class=\"outline\"></div>\n <div class=\"fill\"></div>\n </slot>\n </div>\n )}\n </vertex-viewer-layer>\n </Host>\n );\n }\n\n private handleScreenBoundsChanged(\n details?: VolumeIntersectionQueryDetails\n ): void {\n this.details = details;\n\n this.updateTypeAttribute(details?.type);\n }\n\n private handleExecuteStarted(): void {\n this.interactionHandler?.disable();\n }\n\n private handleExecuteComplete(): void {\n this.interactionHandler?.enable();\n }\n\n private async registerInteractionHandler(\n controller: VolumeIntersectionQueryController,\n viewer: HTMLVertexViewerElement\n ): Promise<void> {\n this.interactionHandler = new VolumeIntersectionQueryInteractionHandler(\n controller\n );\n this.interactionHandlerDisposable = await viewer.registerInteractionHandler(\n this.interactionHandler\n );\n }\n\n private deregisterInteractionHandler(): void {\n this.interactionHandlerDisposable?.dispose();\n this.interactionHandler?.dispose();\n this.interactionHandler = undefined;\n }\n\n private updateTypeAttribute(type?: QueryType): void {\n this.hostEl.setAttribute('inclusive', `${type === 'inclusive'}`);\n this.hostEl.setAttribute('exclusive', `${type === 'exclusive'}`);\n }\n\n private setDefaultClearAndSelectOperation(): void {\n this.controller?.setOperationTransform((builder) => builder.select());\n this.controller?.setAdditionalTransforms([\n (op) => op.where((q) => q.withSelected()).deselect(),\n ]);\n }\n\n private setDefaultSelectOperation(): void {\n this.controller?.setOperationTransform((builder) => builder.select());\n this.controller?.setAdditionalTransforms([]);\n }\n\n private setDefaultDeselectOperation(): void {\n this.controller?.setOperationTransform((builder) => builder.deselect());\n this.controller?.setAdditionalTransforms([]);\n }\n}\n"],"version":3}
1
+ {"file":"vertex-viewer-box-query-tool.entry.cjs.js","mappings":"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","names":["getMouseClientPosition","boxQueryCursor","VolumeIntersectionQueryModel","VolumeIntersectionQueryController","h","Host"],"sources":["./src/lib/volume-intersection/interactions.ts","./src/components/viewer-box-query-tool/viewer-box-query-tool.css?tag=vertex-viewer-box-query-tool&encapsulation=shadow","./src/components/viewer-box-query-tool/viewer-box-query-tool.tsx"],"sourcesContent":["import { Disposable } from '@vertexvis/utils';\n\nimport { boxQueryCursor } from '../cursors';\nimport { getMouseClientPosition } from '../dom';\nimport { InteractionApi } from '../interactions';\nimport { InteractionHandler } from '../interactions/interactionHandler';\nimport { VolumeIntersectionQueryController } from './controller';\n\nexport class VolumeIntersectionQueryInteractionHandler\n implements InteractionHandler\n{\n private element?: HTMLElement;\n private api?: InteractionApi;\n private isInteracting?: boolean;\n private enabled?: boolean;\n private elementBounds?: DOMRect;\n private crosshairCursorDisposable?: Disposable;\n private waitCursorDisposable?: Disposable;\n\n public constructor(private controller: VolumeIntersectionQueryController) {\n this.handleDragBegin = this.handleDragBegin.bind(this);\n this.handleDrag = this.handleDrag.bind(this);\n this.handleDragEnd = this.handleDragEnd.bind(this);\n\n this.enabled = true;\n }\n\n public initialize(element: HTMLElement, api: InteractionApi): void {\n this.element = element;\n this.api = api;\n\n this.element.addEventListener('pointerdown', this.handleDragBegin);\n this.addCrosshairCursor();\n }\n\n public dispose(): void {\n this.element?.removeEventListener('pointerdown', this.handleDragBegin);\n window.removeEventListener('pointermove', this.handleDrag);\n window.removeEventListener('pointerup', this.handleDragEnd);\n this.crosshairCursorDisposable?.dispose();\n this.waitCursorDisposable?.dispose();\n\n this.element = undefined;\n this.api = undefined;\n this.enabled = true;\n }\n\n public disable(): void {\n this.enabled = false;\n }\n\n public enable(): void {\n this.enabled = true;\n }\n\n private handleDragBegin(event: PointerEvent): void {\n if (\n this.enabled &&\n this.isPrimaryMouseButtonClick(event) &&\n !this.isInteracting\n ) {\n this.elementBounds = this.element?.getBoundingClientRect();\n this.isInteracting = true;\n this.controller.setStartPoint(\n getMouseClientPosition(event, this.elementBounds)\n );\n\n window.addEventListener('pointermove', this.handleDrag);\n window.addEventListener('pointerup', this.handleDragEnd);\n }\n }\n\n private handleDrag(event: PointerEvent): void {\n if (this.enabled) {\n this.controller.setEndPoint(\n getMouseClientPosition(event, this.elementBounds)\n );\n }\n }\n\n private async handleDragEnd(): Promise<void> {\n this.isInteracting = false;\n\n window.removeEventListener('pointermove', this.handleDrag);\n window.removeEventListener('pointerup', this.handleDragEnd);\n\n this.crosshairCursorDisposable?.dispose();\n if (this.enabled) {\n this.addWaitCursor();\n try {\n await this.controller.execute();\n } finally {\n this.waitCursorDisposable?.dispose();\n this.addCrosshairCursor();\n }\n }\n }\n\n private isPrimaryMouseButtonClick(event: PointerEvent): boolean {\n return event.buttons === 1;\n }\n\n private addCrosshairCursor(): void {\n this.crosshairCursorDisposable?.dispose();\n this.crosshairCursorDisposable = this.api?.addCursor(boxQueryCursor);\n }\n\n private addWaitCursor(): void {\n this.waitCursorDisposable?.dispose();\n this.waitCursorDisposable = this.api?.addCursor('wait');\n }\n}\n",":host {\n /**\n * @prop --viewer-box-query-outline-exclusive-color: A CSS color that\n * specifies the color of box for an exclusive query. This will\n * be used in combination with `--viewer-box-query-outline-fill-opacity`\n * for the background color of the box. Defaults to `#0099cc`.\n */\n --viewer-box-query-outline-exclusive-color: #0099cc;\n /**\n * @prop --viewer-box-query-outline-exclusive-border-style: A border\n * style that specifies the type of border to display around the box for an\n * exclusive query. Defaults to `solid`.\n */\n --viewer-box-query-outline-exclusive-border-style: solid;\n /**\n * @prop --viewer-box-query-outline-inclusive-color: A CSS color that\n * specifies the color of box for an inclusive query. This will\n * be used in combination with `--viewer-box-query-outline-fill-opacity`\n * for the background color of the box. Defaults to `#00cc00`.\n */\n --viewer-box-query-outline-inclusive-color: #00cc00;\n /**\n * @prop --viewer-box-query-outline-inclusive-border-style: A border\n * style that specifies the type of border to display around the box for an\n * inclusive query. Defaults to `dashed`.\n */\n --viewer-box-query-outline-inclusive-border-style: dashed;\n /**\n * @prop --viewer-box-query-outline-border-radius: A CSS length that\n * specifies the border radius of the drawn box. Defaults to `0.25rem`.\n */\n --viewer-box-query-outline-border-radius: 0.25rem;\n /**\n * @prop--viewer-box-query-outline-fill-opacity: A number between \n * 0 and 1 that specifies the opacity of the background of the drawn box.\n * Defaults to `0.25`.\n */\n --viewer-box-query-outline-fill-opacity: 0.25;\n}\n\n.bounds {\n position: absolute;\n}\n\n.outline {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n box-sizing: border-box;\n border-radius: var(--viewer-box-query-outline-border-radius);\n}\n\n:host([exclusive=\"true\"]) .outline {\n border: 3px var(--viewer-box-query-outline-exclusive-border-style) var(--viewer-box-query-outline-exclusive-color);\n}\n\n:host([inclusive=\"true\"]) .outline {\n border: 3px var(--viewer-box-query-outline-inclusive-border-style) var(--viewer-box-query-outline-inclusive-color);\n}\n\n.fill {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n opacity: var(--viewer-box-query-outline-fill-opacity);\n border-radius: var(--viewer-box-query-outline-border-radius);\n}\n\n:host([exclusive=\"true\"]) .fill {\n background-color: var(--viewer-box-query-outline-exclusive-color);\n}\n\n:host([inclusive=\"true\"]) .fill {\n background-color: var(--viewer-box-query-outline-inclusive-color);\n}","import {\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Host,\n Prop,\n State,\n Watch,\n} from '@stencil/core';\nimport { Disposable } from '@vertexvis/utils';\n\nimport { VolumeIntersectionQueryController } from '../../lib/volume-intersection/controller';\nimport { VolumeIntersectionQueryInteractionHandler } from '../../lib/volume-intersection/interactions';\nimport {\n QueryType,\n VolumeIntersectionQueryDetails,\n VolumeIntersectionQueryModel,\n} from '../../lib/volume-intersection/model';\nimport {\n VolumeIntersectionQueryMode,\n VolumeIntersectionQueryType,\n} from './types';\n\n/**\n * The `ViewerBoxQueryTool` allows for the drawing of a \"box\" on screen to represent\n * a query for items in a specific area of the viewer. This tool then allows for an\n * operation to be performed on the items contained (exclusive) by the box or both\n * contained by and intersecting with (inclusive) the box.\n */\n@Component({\n tag: 'vertex-viewer-box-query-tool',\n styleUrl: 'viewer-box-query-tool.css',\n shadow: true,\n})\nexport class ViewerBoxQueryTool {\n /**\n * The viewer that this component is bound to. This is automatically assigned\n * if added to the light-dom of a parent viewer element.\n */\n @Prop()\n public viewer?: HTMLVertexViewerElement;\n\n /**\n * The controller that is responsible for performing operations using the\n * volume intersection query defined by the drawn box and updating the model.\n */\n @Prop({ mutable: true })\n public controller?: VolumeIntersectionQueryController;\n\n /**\n * The model that contains the points representing the corners of the box\n * displayed on screen, the type of the query to be performed, and methods\n * for setting these values.\n */\n @Prop({ mutable: true })\n public model?: VolumeIntersectionQueryModel;\n\n /**\n * The default operation to perform when a drag has completed and the intersection\n * query will be run. Defaults to `clearAndSelect`, and can be changed to `select` or `deselect`.\n *\n * `clearAndSelect` will clear all existing selection, and select the results of the query.\n * `select` will maintain existing selection, and select the results of the query.\n * `deselect` will maintain existing selection, and deselect the results of the query.\n *\n * The operation behavior for this intersection query tool can also be changed by\n * providing a custom implementation of the `VolumeIntersectionQueryController`, or\n * by using the `setOperationTransform` method of the default controller.\n */\n @Prop()\n public operationType: VolumeIntersectionQueryType = 'clearAndSelect';\n\n /**\n * An optional value to specify a singular mode of intersection query. This value\n * defaults to `undefined`, which will indicate that both `exclusive` and `inclusive`\n * queries should be made, with `inclusive` being represented by a left to right\n * drag behavior and `exclusive` being represented by a right to left drag.\n *\n * Setting this value to `inclusive` will cause dragging left to right and left to right\n * to result in an `inclusive` query, and the box will only be styled for `inclusive` queries.\n *\n * Setting this value to `exclusive` will cause dragging left to right and left to right\n * to result in an `exclusive` query, and the box will only be styled for `exclusive` queries.\n */\n @Prop()\n public mode?: VolumeIntersectionQueryMode;\n\n @State()\n private details?: VolumeIntersectionQueryDetails;\n\n /**\n * Event emitted when the `VolumeIntersectionQueryController` associated with this tool changes.\n */\n @Event()\n public controllerChanged!: EventEmitter<VolumeIntersectionQueryController>;\n\n @Element()\n private hostEl!: HTMLVertexViewerBoxQueryToolElement;\n\n private interactionHandler?: VolumeIntersectionQueryInteractionHandler;\n private interactionHandlerDisposable?: Disposable;\n\n private operationStartedDisposable?: Disposable;\n private operationCompleteDisposable?: Disposable;\n private screenBoundsChangedDisposable?: Disposable;\n\n public constructor() {\n this.handleScreenBoundsChanged = this.handleScreenBoundsChanged.bind(this);\n this.handleExecuteStarted = this.handleExecuteStarted.bind(this);\n this.handleExecuteComplete = this.handleExecuteComplete.bind(this);\n }\n\n public componentWillLoad(): void {\n this.model = this.model ?? new VolumeIntersectionQueryModel(this.mode);\n\n this.screenBoundsChangedDisposable = this.model.onScreenBoundsChanged(\n this.handleScreenBoundsChanged\n );\n\n this.handleViewerChanged(this.viewer);\n this.handleControllerChange(this.controller);\n this.handleDefaultOperationChange(this.operationType);\n }\n\n public disconnectedCallback(): void {\n this.model?.reset();\n this.screenBoundsChangedDisposable?.dispose();\n this.operationStartedDisposable?.dispose();\n this.operationCompleteDisposable?.dispose();\n this.deregisterInteractionHandler();\n }\n\n /**\n * @ignore\n */\n @Watch('viewer')\n protected handleViewerChanged(newViewer?: HTMLVertexViewerElement): void {\n this.deregisterInteractionHandler();\n\n if (this.model != null && newViewer != null) {\n this.controller = new VolumeIntersectionQueryController(\n this.model,\n newViewer\n );\n this.handleDefaultOperationChange(this.operationType);\n this.registerInteractionHandler(this.controller, newViewer);\n }\n }\n\n /**\n * @ignore\n */\n @Watch('operationType')\n protected handleDefaultOperationChange(\n updatedOperationType: VolumeIntersectionQueryType\n ): void {\n switch (updatedOperationType) {\n case 'clearAndSelect':\n this.setDefaultClearAndSelectOperation();\n break;\n case 'select':\n this.setDefaultSelectOperation();\n break;\n case 'deselect':\n this.setDefaultDeselectOperation();\n break;\n }\n }\n\n /**\n * @ignore\n */\n @Watch('mode')\n protected handleModeChange(updatedMode?: VolumeIntersectionQueryMode): void {\n this.model?.setMode(updatedMode);\n }\n\n /**\n * @ignore\n */\n @Watch('controller')\n protected handleControllerChange(\n controller?: VolumeIntersectionQueryController\n ): void {\n this.operationStartedDisposable?.dispose();\n this.operationCompleteDisposable?.dispose();\n\n this.operationStartedDisposable = controller?.onExecuteStarted(\n this.handleExecuteStarted\n );\n this.operationStartedDisposable = controller?.onExecuteComplete(\n this.handleExecuteComplete\n );\n\n this.controllerChanged.emit(this.controller);\n }\n\n /**\n * @ignore\n */\n protected render(): h.JSX.IntrinsicElements {\n return (\n <Host>\n <vertex-viewer-layer>\n {this.details != null && (\n <div\n class=\"bounds\"\n style={{\n left: `${this.details.screenBounds.x}px`,\n top: `${this.details.screenBounds.y}px`,\n width: `${this.details.screenBounds.width}px`,\n height: `${this.details.screenBounds.height}px`,\n }}\n >\n <slot name=\"bounds\">\n <div class=\"outline\"></div>\n <div class=\"fill\"></div>\n </slot>\n </div>\n )}\n </vertex-viewer-layer>\n </Host>\n );\n }\n\n private handleScreenBoundsChanged(\n details?: VolumeIntersectionQueryDetails\n ): void {\n this.details = details;\n\n this.updateTypeAttribute(details?.type);\n }\n\n private handleExecuteStarted(): void {\n this.interactionHandler?.disable();\n }\n\n private handleExecuteComplete(): void {\n this.interactionHandler?.enable();\n }\n\n private async registerInteractionHandler(\n controller: VolumeIntersectionQueryController,\n viewer: HTMLVertexViewerElement\n ): Promise<void> {\n this.interactionHandler = new VolumeIntersectionQueryInteractionHandler(\n controller\n );\n this.interactionHandlerDisposable = await viewer.registerInteractionHandler(\n this.interactionHandler\n );\n }\n\n private deregisterInteractionHandler(): void {\n this.interactionHandlerDisposable?.dispose();\n this.interactionHandler?.dispose();\n this.interactionHandler = undefined;\n }\n\n private updateTypeAttribute(type?: QueryType): void {\n this.hostEl.setAttribute('inclusive', `${type === 'inclusive'}`);\n this.hostEl.setAttribute('exclusive', `${type === 'exclusive'}`);\n }\n\n private setDefaultClearAndSelectOperation(): void {\n this.controller?.setOperationTransform((builder) => builder.select());\n this.controller?.setAdditionalTransforms([\n (op) => op.where((q) => q.withSelected()).deselect(),\n ]);\n }\n\n private setDefaultSelectOperation(): void {\n this.controller?.setOperationTransform((builder) => builder.select());\n this.controller?.setAdditionalTransforms([]);\n }\n\n private setDefaultDeselectOperation(): void {\n this.controller?.setOperationTransform((builder) => builder.deselect());\n this.controller?.setAdditionalTransforms([]);\n }\n}\n"],"version":3}
@@ -1494,7 +1494,15 @@ class MouseInteractionHandler extends BaseInteractionHandler {
1494
1494
  }
1495
1495
  }
1496
1496
 
1497
+ function requestAnimationFrame(callback) {
1498
+ window.requestAnimationFrame(callback);
1499
+ }
1500
+
1497
1501
  class MultiTouchInteractionHandler {
1502
+ constructor() {
1503
+ this.previousFirstPoints = [];
1504
+ this.previousSecondPoints = [];
1505
+ }
1498
1506
  initialize(element, api) {
1499
1507
  this.element = element;
1500
1508
  this.interactionApi = api;
@@ -1502,26 +1510,83 @@ class MultiTouchInteractionHandler {
1502
1510
  dispose() {
1503
1511
  this.element = undefined;
1504
1512
  }
1513
+ beginTwoPointTouch(point1, point2) {
1514
+ this.previousFirstPoints = [...this.previousFirstPoints, point1];
1515
+ this.previousSecondPoints = [...this.previousSecondPoints, point2];
1516
+ }
1505
1517
  handleTwoPointTouchMove(point1, point2) {
1506
- var _a, _b, _c, _d;
1507
- if (this.currentPosition1 != null && this.currentPosition2 != null) {
1508
- const delta = bundle_esm.point.add(bundle_esm.point.subtract(point1, this.currentPosition1), bundle_esm.point.subtract(point2, this.currentPosition2));
1509
- const distance = bundle_esm.point.distance(point1, point2) -
1510
- bundle_esm.point.distance(this.currentPosition1, this.currentPosition2);
1511
- const zoom = distance * 0.5;
1512
- const previousToCurrent = bundle_esm.matrix2.create(bundle_esm.point.subtract(this.currentPosition1, this.currentPosition2), bundle_esm.point.subtract(point1, point2));
1513
- const angle = bundle_esm.angle.toDegrees(Math.atan2(bundle_esm.matrix2.determinant(previousToCurrent), bundle_esm.matrix2.dot(previousToCurrent)));
1514
- const center = bundle_esm.point.create((point1.x + point2.x) / 2, (point1.y + point2.y) / 2);
1515
- (_a = this.interactionApi) === null || _a === void 0 ? void 0 : _a.beginInteraction();
1516
- (_b = this.interactionApi) === null || _b === void 0 ? void 0 : _b.zoomCameraToPoint(center, zoom);
1517
- (_c = this.interactionApi) === null || _c === void 0 ? void 0 : _c.panCameraByDelta(delta);
1518
- // Setting a minimum angle to prevent wobbling
1519
- if (Math.abs(angle) > 0.5) {
1518
+ this.previousFirstPoints = [...this.previousFirstPoints, point1];
1519
+ this.previousSecondPoints = [...this.previousSecondPoints, point2];
1520
+ // Process updates to touch points on animation frame callbacks to batch
1521
+ // the processing. Because each event can potentially only represent a single
1522
+ // touch point moving, two opposing angles can be computed sequentially. This
1523
+ // results in a wobbling effect if those angles are both sent, and this batched
1524
+ // processing helps to reduce that effect.
1525
+ requestAnimationFrame(() => {
1526
+ var _a, _b, _c, _d;
1527
+ if (this.previousFirstPoints.length > 1 &&
1528
+ this.previousSecondPoints.length > 1 &&
1529
+ this.previousFirstPoints.length === this.previousSecondPoints.length) {
1530
+ const previousFirstPoints = this.previousFirstPoints;
1531
+ const previousSecondPoints = this.previousSecondPoints;
1532
+ this.previousFirstPoints = this.previousFirstPoints.slice(-1);
1533
+ this.previousSecondPoints = this.previousSecondPoints.slice(-1);
1534
+ const changes = previousFirstPoints.reduce((result, previousFirstPoint, i) => {
1535
+ if (i < previousFirstPoints.length - 1) {
1536
+ const firstPoint = previousFirstPoints[i + 1];
1537
+ const previousSecondPoint = previousSecondPoints[i];
1538
+ const secondPoint = previousSecondPoints[i + 1];
1539
+ return {
1540
+ deltas: [
1541
+ ...result.deltas,
1542
+ this.computeDelta(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
1543
+ ],
1544
+ zooms: [
1545
+ ...result.zooms,
1546
+ this.computeZoom(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
1547
+ ],
1548
+ angles: [
1549
+ ...result.angles,
1550
+ this.computeAngle(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
1551
+ ],
1552
+ };
1553
+ }
1554
+ return result;
1555
+ }, {
1556
+ deltas: [],
1557
+ zooms: [],
1558
+ angles: [],
1559
+ });
1560
+ const delta = changes.deltas.reduce((r, d) => bundle_esm.point.add(r, d), bundle_esm.point.create());
1561
+ const zoom = changes.zooms.reduce((z, d) => z + d, 0);
1562
+ const angle = changes.angles.reduce((a, d) => a + d, 0);
1563
+ const center = bundle_esm.point.create((previousFirstPoints[previousFirstPoints.length - 1].x +
1564
+ previousSecondPoints[previousSecondPoints.length - 1].x) /
1565
+ 2, (previousFirstPoints[previousFirstPoints.length - 1].y +
1566
+ previousSecondPoints[previousSecondPoints.length - 1].y) /
1567
+ 2);
1568
+ (_a = this.interactionApi) === null || _a === void 0 ? void 0 : _a.beginInteraction();
1569
+ (_b = this.interactionApi) === null || _b === void 0 ? void 0 : _b.zoomCameraToPoint(center, zoom);
1570
+ (_c = this.interactionApi) === null || _c === void 0 ? void 0 : _c.panCameraByDelta(delta);
1520
1571
  (_d = this.interactionApi) === null || _d === void 0 ? void 0 : _d.twistCamera(angle);
1521
1572
  }
1522
- }
1523
- this.currentPosition1 = point1;
1524
- this.currentPosition2 = point2;
1573
+ });
1574
+ }
1575
+ endTwoPointTouch() {
1576
+ this.previousFirstPoints = [];
1577
+ this.previousSecondPoints = [];
1578
+ }
1579
+ computeDelta(previousPoint1, previousPoint2, point1, point2) {
1580
+ return bundle_esm.point.add(bundle_esm.point.subtract(point1, previousPoint1), bundle_esm.point.subtract(point2, previousPoint2));
1581
+ }
1582
+ computeZoom(previousPoint1, previousPoint2, point1, point2) {
1583
+ const distance = bundle_esm.point.distance(point1, point2) -
1584
+ bundle_esm.point.distance(previousPoint1, previousPoint2);
1585
+ return distance * 0.5;
1586
+ }
1587
+ computeAngle(previousPoint1, previousPoint2, point1, point2) {
1588
+ const previousToCurrent = bundle_esm.matrix2.create(bundle_esm.point.subtract(previousPoint1, previousPoint2), bundle_esm.point.subtract(point1, point2));
1589
+ return bundle_esm.angle.toDegrees(Math.atan2(bundle_esm.matrix2.determinant(previousToCurrent), bundle_esm.matrix2.dot(previousToCurrent)));
1525
1590
  }
1526
1591
  }
1527
1592
 
@@ -1550,6 +1615,9 @@ class MultiPointerInteractionHandler extends MultiTouchInteractionHandler {
1550
1615
  window.addEventListener('pointermove', this.handlePointerMove);
1551
1616
  window.addEventListener('pointerup', this.handlePointerUp);
1552
1617
  }
1618
+ else if (keys.length === 2) {
1619
+ this.beginTwoPointTouch(this.touchPoints[0], this.touchPoints[1]);
1620
+ }
1553
1621
  }
1554
1622
  handlePointerMove(event) {
1555
1623
  if (this.touchPoints[event.pointerId] != null) {
@@ -1568,13 +1636,12 @@ class MultiPointerInteractionHandler extends MultiTouchInteractionHandler {
1568
1636
  const keys = Object.keys(this.touchPoints);
1569
1637
  if (keys.length === 1) {
1570
1638
  (_a = this.interactionApi) === null || _a === void 0 ? void 0 : _a.endInteraction();
1571
- this.currentPosition1 = undefined;
1572
- this.currentPosition2 = undefined;
1573
1639
  }
1574
1640
  if (keys.length === 0) {
1575
1641
  window.removeEventListener('pointermove', this.handlePointerMove);
1576
1642
  window.removeEventListener('pointerup', this.handlePointerUp);
1577
1643
  }
1644
+ this.endTwoPointTouch();
1578
1645
  }
1579
1646
  }
1580
1647
 
@@ -1837,12 +1904,10 @@ class TouchInteractionHandler extends MultiTouchInteractionHandler {
1837
1904
  if (event.touches.length >= 1) {
1838
1905
  event.preventDefault();
1839
1906
  const touch1 = event.touches[0];
1840
- const touch2 = event.touches[1];
1841
1907
  this.currentPosition1 = bundle_esm.point.create(touch1.screenX, touch1.screenY);
1842
- this.currentPosition2 =
1843
- touch2 != null
1844
- ? bundle_esm.point.create(touch2.screenX, touch2.screenY)
1845
- : undefined;
1908
+ if (event.touches[1] != null) {
1909
+ this.beginTwoPointTouch(this.currentPosition1, bundle_esm.point.create(event.touches[1].screenX, event.touches[1].screenY));
1910
+ }
1846
1911
  window.addEventListener('touchmove', this.handleTouchMove, {
1847
1912
  passive: false,
1848
1913
  });
@@ -1867,6 +1932,7 @@ class TouchInteractionHandler extends MultiTouchInteractionHandler {
1867
1932
  this.isInteracting = false;
1868
1933
  window.removeEventListener('touchmove', this.handleTouchMove);
1869
1934
  window.removeEventListener('touchend', this.handleTouchEnd);
1935
+ this.endTwoPointTouch();
1870
1936
  }
1871
1937
  handleOnePointTouchMove(touch) {
1872
1938
  var _a, _b, _c;