@vertexvis/viewer 0.20.1-testing.0 → 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.
- package/dist/cjs/index.cjs.js +3 -2
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/cjs/{controller-0155a10a.js → model-2105e63b.js} +85 -1
- package/dist/cjs/model-2105e63b.js.map +1 -0
- package/dist/cjs/vertex-viewer-box-query-tool.cjs.entry.js +7 -87
- package/dist/cjs/vertex-viewer-box-query-tool.cjs.entry.js.map +1 -1
- package/dist/cjs/vertex-viewer.cjs.entry.js +90 -24
- package/dist/cjs/vertex-viewer.cjs.entry.js.map +1 -1
- package/dist/collection/components/viewer-box-query-tool/viewer-box-query-tool.js +23 -1
- package/dist/collection/components/viewer-box-query-tool/viewer-box-query-tool.js.map +1 -1
- package/dist/collection/lib/interactions/multiPointerInteractionHandler.js +4 -2
- package/dist/collection/lib/interactions/multiPointerInteractionHandler.js.map +1 -1
- package/dist/collection/lib/interactions/multiTouchInteractionHandler.js +79 -17
- package/dist/collection/lib/interactions/multiTouchInteractionHandler.js.map +1 -1
- package/dist/collection/lib/interactions/touchInteractionHandler.js +4 -5
- package/dist/collection/lib/interactions/touchInteractionHandler.js.map +1 -1
- package/dist/collection/lib/volume-intersection/index.js +1 -0
- package/dist/collection/lib/volume-intersection/index.js.map +1 -1
- package/dist/collection/lib/window.js +7 -0
- package/dist/collection/lib/window.js.map +1 -0
- package/dist/components/index.js +1 -1
- package/dist/components/model2.js +165 -128
- package/dist/components/model2.js.map +1 -1
- package/dist/components/model3.js +157 -0
- package/dist/components/model3.js.map +1 -0
- package/dist/components/vertex-viewer-box-query-tool.js +4 -86
- package/dist/components/vertex-viewer-box-query-tool.js.map +1 -1
- package/dist/components/vertex-viewer-pin-tool.js +1 -1
- package/dist/components/vertex-viewer.js +91 -25
- package/dist/components/vertex-viewer.js.map +1 -1
- package/dist/components/viewer-pin-group.js +1 -1
- package/dist/components/viewer-pin-label-line.js +1 -1
- package/dist/components/viewer-pin-label.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/{controller-f0d7a836.js → model-4ba9fc30.js} +85 -2
- package/dist/esm/model-4ba9fc30.js.map +1 -0
- package/dist/esm/vertex-viewer-box-query-tool.entry.js +6 -86
- package/dist/esm/vertex-viewer-box-query-tool.entry.js.map +1 -1
- package/dist/esm/vertex-viewer.entry.js +91 -25
- package/dist/esm/vertex-viewer.entry.js.map +1 -1
- package/dist/types/components/viewer-box-query-tool/viewer-box-query-tool.d.ts +5 -1
- package/dist/types/components.d.ts +8 -0
- package/dist/types/lib/interactions/multiTouchInteractionHandler.d.ts +7 -2
- package/dist/types/lib/interactions/touchInteractionHandler.d.ts +1 -0
- package/dist/types/lib/volume-intersection/index.d.ts +1 -0
- package/dist/types/lib/window.d.ts +1 -0
- package/dist/viewer/index.esm.js +1 -1
- package/dist/viewer/index.esm.js.map +1 -1
- package/dist/viewer/p-12a301e0.entry.js +5 -0
- package/dist/viewer/p-12a301e0.entry.js.map +1 -0
- package/dist/viewer/p-4c4019b2.entry.js +5 -0
- package/dist/viewer/p-4c4019b2.entry.js.map +1 -0
- package/dist/viewer/p-ee0c9d33.js +5 -0
- package/dist/viewer/p-ee0c9d33.js.map +1 -0
- package/dist/viewer/viewer.esm.js +1 -1
- package/package.json +7 -7
- package/readme.md +4 -4
- package/dist/cjs/controller-0155a10a.js.map +0 -1
- package/dist/components/controller3.js +0 -111
- package/dist/components/controller3.js.map +0 -1
- package/dist/esm/controller-f0d7a836.js.map +0 -1
- package/dist/viewer/p-b50678f0.js +0 -5
- package/dist/viewer/p-b50678f0.js.map +0 -1
- package/dist/viewer/p-c6e12cf7.entry.js +0 -5
- package/dist/viewer/p-c6e12cf7.entry.js.map +0 -1
- package/dist/viewer/p-cfa05845.entry.js +0 -5
- package/dist/viewer/p-cfa05845.entry.js.map +0 -1
|
@@ -11,7 +11,7 @@ import './streamAttributes.js';
|
|
|
11
11
|
import { V as Viewport } from './viewport.js';
|
|
12
12
|
import './representation_pb.js';
|
|
13
13
|
import { P as PinController, t as translatePointToScreen, d as defineCustomElement$2 } from './viewer-pin-label.js';
|
|
14
|
-
import { g as getPinColors, i as isTextPin, a as isIconPin, P as PinModel } from './
|
|
14
|
+
import { g as getPinColors, i as isTextPin, a as isIconPin, P as PinModel } from './model3.js';
|
|
15
15
|
import { c as classnames } from './index2.js';
|
|
16
16
|
import { d as defineCustomElement$4 } from './viewer-dom-element.js';
|
|
17
17
|
import { d as defineCustomElement$3 } from './viewer-icon.js';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2024 Vertex Software LLC. All rights reserved.
|
|
3
3
|
*/
|
|
4
4
|
import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
|
|
5
|
-
import { g as getPinColors } from './
|
|
5
|
+
import { g as getPinColors } from './model3.js';
|
|
6
6
|
|
|
7
7
|
const viewerPinLabelLineCss = ":host{--viewer-annotations-pin-label-line-color:var(--viewer-annotations-pin-primary-color);--viewer-annotations-pin-label-line-width:1\n\n overflow: hidden;pointer-events:none}.label-line{pointer-events:auto;stroke:var(--viewer-annotations-pin-label-line-color);stroke-width:var( --viewer-annotations-pin-label-line-width);cursor:default}.svg{position:absolute;top:0;bottom:0;left:0;right:0;overflow:hidden;pointer-events:none;height:100%;width:100%}";
|
|
8
8
|
|
|
@@ -5,7 +5,7 @@ import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/
|
|
|
5
5
|
import { p as point, d as dimensions } from './bundle.esm.js';
|
|
6
6
|
import { c as classnames } from './index2.js';
|
|
7
7
|
import { g as getMouseClientPosition } from './dom.js';
|
|
8
|
-
import { P as PinModel, g as getPinColors, i as isTextPin } from './
|
|
8
|
+
import { P as PinModel, g as getPinColors, i as isTextPin } from './model3.js';
|
|
9
9
|
import { r as readDOM } from './stencil.js';
|
|
10
10
|
import { r as range } from './browser.esm.js';
|
|
11
11
|
|
package/dist/esm/index.js
CHANGED
|
@@ -15,7 +15,7 @@ export { A as AngleUnits, g as AreaUnits, c as CrossSectioning, D as DistanceUni
|
|
|
15
15
|
export { E as EntityType } from './entities-0a248a42.js';
|
|
16
16
|
export { A as ArrowMarkup, C as CircleMarkup, F as FreeformMarkup } from './markup-de28aeff.js';
|
|
17
17
|
export { V as Viewport } from './viewport-4ab005ad.js';
|
|
18
|
-
export { V as VolumeIntersectionQueryController } from './
|
|
18
|
+
export { V as VolumeIntersectionQueryController, a as VolumeIntersectionQueryModel } from './model-4ba9fc30.js';
|
|
19
19
|
import './browser.esm-e0ef86ec.js';
|
|
20
20
|
import './errors-3ffaf550.js';
|
|
21
21
|
import './representation_pb-efee7a8e.js';
|
package/dist/esm/index.mjs
CHANGED
|
@@ -15,7 +15,7 @@ export { A as AngleUnits, g as AreaUnits, c as CrossSectioning, D as DistanceUni
|
|
|
15
15
|
export { E as EntityType } from './entities-0a248a42.js';
|
|
16
16
|
export { A as ArrowMarkup, C as CircleMarkup, F as FreeformMarkup } from './markup-de28aeff.js';
|
|
17
17
|
export { V as Viewport } from './viewport-4ab005ad.js';
|
|
18
|
-
export { V as VolumeIntersectionQueryController } from './
|
|
18
|
+
export { V as VolumeIntersectionQueryController, a as VolumeIntersectionQueryModel } from './model-4ba9fc30.js';
|
|
19
19
|
import './browser.esm-e0ef86ec.js';
|
|
20
20
|
import './errors-3ffaf550.js';
|
|
21
21
|
import './representation_pb-efee7a8e.js';
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { S as StreamRequestError } from './bundle.esm-6602f71c.js';
|
|
5
5
|
import { E as EventDispatcher } from './browser.esm-e0ef86ec.js';
|
|
6
|
+
import { p as point, e as rectangle } from './bundle.esm-77ed5eae.js';
|
|
6
7
|
|
|
7
8
|
class VolumeIntersectionQueryController {
|
|
8
9
|
constructor(model, viewer) {
|
|
@@ -106,6 +107,88 @@ class VolumeIntersectionQueryController {
|
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
class VolumeIntersectionQueryModel {
|
|
111
|
+
constructor(mode) {
|
|
112
|
+
this.mode = mode;
|
|
113
|
+
this.dragStarted = new EventDispatcher();
|
|
114
|
+
this.dragComplete = new EventDispatcher();
|
|
115
|
+
this.dragCancelled = new EventDispatcher();
|
|
116
|
+
this.screenBoundsChanged = new EventDispatcher();
|
|
117
|
+
}
|
|
118
|
+
setStartPoint(point) {
|
|
119
|
+
this.startPoint = point;
|
|
120
|
+
this.dragStarted.emit();
|
|
121
|
+
}
|
|
122
|
+
setEndPoint(point$1) {
|
|
123
|
+
if (this.startPoint != null &&
|
|
124
|
+
point.distance(this.startPoint, point$1) >= 2) {
|
|
125
|
+
this.endPoint = point$1;
|
|
126
|
+
this.updateQueryType();
|
|
127
|
+
this.screenBoundsChanged.emit(this.getQueryDetails());
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
setMode(mode) {
|
|
131
|
+
this.mode = mode;
|
|
132
|
+
}
|
|
133
|
+
complete() {
|
|
134
|
+
if (this.startPoint != null && this.endPoint != null) {
|
|
135
|
+
this.screenBoundsChanged.emit(undefined);
|
|
136
|
+
this.dragComplete.emit(this.getQueryDetails());
|
|
137
|
+
this.reset();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
cancel() {
|
|
141
|
+
this.screenBoundsChanged.emit(undefined);
|
|
142
|
+
this.dragCancelled.emit();
|
|
143
|
+
this.reset();
|
|
144
|
+
}
|
|
145
|
+
reset() {
|
|
146
|
+
this.startPoint = undefined;
|
|
147
|
+
this.endPoint = undefined;
|
|
148
|
+
this.type = undefined;
|
|
149
|
+
}
|
|
150
|
+
getScreenBounds() {
|
|
151
|
+
return this.startPoint != null && this.endPoint != null
|
|
152
|
+
? rectangle.fromPoints(this.startPoint, this.endPoint)
|
|
153
|
+
: undefined;
|
|
154
|
+
}
|
|
155
|
+
getType() {
|
|
156
|
+
return this.type;
|
|
157
|
+
}
|
|
158
|
+
onScreenBoundsChanged(listener) {
|
|
159
|
+
return this.screenBoundsChanged.on(listener);
|
|
160
|
+
}
|
|
161
|
+
onDragStarted(listener) {
|
|
162
|
+
return this.dragStarted.on(listener);
|
|
163
|
+
}
|
|
164
|
+
onDragComplete(listener) {
|
|
165
|
+
return this.dragComplete.on(listener);
|
|
166
|
+
}
|
|
167
|
+
onDragCancelled(listener) {
|
|
168
|
+
return this.dragCancelled.on(listener);
|
|
169
|
+
}
|
|
170
|
+
getQueryDetails() {
|
|
171
|
+
if (this.startPoint != null && this.endPoint != null && this.type != null) {
|
|
172
|
+
return {
|
|
173
|
+
screenBounds: rectangle.fromPoints(this.startPoint, this.endPoint),
|
|
174
|
+
type: this.type,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
throw new Error('Failed to create query details, the start and end points must be set.');
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
updateQueryType() {
|
|
182
|
+
var _a;
|
|
183
|
+
if (this.startPoint != null && this.endPoint != null) {
|
|
184
|
+
const directionalType = point.subtract(this.endPoint, this.startPoint).x > 0
|
|
185
|
+
? 'exclusive'
|
|
186
|
+
: 'inclusive';
|
|
187
|
+
this.type = (_a = this.mode) !== null && _a !== void 0 ? _a : directionalType;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export { VolumeIntersectionQueryController as V, VolumeIntersectionQueryModel as a };
|
|
110
193
|
|
|
111
|
-
//# sourceMappingURL=
|
|
194
|
+
//# sourceMappingURL=model-4ba9fc30.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"file":"model-4ba9fc30.js","mappings":"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","names":["point","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}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* Copyright (c) 2024 Vertex Software LLC. All rights reserved.
|
|
3
3
|
*/
|
|
4
|
-
import { r as registerInstance, h, H as Host, g as getElement } from './index-4611b0d5.js';
|
|
5
|
-
import { V as VolumeIntersectionQueryController } from './
|
|
4
|
+
import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-4611b0d5.js';
|
|
5
|
+
import { a as VolumeIntersectionQueryModel, V as VolumeIntersectionQueryController } from './model-4ba9fc30.js';
|
|
6
6
|
import { b as boxQueryCursor } from './cursors-aad0bebb.js';
|
|
7
7
|
import { g as getMouseClientPosition } from './dom-2ca82d60.js';
|
|
8
|
-
import { p as point, e as rectangle } from './bundle.esm-77ed5eae.js';
|
|
9
|
-
import { E as EventDispatcher } from './browser.esm-e0ef86ec.js';
|
|
10
8
|
import './bundle.esm-6602f71c.js';
|
|
9
|
+
import './bundle.esm-77ed5eae.js';
|
|
10
|
+
import './browser.esm-e0ef86ec.js';
|
|
11
11
|
|
|
12
12
|
class VolumeIntersectionQueryInteractionHandler {
|
|
13
13
|
constructor(controller) {
|
|
@@ -89,93 +89,12 @@ class VolumeIntersectionQueryInteractionHandler {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
class VolumeIntersectionQueryModel {
|
|
93
|
-
constructor(mode) {
|
|
94
|
-
this.mode = mode;
|
|
95
|
-
this.dragStarted = new EventDispatcher();
|
|
96
|
-
this.dragComplete = new EventDispatcher();
|
|
97
|
-
this.dragCancelled = new EventDispatcher();
|
|
98
|
-
this.screenBoundsChanged = new EventDispatcher();
|
|
99
|
-
}
|
|
100
|
-
setStartPoint(point) {
|
|
101
|
-
this.startPoint = point;
|
|
102
|
-
this.dragStarted.emit();
|
|
103
|
-
}
|
|
104
|
-
setEndPoint(point$1) {
|
|
105
|
-
if (this.startPoint != null &&
|
|
106
|
-
point.distance(this.startPoint, point$1) >= 2) {
|
|
107
|
-
this.endPoint = point$1;
|
|
108
|
-
this.updateQueryType();
|
|
109
|
-
this.screenBoundsChanged.emit(this.getQueryDetails());
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
setMode(mode) {
|
|
113
|
-
this.mode = mode;
|
|
114
|
-
}
|
|
115
|
-
complete() {
|
|
116
|
-
if (this.startPoint != null && this.endPoint != null) {
|
|
117
|
-
this.screenBoundsChanged.emit(undefined);
|
|
118
|
-
this.dragComplete.emit(this.getQueryDetails());
|
|
119
|
-
this.reset();
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
cancel() {
|
|
123
|
-
this.screenBoundsChanged.emit(undefined);
|
|
124
|
-
this.dragCancelled.emit();
|
|
125
|
-
this.reset();
|
|
126
|
-
}
|
|
127
|
-
reset() {
|
|
128
|
-
this.startPoint = undefined;
|
|
129
|
-
this.endPoint = undefined;
|
|
130
|
-
this.type = undefined;
|
|
131
|
-
}
|
|
132
|
-
getScreenBounds() {
|
|
133
|
-
return this.startPoint != null && this.endPoint != null
|
|
134
|
-
? rectangle.fromPoints(this.startPoint, this.endPoint)
|
|
135
|
-
: undefined;
|
|
136
|
-
}
|
|
137
|
-
getType() {
|
|
138
|
-
return this.type;
|
|
139
|
-
}
|
|
140
|
-
onScreenBoundsChanged(listener) {
|
|
141
|
-
return this.screenBoundsChanged.on(listener);
|
|
142
|
-
}
|
|
143
|
-
onDragStarted(listener) {
|
|
144
|
-
return this.dragStarted.on(listener);
|
|
145
|
-
}
|
|
146
|
-
onDragComplete(listener) {
|
|
147
|
-
return this.dragComplete.on(listener);
|
|
148
|
-
}
|
|
149
|
-
onDragCancelled(listener) {
|
|
150
|
-
return this.dragCancelled.on(listener);
|
|
151
|
-
}
|
|
152
|
-
getQueryDetails() {
|
|
153
|
-
if (this.startPoint != null && this.endPoint != null && this.type != null) {
|
|
154
|
-
return {
|
|
155
|
-
screenBounds: rectangle.fromPoints(this.startPoint, this.endPoint),
|
|
156
|
-
type: this.type,
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
throw new Error('Failed to create query details, the start and end points must be set.');
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
updateQueryType() {
|
|
164
|
-
var _a;
|
|
165
|
-
if (this.startPoint != null && this.endPoint != null) {
|
|
166
|
-
const directionalType = point.subtract(this.endPoint, this.startPoint).x > 0
|
|
167
|
-
? 'exclusive'
|
|
168
|
-
: 'inclusive';
|
|
169
|
-
this.type = (_a = this.mode) !== null && _a !== void 0 ? _a : directionalType;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
92
|
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)}";
|
|
175
93
|
|
|
176
94
|
const ViewerBoxQueryTool = class {
|
|
177
95
|
constructor(hostRef) {
|
|
178
96
|
registerInstance(this, hostRef);
|
|
97
|
+
this.controllerChanged = createEvent(this, "controllerChanged", 7);
|
|
179
98
|
/**
|
|
180
99
|
* The default operation to perform when a drag has completed and the intersection
|
|
181
100
|
* query will be run. Defaults to `clearAndSelect`, and can be changed to `select` or `deselect`.
|
|
@@ -252,6 +171,7 @@ const ViewerBoxQueryTool = class {
|
|
|
252
171
|
(_b = this.operationCompleteDisposable) === null || _b === void 0 ? void 0 : _b.dispose();
|
|
253
172
|
this.operationStartedDisposable = controller === null || controller === void 0 ? void 0 : controller.onExecuteStarted(this.handleExecuteStarted);
|
|
254
173
|
this.operationStartedDisposable = controller === null || controller === void 0 ? void 0 : controller.onExecuteComplete(this.handleExecuteComplete);
|
|
174
|
+
this.controllerChanged.emit(this.controller);
|
|
255
175
|
}
|
|
256
176
|
/**
|
|
257
177
|
* @ignore
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"file":"vertex-viewer-box-query-tool.entry.js","mappings":"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","names":["point","Point","Rectangle"],"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.js","mappings":"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","names":[],"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}
|
|
@@ -1490,7 +1490,15 @@ class MouseInteractionHandler extends BaseInteractionHandler {
|
|
|
1490
1490
|
}
|
|
1491
1491
|
}
|
|
1492
1492
|
|
|
1493
|
+
function requestAnimationFrame(callback) {
|
|
1494
|
+
window.requestAnimationFrame(callback);
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1493
1497
|
class MultiTouchInteractionHandler {
|
|
1498
|
+
constructor() {
|
|
1499
|
+
this.previousFirstPoints = [];
|
|
1500
|
+
this.previousSecondPoints = [];
|
|
1501
|
+
}
|
|
1494
1502
|
initialize(element, api) {
|
|
1495
1503
|
this.element = element;
|
|
1496
1504
|
this.interactionApi = api;
|
|
@@ -1498,26 +1506,83 @@ class MultiTouchInteractionHandler {
|
|
|
1498
1506
|
dispose() {
|
|
1499
1507
|
this.element = undefined;
|
|
1500
1508
|
}
|
|
1509
|
+
beginTwoPointTouch(point1, point2) {
|
|
1510
|
+
this.previousFirstPoints = [...this.previousFirstPoints, point1];
|
|
1511
|
+
this.previousSecondPoints = [...this.previousSecondPoints, point2];
|
|
1512
|
+
}
|
|
1501
1513
|
handleTwoPointTouchMove(point1, point2) {
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
(
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1514
|
+
this.previousFirstPoints = [...this.previousFirstPoints, point1];
|
|
1515
|
+
this.previousSecondPoints = [...this.previousSecondPoints, point2];
|
|
1516
|
+
// Process updates to touch points on animation frame callbacks to batch
|
|
1517
|
+
// the processing. Because each event can potentially only represent a single
|
|
1518
|
+
// touch point moving, two opposing angles can be computed sequentially. This
|
|
1519
|
+
// results in a wobbling effect if those angles are both sent, and this batched
|
|
1520
|
+
// processing helps to reduce that effect.
|
|
1521
|
+
requestAnimationFrame(() => {
|
|
1522
|
+
var _a, _b, _c, _d;
|
|
1523
|
+
if (this.previousFirstPoints.length > 1 &&
|
|
1524
|
+
this.previousSecondPoints.length > 1 &&
|
|
1525
|
+
this.previousFirstPoints.length === this.previousSecondPoints.length) {
|
|
1526
|
+
const previousFirstPoints = this.previousFirstPoints;
|
|
1527
|
+
const previousSecondPoints = this.previousSecondPoints;
|
|
1528
|
+
this.previousFirstPoints = this.previousFirstPoints.slice(-1);
|
|
1529
|
+
this.previousSecondPoints = this.previousSecondPoints.slice(-1);
|
|
1530
|
+
const changes = previousFirstPoints.reduce((result, previousFirstPoint, i) => {
|
|
1531
|
+
if (i < previousFirstPoints.length - 1) {
|
|
1532
|
+
const firstPoint = previousFirstPoints[i + 1];
|
|
1533
|
+
const previousSecondPoint = previousSecondPoints[i];
|
|
1534
|
+
const secondPoint = previousSecondPoints[i + 1];
|
|
1535
|
+
return {
|
|
1536
|
+
deltas: [
|
|
1537
|
+
...result.deltas,
|
|
1538
|
+
this.computeDelta(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
|
|
1539
|
+
],
|
|
1540
|
+
zooms: [
|
|
1541
|
+
...result.zooms,
|
|
1542
|
+
this.computeZoom(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
|
|
1543
|
+
],
|
|
1544
|
+
angles: [
|
|
1545
|
+
...result.angles,
|
|
1546
|
+
this.computeAngle(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
|
|
1547
|
+
],
|
|
1548
|
+
};
|
|
1549
|
+
}
|
|
1550
|
+
return result;
|
|
1551
|
+
}, {
|
|
1552
|
+
deltas: [],
|
|
1553
|
+
zooms: [],
|
|
1554
|
+
angles: [],
|
|
1555
|
+
});
|
|
1556
|
+
const delta = changes.deltas.reduce((r, d) => point.add(r, d), point.create());
|
|
1557
|
+
const zoom = changes.zooms.reduce((z, d) => z + d, 0);
|
|
1558
|
+
const angle = changes.angles.reduce((a, d) => a + d, 0);
|
|
1559
|
+
const center = point.create((previousFirstPoints[previousFirstPoints.length - 1].x +
|
|
1560
|
+
previousSecondPoints[previousSecondPoints.length - 1].x) /
|
|
1561
|
+
2, (previousFirstPoints[previousFirstPoints.length - 1].y +
|
|
1562
|
+
previousSecondPoints[previousSecondPoints.length - 1].y) /
|
|
1563
|
+
2);
|
|
1564
|
+
(_a = this.interactionApi) === null || _a === void 0 ? void 0 : _a.beginInteraction();
|
|
1565
|
+
(_b = this.interactionApi) === null || _b === void 0 ? void 0 : _b.zoomCameraToPoint(center, zoom);
|
|
1566
|
+
(_c = this.interactionApi) === null || _c === void 0 ? void 0 : _c.panCameraByDelta(delta);
|
|
1567
|
+
(_d = this.interactionApi) === null || _d === void 0 ? void 0 : _d.twistCamera(angle);
|
|
1517
1568
|
}
|
|
1518
|
-
}
|
|
1519
|
-
|
|
1520
|
-
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
endTwoPointTouch() {
|
|
1572
|
+
this.previousFirstPoints = [];
|
|
1573
|
+
this.previousSecondPoints = [];
|
|
1574
|
+
}
|
|
1575
|
+
computeDelta(previousPoint1, previousPoint2, point1, point2) {
|
|
1576
|
+
return point.add(point.subtract(point1, previousPoint1), point.subtract(point2, previousPoint2));
|
|
1577
|
+
}
|
|
1578
|
+
computeZoom(previousPoint1, previousPoint2, point1, point2) {
|
|
1579
|
+
const distance = point.distance(point1, point2) -
|
|
1580
|
+
point.distance(previousPoint1, previousPoint2);
|
|
1581
|
+
return distance * 0.5;
|
|
1582
|
+
}
|
|
1583
|
+
computeAngle(previousPoint1, previousPoint2, point1, point2) {
|
|
1584
|
+
const previousToCurrent = matrix2.create(point.subtract(previousPoint1, previousPoint2), point.subtract(point1, point2));
|
|
1585
|
+
return angle.toDegrees(Math.atan2(matrix2.determinant(previousToCurrent), matrix2.dot(previousToCurrent)));
|
|
1521
1586
|
}
|
|
1522
1587
|
}
|
|
1523
1588
|
|
|
@@ -1546,6 +1611,9 @@ class MultiPointerInteractionHandler extends MultiTouchInteractionHandler {
|
|
|
1546
1611
|
window.addEventListener('pointermove', this.handlePointerMove);
|
|
1547
1612
|
window.addEventListener('pointerup', this.handlePointerUp);
|
|
1548
1613
|
}
|
|
1614
|
+
else if (keys.length === 2) {
|
|
1615
|
+
this.beginTwoPointTouch(this.touchPoints[0], this.touchPoints[1]);
|
|
1616
|
+
}
|
|
1549
1617
|
}
|
|
1550
1618
|
handlePointerMove(event) {
|
|
1551
1619
|
if (this.touchPoints[event.pointerId] != null) {
|
|
@@ -1564,13 +1632,12 @@ class MultiPointerInteractionHandler extends MultiTouchInteractionHandler {
|
|
|
1564
1632
|
const keys = Object.keys(this.touchPoints);
|
|
1565
1633
|
if (keys.length === 1) {
|
|
1566
1634
|
(_a = this.interactionApi) === null || _a === void 0 ? void 0 : _a.endInteraction();
|
|
1567
|
-
this.currentPosition1 = undefined;
|
|
1568
|
-
this.currentPosition2 = undefined;
|
|
1569
1635
|
}
|
|
1570
1636
|
if (keys.length === 0) {
|
|
1571
1637
|
window.removeEventListener('pointermove', this.handlePointerMove);
|
|
1572
1638
|
window.removeEventListener('pointerup', this.handlePointerUp);
|
|
1573
1639
|
}
|
|
1640
|
+
this.endTwoPointTouch();
|
|
1574
1641
|
}
|
|
1575
1642
|
}
|
|
1576
1643
|
|
|
@@ -1833,12 +1900,10 @@ class TouchInteractionHandler extends MultiTouchInteractionHandler {
|
|
|
1833
1900
|
if (event.touches.length >= 1) {
|
|
1834
1901
|
event.preventDefault();
|
|
1835
1902
|
const touch1 = event.touches[0];
|
|
1836
|
-
const touch2 = event.touches[1];
|
|
1837
1903
|
this.currentPosition1 = point.create(touch1.screenX, touch1.screenY);
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
: undefined;
|
|
1904
|
+
if (event.touches[1] != null) {
|
|
1905
|
+
this.beginTwoPointTouch(this.currentPosition1, point.create(event.touches[1].screenX, event.touches[1].screenY));
|
|
1906
|
+
}
|
|
1842
1907
|
window.addEventListener('touchmove', this.handleTouchMove, {
|
|
1843
1908
|
passive: false,
|
|
1844
1909
|
});
|
|
@@ -1863,6 +1928,7 @@ class TouchInteractionHandler extends MultiTouchInteractionHandler {
|
|
|
1863
1928
|
this.isInteracting = false;
|
|
1864
1929
|
window.removeEventListener('touchmove', this.handleTouchMove);
|
|
1865
1930
|
window.removeEventListener('touchend', this.handleTouchEnd);
|
|
1931
|
+
this.endTwoPointTouch();
|
|
1866
1932
|
}
|
|
1867
1933
|
handleOnePointTouchMove(touch) {
|
|
1868
1934
|
var _a, _b, _c;
|