@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.
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
@@ -1,12 +1,10 @@
1
1
  /*!
2
2
  * Copyright (c) 2024 Vertex Software LLC. All rights reserved.
3
3
  */
4
- import { proxyCustomElement, HTMLElement, h, Host } from '@stencil/core/internal/client';
5
- import { V as VolumeIntersectionQueryController } from './controller3.js';
4
+ import { proxyCustomElement, HTMLElement, createEvent, h, Host } from '@stencil/core/internal/client';
5
+ import { a as VolumeIntersectionQueryModel, V as VolumeIntersectionQueryController } from './model2.js';
6
6
  import { b as boxQueryCursor } from './cursors.js';
7
7
  import { g as getMouseClientPosition } from './dom.js';
8
- import { p as point, e as rectangle } from './bundle.esm.js';
9
- import { E as EventDispatcher } from './browser.esm.js';
10
8
  import { d as defineCustomElement$2 } from './viewer-layer.js';
11
9
 
12
10
  class VolumeIntersectionQueryInteractionHandler {
@@ -89,88 +87,6 @@ class VolumeIntersectionQueryInteractionHandler {
89
87
  }
90
88
  }
91
89
 
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
90
  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
91
 
176
92
  const ViewerBoxQueryTool = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
@@ -178,6 +94,7 @@ const ViewerBoxQueryTool = /*@__PURE__*/ proxyCustomElement(class extends HTMLEl
178
94
  super();
179
95
  this.__registerHost();
180
96
  this.__attachShadow();
97
+ this.controllerChanged = createEvent(this, "controllerChanged", 7);
181
98
  /**
182
99
  * The default operation to perform when a drag has completed and the intersection
183
100
  * query will be run. Defaults to `clearAndSelect`, and can be changed to `select` or `deselect`.
@@ -254,6 +171,7 @@ const ViewerBoxQueryTool = /*@__PURE__*/ proxyCustomElement(class extends HTMLEl
254
171
  (_b = this.operationCompleteDisposable) === null || _b === void 0 ? void 0 : _b.dispose();
255
172
  this.operationStartedDisposable = controller === null || controller === void 0 ? void 0 : controller.onExecuteStarted(this.handleExecuteStarted);
256
173
  this.operationStartedDisposable = controller === null || controller === void 0 ? void 0 : controller.onExecuteComplete(this.handleExecuteComplete);
174
+ this.controllerChanged.emit(this.controller);
257
175
  }
258
176
  /**
259
177
  * @ignore
@@ -1 +1 @@
1
- {"file":"vertex-viewer-box-query-tool.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.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}
@@ -9,7 +9,7 @@ import { l as labelPinCursor, p as pinCursor } from './cursors.js';
9
9
  import { g as getMouseClientPosition } from './dom.js';
10
10
  import { E as ElementRectObserver } from './elementRectObserver.js';
11
11
  import { E as EntityType } from './streamAttributes.js';
12
- import { P as PinModel } from './model2.js';
12
+ import { P as PinModel } from './model3.js';
13
13
  import { g as getMarkupBoundingClientRect } from './dom2.js';
14
14
  import { d as defineCustomElement$7 } from './viewer-dom-element.js';
15
15
  import { d as defineCustomElement$6 } from './viewer-dom-renderer.js';
@@ -1485,7 +1485,15 @@ class MouseInteractionHandler extends BaseInteractionHandler {
1485
1485
  }
1486
1486
  }
1487
1487
 
1488
+ function requestAnimationFrame(callback) {
1489
+ window.requestAnimationFrame(callback);
1490
+ }
1491
+
1488
1492
  class MultiTouchInteractionHandler {
1493
+ constructor() {
1494
+ this.previousFirstPoints = [];
1495
+ this.previousSecondPoints = [];
1496
+ }
1489
1497
  initialize(element, api) {
1490
1498
  this.element = element;
1491
1499
  this.interactionApi = api;
@@ -1493,26 +1501,83 @@ class MultiTouchInteractionHandler {
1493
1501
  dispose() {
1494
1502
  this.element = undefined;
1495
1503
  }
1504
+ beginTwoPointTouch(point1, point2) {
1505
+ this.previousFirstPoints = [...this.previousFirstPoints, point1];
1506
+ this.previousSecondPoints = [...this.previousSecondPoints, point2];
1507
+ }
1496
1508
  handleTwoPointTouchMove(point1, point2) {
1497
- var _a, _b, _c, _d;
1498
- if (this.currentPosition1 != null && this.currentPosition2 != null) {
1499
- const delta = point.add(point.subtract(point1, this.currentPosition1), point.subtract(point2, this.currentPosition2));
1500
- const distance = point.distance(point1, point2) -
1501
- point.distance(this.currentPosition1, this.currentPosition2);
1502
- const zoom = distance * 0.5;
1503
- const previousToCurrent = matrix2.create(point.subtract(this.currentPosition1, this.currentPosition2), point.subtract(point1, point2));
1504
- const angle$1 = angle.toDegrees(Math.atan2(matrix2.determinant(previousToCurrent), matrix2.dot(previousToCurrent)));
1505
- const center = point.create((point1.x + point2.x) / 2, (point1.y + point2.y) / 2);
1506
- (_a = this.interactionApi) === null || _a === void 0 ? void 0 : _a.beginInteraction();
1507
- (_b = this.interactionApi) === null || _b === void 0 ? void 0 : _b.zoomCameraToPoint(center, zoom);
1508
- (_c = this.interactionApi) === null || _c === void 0 ? void 0 : _c.panCameraByDelta(delta);
1509
- // Setting a minimum angle to prevent wobbling
1510
- if (Math.abs(angle$1) > 0.5) {
1511
- (_d = this.interactionApi) === null || _d === void 0 ? void 0 : _d.twistCamera(angle$1);
1509
+ this.previousFirstPoints = [...this.previousFirstPoints, point1];
1510
+ this.previousSecondPoints = [...this.previousSecondPoints, point2];
1511
+ // Process updates to touch points on animation frame callbacks to batch
1512
+ // the processing. Because each event can potentially only represent a single
1513
+ // touch point moving, two opposing angles can be computed sequentially. This
1514
+ // results in a wobbling effect if those angles are both sent, and this batched
1515
+ // processing helps to reduce that effect.
1516
+ requestAnimationFrame(() => {
1517
+ var _a, _b, _c, _d;
1518
+ if (this.previousFirstPoints.length > 1 &&
1519
+ this.previousSecondPoints.length > 1 &&
1520
+ this.previousFirstPoints.length === this.previousSecondPoints.length) {
1521
+ const previousFirstPoints = this.previousFirstPoints;
1522
+ const previousSecondPoints = this.previousSecondPoints;
1523
+ this.previousFirstPoints = this.previousFirstPoints.slice(-1);
1524
+ this.previousSecondPoints = this.previousSecondPoints.slice(-1);
1525
+ const changes = previousFirstPoints.reduce((result, previousFirstPoint, i) => {
1526
+ if (i < previousFirstPoints.length - 1) {
1527
+ const firstPoint = previousFirstPoints[i + 1];
1528
+ const previousSecondPoint = previousSecondPoints[i];
1529
+ const secondPoint = previousSecondPoints[i + 1];
1530
+ return {
1531
+ deltas: [
1532
+ ...result.deltas,
1533
+ this.computeDelta(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
1534
+ ],
1535
+ zooms: [
1536
+ ...result.zooms,
1537
+ this.computeZoom(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
1538
+ ],
1539
+ angles: [
1540
+ ...result.angles,
1541
+ this.computeAngle(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
1542
+ ],
1543
+ };
1544
+ }
1545
+ return result;
1546
+ }, {
1547
+ deltas: [],
1548
+ zooms: [],
1549
+ angles: [],
1550
+ });
1551
+ const delta = changes.deltas.reduce((r, d) => point.add(r, d), point.create());
1552
+ const zoom = changes.zooms.reduce((z, d) => z + d, 0);
1553
+ const angle = changes.angles.reduce((a, d) => a + d, 0);
1554
+ const center = point.create((previousFirstPoints[previousFirstPoints.length - 1].x +
1555
+ previousSecondPoints[previousSecondPoints.length - 1].x) /
1556
+ 2, (previousFirstPoints[previousFirstPoints.length - 1].y +
1557
+ previousSecondPoints[previousSecondPoints.length - 1].y) /
1558
+ 2);
1559
+ (_a = this.interactionApi) === null || _a === void 0 ? void 0 : _a.beginInteraction();
1560
+ (_b = this.interactionApi) === null || _b === void 0 ? void 0 : _b.zoomCameraToPoint(center, zoom);
1561
+ (_c = this.interactionApi) === null || _c === void 0 ? void 0 : _c.panCameraByDelta(delta);
1562
+ (_d = this.interactionApi) === null || _d === void 0 ? void 0 : _d.twistCamera(angle);
1512
1563
  }
1513
- }
1514
- this.currentPosition1 = point1;
1515
- this.currentPosition2 = point2;
1564
+ });
1565
+ }
1566
+ endTwoPointTouch() {
1567
+ this.previousFirstPoints = [];
1568
+ this.previousSecondPoints = [];
1569
+ }
1570
+ computeDelta(previousPoint1, previousPoint2, point1, point2) {
1571
+ return point.add(point.subtract(point1, previousPoint1), point.subtract(point2, previousPoint2));
1572
+ }
1573
+ computeZoom(previousPoint1, previousPoint2, point1, point2) {
1574
+ const distance = point.distance(point1, point2) -
1575
+ point.distance(previousPoint1, previousPoint2);
1576
+ return distance * 0.5;
1577
+ }
1578
+ computeAngle(previousPoint1, previousPoint2, point1, point2) {
1579
+ const previousToCurrent = matrix2.create(point.subtract(previousPoint1, previousPoint2), point.subtract(point1, point2));
1580
+ return angle.toDegrees(Math.atan2(matrix2.determinant(previousToCurrent), matrix2.dot(previousToCurrent)));
1516
1581
  }
1517
1582
  }
1518
1583
 
@@ -1541,6 +1606,9 @@ class MultiPointerInteractionHandler extends MultiTouchInteractionHandler {
1541
1606
  window.addEventListener('pointermove', this.handlePointerMove);
1542
1607
  window.addEventListener('pointerup', this.handlePointerUp);
1543
1608
  }
1609
+ else if (keys.length === 2) {
1610
+ this.beginTwoPointTouch(this.touchPoints[0], this.touchPoints[1]);
1611
+ }
1544
1612
  }
1545
1613
  handlePointerMove(event) {
1546
1614
  if (this.touchPoints[event.pointerId] != null) {
@@ -1559,13 +1627,12 @@ class MultiPointerInteractionHandler extends MultiTouchInteractionHandler {
1559
1627
  const keys = Object.keys(this.touchPoints);
1560
1628
  if (keys.length === 1) {
1561
1629
  (_a = this.interactionApi) === null || _a === void 0 ? void 0 : _a.endInteraction();
1562
- this.currentPosition1 = undefined;
1563
- this.currentPosition2 = undefined;
1564
1630
  }
1565
1631
  if (keys.length === 0) {
1566
1632
  window.removeEventListener('pointermove', this.handlePointerMove);
1567
1633
  window.removeEventListener('pointerup', this.handlePointerUp);
1568
1634
  }
1635
+ this.endTwoPointTouch();
1569
1636
  }
1570
1637
  }
1571
1638
 
@@ -1828,12 +1895,10 @@ class TouchInteractionHandler extends MultiTouchInteractionHandler {
1828
1895
  if (event.touches.length >= 1) {
1829
1896
  event.preventDefault();
1830
1897
  const touch1 = event.touches[0];
1831
- const touch2 = event.touches[1];
1832
1898
  this.currentPosition1 = point.create(touch1.screenX, touch1.screenY);
1833
- this.currentPosition2 =
1834
- touch2 != null
1835
- ? point.create(touch2.screenX, touch2.screenY)
1836
- : undefined;
1899
+ if (event.touches[1] != null) {
1900
+ this.beginTwoPointTouch(this.currentPosition1, point.create(event.touches[1].screenX, event.touches[1].screenY));
1901
+ }
1837
1902
  window.addEventListener('touchmove', this.handleTouchMove, {
1838
1903
  passive: false,
1839
1904
  });
@@ -1858,6 +1923,7 @@ class TouchInteractionHandler extends MultiTouchInteractionHandler {
1858
1923
  this.isInteracting = false;
1859
1924
  window.removeEventListener('touchmove', this.handleTouchMove);
1860
1925
  window.removeEventListener('touchend', this.handleTouchEnd);
1926
+ this.endTwoPointTouch();
1861
1927
  }
1862
1928
  handleOnePointTouchMove(touch) {
1863
1929
  var _a, _b, _c;