@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,7 +1,7 @@
1
1
  /*!
2
2
  * Copyright (c) 2024 Vertex Software LLC. All rights reserved.
3
3
  */
4
- import { Component, Element, h, Host, Prop, State, Watch } from '@stencil/core';
4
+ import { Component, Element, Event, h, Host, Prop, State, Watch, } from '@stencil/core';
5
5
  import { VolumeIntersectionQueryController } from '../../lib/volume-intersection/controller';
6
6
  import { VolumeIntersectionQueryInteractionHandler } from '../../lib/volume-intersection/interactions';
7
7
  import { VolumeIntersectionQueryModel, } from '../../lib/volume-intersection/model';
@@ -89,6 +89,7 @@ export class ViewerBoxQueryTool {
89
89
  (_b = this.operationCompleteDisposable) === null || _b === void 0 ? void 0 : _b.dispose();
90
90
  this.operationStartedDisposable = controller === null || controller === void 0 ? void 0 : controller.onExecuteStarted(this.handleExecuteStarted);
91
91
  this.operationStartedDisposable = controller === null || controller === void 0 ? void 0 : controller.onExecuteComplete(this.handleExecuteComplete);
92
+ this.controllerChanged.emit(this.controller);
92
93
  }
93
94
  /**
94
95
  * @ignore
@@ -265,6 +266,27 @@ export class ViewerBoxQueryTool {
265
266
  static get states() { return {
266
267
  "details": {}
267
268
  }; }
269
+ static get events() { return [{
270
+ "method": "controllerChanged",
271
+ "name": "controllerChanged",
272
+ "bubbles": true,
273
+ "cancelable": true,
274
+ "composed": true,
275
+ "docs": {
276
+ "tags": [],
277
+ "text": "Event emitted when the `VolumeIntersectionQueryController` associated with this tool changes."
278
+ },
279
+ "complexType": {
280
+ "original": "VolumeIntersectionQueryController",
281
+ "resolved": "VolumeIntersectionQueryController",
282
+ "references": {
283
+ "VolumeIntersectionQueryController": {
284
+ "location": "import",
285
+ "path": "../../lib/volume-intersection/controller"
286
+ }
287
+ }
288
+ }
289
+ }]; }
268
290
  static get elementRef() { return "hostEl"; }
269
291
  static get watchers() { return [{
270
292
  "propName": "viewer",
@@ -1 +1 @@
1
- {"version":3,"file":"viewer-box-query-tool.js","sourceRoot":"","sources":["../../../src/components/viewer-box-query-tool/viewer-box-query-tool.tsx"],"names":[],"mappings":"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","sourcesContent":["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"]}
1
+ {"version":3,"file":"viewer-box-query-tool.js","sourceRoot":"","sources":["../../../src/components/viewer-box-query-tool/viewer-box-query-tool.tsx"],"names":[],"mappings":"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","sourcesContent":["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"]}
@@ -28,6 +28,9 @@ export class MultiPointerInteractionHandler extends MultiTouchInteractionHandler
28
28
  window.addEventListener('pointermove', this.handlePointerMove);
29
29
  window.addEventListener('pointerup', this.handlePointerUp);
30
30
  }
31
+ else if (keys.length === 2) {
32
+ this.beginTwoPointTouch(this.touchPoints[0], this.touchPoints[1]);
33
+ }
31
34
  }
32
35
  handlePointerMove(event) {
33
36
  if (this.touchPoints[event.pointerId] != null) {
@@ -46,13 +49,12 @@ export class MultiPointerInteractionHandler extends MultiTouchInteractionHandler
46
49
  const keys = Object.keys(this.touchPoints);
47
50
  if (keys.length === 1) {
48
51
  (_a = this.interactionApi) === null || _a === void 0 ? void 0 : _a.endInteraction();
49
- this.currentPosition1 = undefined;
50
- this.currentPosition2 = undefined;
51
52
  }
52
53
  if (keys.length === 0) {
53
54
  window.removeEventListener('pointermove', this.handlePointerMove);
54
55
  window.removeEventListener('pointerup', this.handlePointerUp);
55
56
  }
57
+ this.endTwoPointTouch();
56
58
  }
57
59
  }
58
60
  //# sourceMappingURL=multiPointerInteractionHandler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"multiPointerInteractionHandler.js","sourceRoot":"","sources":["../../../src/lib/interactions/multiPointerInteractionHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Point } from '@vertexvis/geometry';\n\nimport { InteractionApi } from './interactionApi';\nimport { MultiTouchInteractionHandler } from './multiTouchInteractionHandler';\n\nexport class MultiPointerInteractionHandler extends MultiTouchInteractionHandler {\n private touchPoints: Record<string, Point.Point> = {};\n\n public constructor() {\n super();\n this.handlePointerDown = this.handlePointerDown.bind(this);\n this.handlePointerMove = this.handlePointerMove.bind(this);\n this.handlePointerUp = this.handlePointerUp.bind(this);\n }\n\n public dispose(): void {\n this.element?.removeEventListener('pointerdown', this.handlePointerDown);\n super.dispose();\n }\n\n public initialize(element: HTMLElement, api: InteractionApi): void {\n super.initialize(element, api);\n\n element.addEventListener('pointerdown', this.handlePointerDown);\n }\n\n private handlePointerDown(event: PointerEvent): void {\n const point = Point.create(event.screenX, event.screenY);\n this.touchPoints = {\n ...this.touchPoints,\n [event.pointerId]: point,\n };\n const keys = Object.keys(this.touchPoints);\n if (keys.length === 1) {\n window.addEventListener('pointermove', this.handlePointerMove);\n window.addEventListener('pointerup', this.handlePointerUp);\n }\n }\n\n private handlePointerMove(event: PointerEvent): void {\n if (this.touchPoints[event.pointerId] != null) {\n this.touchPoints[event.pointerId] = Point.create(\n event.screenX,\n event.screenY\n );\n }\n\n const keys = Object.keys(this.touchPoints);\n if (keys.length === 2) {\n const point1 = this.touchPoints[keys[0]];\n const point2 = this.touchPoints[keys[1]];\n this.handleTwoPointTouchMove(point1, point2);\n }\n }\n\n private handlePointerUp(event: PointerEvent): void {\n delete this.touchPoints[event.pointerId];\n\n const keys = Object.keys(this.touchPoints);\n if (keys.length === 1) {\n this.interactionApi?.endInteraction();\n this.currentPosition1 = undefined;\n this.currentPosition2 = undefined;\n }\n if (keys.length === 0) {\n window.removeEventListener('pointermove', this.handlePointerMove);\n window.removeEventListener('pointerup', this.handlePointerUp);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"multiPointerInteractionHandler.js","sourceRoot":"","sources":["../../../src/lib/interactions/multiPointerInteractionHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Point } from '@vertexvis/geometry';\n\nimport { InteractionApi } from './interactionApi';\nimport { MultiTouchInteractionHandler } from './multiTouchInteractionHandler';\n\nexport class MultiPointerInteractionHandler extends MultiTouchInteractionHandler {\n private touchPoints: Record<string, Point.Point> = {};\n\n public constructor() {\n super();\n this.handlePointerDown = this.handlePointerDown.bind(this);\n this.handlePointerMove = this.handlePointerMove.bind(this);\n this.handlePointerUp = this.handlePointerUp.bind(this);\n }\n\n public dispose(): void {\n this.element?.removeEventListener('pointerdown', this.handlePointerDown);\n super.dispose();\n }\n\n public initialize(element: HTMLElement, api: InteractionApi): void {\n super.initialize(element, api);\n\n element.addEventListener('pointerdown', this.handlePointerDown);\n }\n\n private handlePointerDown(event: PointerEvent): void {\n const point = Point.create(event.screenX, event.screenY);\n this.touchPoints = {\n ...this.touchPoints,\n [event.pointerId]: point,\n };\n const keys = Object.keys(this.touchPoints);\n if (keys.length === 1) {\n window.addEventListener('pointermove', this.handlePointerMove);\n window.addEventListener('pointerup', this.handlePointerUp);\n } else if (keys.length === 2) {\n this.beginTwoPointTouch(this.touchPoints[0], this.touchPoints[1]);\n }\n }\n\n private handlePointerMove(event: PointerEvent): void {\n if (this.touchPoints[event.pointerId] != null) {\n this.touchPoints[event.pointerId] = Point.create(\n event.screenX,\n event.screenY\n );\n }\n\n const keys = Object.keys(this.touchPoints);\n if (keys.length === 2) {\n const point1 = this.touchPoints[keys[0]];\n const point2 = this.touchPoints[keys[1]];\n this.handleTwoPointTouchMove(point1, point2);\n }\n }\n\n private handlePointerUp(event: PointerEvent): void {\n delete this.touchPoints[event.pointerId];\n\n const keys = Object.keys(this.touchPoints);\n if (keys.length === 1) {\n this.interactionApi?.endInteraction();\n }\n if (keys.length === 0) {\n window.removeEventListener('pointermove', this.handlePointerMove);\n window.removeEventListener('pointerup', this.handlePointerUp);\n }\n this.endTwoPointTouch();\n }\n}\n"]}
@@ -2,7 +2,12 @@
2
2
  * Copyright (c) 2024 Vertex Software LLC. All rights reserved.
3
3
  */
4
4
  import { Angle, Matrix2, Point } from '@vertexvis/geometry';
5
+ import { requestAnimationFrame } from '../window';
5
6
  export class MultiTouchInteractionHandler {
7
+ constructor() {
8
+ this.previousFirstPoints = [];
9
+ this.previousSecondPoints = [];
10
+ }
6
11
  initialize(element, api) {
7
12
  this.element = element;
8
13
  this.interactionApi = api;
@@ -10,26 +15,83 @@ export class MultiTouchInteractionHandler {
10
15
  dispose() {
11
16
  this.element = undefined;
12
17
  }
18
+ beginTwoPointTouch(point1, point2) {
19
+ this.previousFirstPoints = [...this.previousFirstPoints, point1];
20
+ this.previousSecondPoints = [...this.previousSecondPoints, point2];
21
+ }
13
22
  handleTwoPointTouchMove(point1, point2) {
14
- var _a, _b, _c, _d;
15
- if (this.currentPosition1 != null && this.currentPosition2 != null) {
16
- const delta = Point.add(Point.subtract(point1, this.currentPosition1), Point.subtract(point2, this.currentPosition2));
17
- const distance = Point.distance(point1, point2) -
18
- Point.distance(this.currentPosition1, this.currentPosition2);
19
- const zoom = distance * 0.5;
20
- const previousToCurrent = Matrix2.create(Point.subtract(this.currentPosition1, this.currentPosition2), Point.subtract(point1, point2));
21
- const angle = Angle.toDegrees(Math.atan2(Matrix2.determinant(previousToCurrent), Matrix2.dot(previousToCurrent)));
22
- const center = Point.create((point1.x + point2.x) / 2, (point1.y + point2.y) / 2);
23
- (_a = this.interactionApi) === null || _a === void 0 ? void 0 : _a.beginInteraction();
24
- (_b = this.interactionApi) === null || _b === void 0 ? void 0 : _b.zoomCameraToPoint(center, zoom);
25
- (_c = this.interactionApi) === null || _c === void 0 ? void 0 : _c.panCameraByDelta(delta);
26
- // Setting a minimum angle to prevent wobbling
27
- if (Math.abs(angle) > 0.5) {
23
+ this.previousFirstPoints = [...this.previousFirstPoints, point1];
24
+ this.previousSecondPoints = [...this.previousSecondPoints, point2];
25
+ // Process updates to touch points on animation frame callbacks to batch
26
+ // the processing. Because each event can potentially only represent a single
27
+ // touch point moving, two opposing angles can be computed sequentially. This
28
+ // results in a wobbling effect if those angles are both sent, and this batched
29
+ // processing helps to reduce that effect.
30
+ requestAnimationFrame(() => {
31
+ var _a, _b, _c, _d;
32
+ if (this.previousFirstPoints.length > 1 &&
33
+ this.previousSecondPoints.length > 1 &&
34
+ this.previousFirstPoints.length === this.previousSecondPoints.length) {
35
+ const previousFirstPoints = this.previousFirstPoints;
36
+ const previousSecondPoints = this.previousSecondPoints;
37
+ this.previousFirstPoints = this.previousFirstPoints.slice(-1);
38
+ this.previousSecondPoints = this.previousSecondPoints.slice(-1);
39
+ const changes = previousFirstPoints.reduce((result, previousFirstPoint, i) => {
40
+ if (i < previousFirstPoints.length - 1) {
41
+ const firstPoint = previousFirstPoints[i + 1];
42
+ const previousSecondPoint = previousSecondPoints[i];
43
+ const secondPoint = previousSecondPoints[i + 1];
44
+ return {
45
+ deltas: [
46
+ ...result.deltas,
47
+ this.computeDelta(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
48
+ ],
49
+ zooms: [
50
+ ...result.zooms,
51
+ this.computeZoom(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
52
+ ],
53
+ angles: [
54
+ ...result.angles,
55
+ this.computeAngle(previousFirstPoint, previousSecondPoint, firstPoint, secondPoint),
56
+ ],
57
+ };
58
+ }
59
+ return result;
60
+ }, {
61
+ deltas: [],
62
+ zooms: [],
63
+ angles: [],
64
+ });
65
+ const delta = changes.deltas.reduce((r, d) => Point.add(r, d), Point.create());
66
+ const zoom = changes.zooms.reduce((z, d) => z + d, 0);
67
+ const angle = changes.angles.reduce((a, d) => a + d, 0);
68
+ const center = Point.create((previousFirstPoints[previousFirstPoints.length - 1].x +
69
+ previousSecondPoints[previousSecondPoints.length - 1].x) /
70
+ 2, (previousFirstPoints[previousFirstPoints.length - 1].y +
71
+ previousSecondPoints[previousSecondPoints.length - 1].y) /
72
+ 2);
73
+ (_a = this.interactionApi) === null || _a === void 0 ? void 0 : _a.beginInteraction();
74
+ (_b = this.interactionApi) === null || _b === void 0 ? void 0 : _b.zoomCameraToPoint(center, zoom);
75
+ (_c = this.interactionApi) === null || _c === void 0 ? void 0 : _c.panCameraByDelta(delta);
28
76
  (_d = this.interactionApi) === null || _d === void 0 ? void 0 : _d.twistCamera(angle);
29
77
  }
30
- }
31
- this.currentPosition1 = point1;
32
- this.currentPosition2 = point2;
78
+ });
79
+ }
80
+ endTwoPointTouch() {
81
+ this.previousFirstPoints = [];
82
+ this.previousSecondPoints = [];
83
+ }
84
+ computeDelta(previousPoint1, previousPoint2, point1, point2) {
85
+ return Point.add(Point.subtract(point1, previousPoint1), Point.subtract(point2, previousPoint2));
86
+ }
87
+ computeZoom(previousPoint1, previousPoint2, point1, point2) {
88
+ const distance = Point.distance(point1, point2) -
89
+ Point.distance(previousPoint1, previousPoint2);
90
+ return distance * 0.5;
91
+ }
92
+ computeAngle(previousPoint1, previousPoint2, point1, point2) {
93
+ const previousToCurrent = Matrix2.create(Point.subtract(previousPoint1, previousPoint2), Point.subtract(point1, point2));
94
+ return Angle.toDegrees(Math.atan2(Matrix2.determinant(previousToCurrent), Matrix2.dot(previousToCurrent)));
33
95
  }
34
96
  }
35
97
  //# sourceMappingURL=multiTouchInteractionHandler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"multiTouchInteractionHandler.js","sourceRoot":"","sources":["../../../src/lib/interactions/multiTouchInteractionHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAK5D,MAAM,OAAgB,4BAA4B;EAQzC,UAAU,CAAC,OAAoB,EAAE,GAAmB;IACzD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACvB,IAAI,CAAC,cAAc,GAAG,GAAG,CAAC;EAC5B,CAAC;EAEM,OAAO;IACZ,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;EAC3B,CAAC;EAES,uBAAuB,CAC/B,MAAmB,EACnB,MAAmB;;IAEnB,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,EAAE;MAClE,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CACrB,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAC7C,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAC9C,CAAC;MAEF,MAAM,QAAQ,GACZ,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAC9B,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;MAC/D,MAAM,IAAI,GAAG,QAAQ,GAAG,GAAG,CAAC;MAC5B,MAAM,iBAAiB,GAAG,OAAO,CAAC,MAAM,CACtC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAC5D,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAC/B,CAAC;MACF,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAC3B,IAAI,CAAC,KAAK,CACR,OAAO,CAAC,WAAW,CAAC,iBAAiB,CAAC,EACtC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAC/B,CACF,CAAC;MACF,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CACzB,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EACzB,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAC1B,CAAC;MAEF,MAAA,IAAI,CAAC,cAAc,0CAAE,gBAAgB,EAAE,CAAC;MACxC,MAAA,IAAI,CAAC,cAAc,0CAAE,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;MACrD,MAAA,IAAI,CAAC,cAAc,0CAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;MAE7C,8CAA8C;MAC9C,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE;QACzB,MAAA,IAAI,CAAC,cAAc,0CAAE,WAAW,CAAC,KAAK,CAAC,CAAC;OACzC;KACF;IAED,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC;IAC/B,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC;EACjC,CAAC;CACF","sourcesContent":["import { Angle, Matrix2, Point } from '@vertexvis/geometry';\n\nimport { InteractionApi } from './interactionApi';\nimport { InteractionHandler } from './interactionHandler';\n\nexport abstract class MultiTouchInteractionHandler\n implements InteractionHandler\n{\n protected element?: HTMLElement;\n protected interactionApi?: InteractionApi;\n protected currentPosition1?: Point.Point;\n protected currentPosition2?: Point.Point;\n\n public initialize(element: HTMLElement, api: InteractionApi): void {\n this.element = element;\n this.interactionApi = api;\n }\n\n public dispose(): void {\n this.element = undefined;\n }\n\n protected handleTwoPointTouchMove(\n point1: Point.Point,\n point2: Point.Point\n ): void {\n if (this.currentPosition1 != null && this.currentPosition2 != null) {\n const delta = Point.add(\n Point.subtract(point1, this.currentPosition1),\n Point.subtract(point2, this.currentPosition2)\n );\n\n const distance =\n Point.distance(point1, point2) -\n Point.distance(this.currentPosition1, this.currentPosition2);\n const zoom = distance * 0.5;\n const previousToCurrent = Matrix2.create(\n Point.subtract(this.currentPosition1, this.currentPosition2),\n Point.subtract(point1, point2)\n );\n const angle = Angle.toDegrees(\n Math.atan2(\n Matrix2.determinant(previousToCurrent),\n Matrix2.dot(previousToCurrent)\n )\n );\n const center = Point.create(\n (point1.x + point2.x) / 2,\n (point1.y + point2.y) / 2\n );\n\n this.interactionApi?.beginInteraction();\n this.interactionApi?.zoomCameraToPoint(center, zoom);\n this.interactionApi?.panCameraByDelta(delta);\n\n // Setting a minimum angle to prevent wobbling\n if (Math.abs(angle) > 0.5) {\n this.interactionApi?.twistCamera(angle);\n }\n }\n\n this.currentPosition1 = point1;\n this.currentPosition2 = point2;\n }\n}\n"]}
1
+ {"version":3,"file":"multiTouchInteractionHandler.js","sourceRoot":"","sources":["../../../src/lib/interactions/multiTouchInteractionHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Angle, Matrix2, Point } from '@vertexvis/geometry';\n\nimport { requestAnimationFrame } from '../window';\nimport { InteractionApi } from './interactionApi';\nimport { InteractionHandler } from './interactionHandler';\n\nexport abstract class MultiTouchInteractionHandler\n implements InteractionHandler\n{\n protected element?: HTMLElement;\n protected interactionApi?: InteractionApi;\n\n private previousFirstPoints: Point.Point[] = [];\n private previousSecondPoints: Point.Point[] = [];\n\n public initialize(element: HTMLElement, api: InteractionApi): void {\n this.element = element;\n this.interactionApi = api;\n }\n\n public dispose(): void {\n this.element = undefined;\n }\n\n protected beginTwoPointTouch(point1: Point.Point, point2: Point.Point): void {\n this.previousFirstPoints = [...this.previousFirstPoints, point1];\n this.previousSecondPoints = [...this.previousSecondPoints, point2];\n }\n\n protected handleTwoPointTouchMove(\n point1: Point.Point,\n point2: Point.Point\n ): void {\n this.previousFirstPoints = [...this.previousFirstPoints, point1];\n this.previousSecondPoints = [...this.previousSecondPoints, point2];\n\n // Process updates to touch points on animation frame callbacks to batch\n // the processing. Because each event can potentially only represent a single\n // touch point moving, two opposing angles can be computed sequentially. This\n // results in a wobbling effect if those angles are both sent, and this batched\n // processing helps to reduce that effect.\n requestAnimationFrame(() => {\n if (\n this.previousFirstPoints.length > 1 &&\n this.previousSecondPoints.length > 1 &&\n this.previousFirstPoints.length === this.previousSecondPoints.length\n ) {\n const previousFirstPoints = this.previousFirstPoints;\n const previousSecondPoints = this.previousSecondPoints;\n\n this.previousFirstPoints = this.previousFirstPoints.slice(-1);\n this.previousSecondPoints = this.previousSecondPoints.slice(-1);\n\n const changes = previousFirstPoints.reduce<{\n deltas: Point.Point[];\n zooms: number[];\n angles: number[];\n }>(\n (result, previousFirstPoint, i) => {\n if (i < previousFirstPoints.length - 1) {\n const firstPoint = previousFirstPoints[i + 1];\n const previousSecondPoint = previousSecondPoints[i];\n const secondPoint = previousSecondPoints[i + 1];\n\n return {\n deltas: [\n ...result.deltas,\n this.computeDelta(\n previousFirstPoint,\n previousSecondPoint,\n firstPoint,\n secondPoint\n ),\n ],\n zooms: [\n ...result.zooms,\n this.computeZoom(\n previousFirstPoint,\n previousSecondPoint,\n firstPoint,\n secondPoint\n ),\n ],\n angles: [\n ...result.angles,\n this.computeAngle(\n previousFirstPoint,\n previousSecondPoint,\n firstPoint,\n secondPoint\n ),\n ],\n };\n }\n return result;\n },\n {\n deltas: [],\n zooms: [],\n angles: [],\n }\n );\n\n const delta = changes.deltas.reduce(\n (r, d) => Point.add(r, d),\n Point.create()\n );\n const zoom = changes.zooms.reduce((z, d) => z + d, 0);\n const angle = changes.angles.reduce((a, d) => a + d, 0);\n\n const center = Point.create(\n (previousFirstPoints[previousFirstPoints.length - 1].x +\n previousSecondPoints[previousSecondPoints.length - 1].x) /\n 2,\n (previousFirstPoints[previousFirstPoints.length - 1].y +\n previousSecondPoints[previousSecondPoints.length - 1].y) /\n 2\n );\n\n this.interactionApi?.beginInteraction();\n this.interactionApi?.zoomCameraToPoint(center, zoom);\n this.interactionApi?.panCameraByDelta(delta);\n this.interactionApi?.twistCamera(angle);\n }\n });\n }\n\n protected endTwoPointTouch(): void {\n this.previousFirstPoints = [];\n this.previousSecondPoints = [];\n }\n\n private computeDelta(\n previousPoint1: Point.Point,\n previousPoint2: Point.Point,\n point1: Point.Point,\n point2: Point.Point\n ): Point.Point {\n return Point.add(\n Point.subtract(point1, previousPoint1),\n Point.subtract(point2, previousPoint2)\n );\n }\n\n private computeZoom(\n previousPoint1: Point.Point,\n previousPoint2: Point.Point,\n point1: Point.Point,\n point2: Point.Point\n ): number {\n const distance =\n Point.distance(point1, point2) -\n Point.distance(previousPoint1, previousPoint2);\n return distance * 0.5;\n }\n\n private computeAngle(\n previousPoint1: Point.Point,\n previousPoint2: Point.Point,\n point1: Point.Point,\n point2: Point.Point\n ): number {\n const previousToCurrent = Matrix2.create(\n Point.subtract(previousPoint1, previousPoint2),\n Point.subtract(point1, point2)\n );\n return Angle.toDegrees(\n Math.atan2(\n Matrix2.determinant(previousToCurrent),\n Matrix2.dot(previousToCurrent)\n )\n );\n }\n}\n"]}
@@ -23,12 +23,10 @@ export class TouchInteractionHandler extends MultiTouchInteractionHandler {
23
23
  if (event.touches.length >= 1) {
24
24
  event.preventDefault();
25
25
  const touch1 = event.touches[0];
26
- const touch2 = event.touches[1];
27
26
  this.currentPosition1 = Point.create(touch1.screenX, touch1.screenY);
28
- this.currentPosition2 =
29
- touch2 != null
30
- ? Point.create(touch2.screenX, touch2.screenY)
31
- : undefined;
27
+ if (event.touches[1] != null) {
28
+ this.beginTwoPointTouch(this.currentPosition1, Point.create(event.touches[1].screenX, event.touches[1].screenY));
29
+ }
32
30
  window.addEventListener('touchmove', this.handleTouchMove, {
33
31
  passive: false,
34
32
  });
@@ -53,6 +51,7 @@ export class TouchInteractionHandler extends MultiTouchInteractionHandler {
53
51
  this.isInteracting = false;
54
52
  window.removeEventListener('touchmove', this.handleTouchMove);
55
53
  window.removeEventListener('touchend', this.handleTouchEnd);
54
+ this.endTwoPointTouch();
56
55
  }
57
56
  handleOnePointTouchMove(touch) {
58
57
  var _a, _b, _c;
@@ -1 +1 @@
1
- {"version":3,"file":"touchInteractionHandler.js","sourceRoot":"","sources":["../../../src/lib/interactions/touchInteractionHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Point } from '@vertexvis/geometry';\n\nimport { InteractionApi } from './interactionApi';\nimport { MultiTouchInteractionHandler } from './multiTouchInteractionHandler';\n\nexport class TouchInteractionHandler extends MultiTouchInteractionHandler {\n private isInteracting?: boolean;\n\n public constructor() {\n super();\n this.handleTouchStart = this.handleTouchStart.bind(this);\n this.handleTouchMove = this.handleTouchMove.bind(this);\n this.handleTouchEnd = this.handleTouchEnd.bind(this);\n }\n\n public dispose(): void {\n this.element?.removeEventListener('touchstart', this.handleTouchStart);\n super.dispose();\n }\n\n public initialize(element: HTMLElement, api: InteractionApi): void {\n super.initialize(element, api);\n\n element.addEventListener('touchstart', this.handleTouchStart);\n }\n\n private handleTouchStart(event: TouchEvent): void {\n if (event.touches.length >= 1) {\n event.preventDefault();\n\n const touch1 = event.touches[0];\n const touch2 = event.touches[1];\n\n this.currentPosition1 = Point.create(touch1.screenX, touch1.screenY);\n this.currentPosition2 =\n touch2 != null\n ? Point.create(touch2.screenX, touch2.screenY)\n : undefined;\n\n window.addEventListener('touchmove', this.handleTouchMove, {\n passive: false,\n });\n window.addEventListener('touchend', this.handleTouchEnd);\n }\n }\n\n private handleTouchMove(event: TouchEvent): void {\n event.preventDefault();\n\n if (event.touches.length === 1) {\n this.handleOnePointTouchMove(event.touches[0]);\n } else if (event.touches.length === 2) {\n const point1 = Point.create(\n event.touches[0].clientX,\n event.touches[0].clientY\n );\n const point2 = Point.create(\n event.touches[1].clientX,\n event.touches[1].clientY\n );\n\n this.handleTwoPointTouchMove(point1, point2);\n }\n }\n\n private handleTouchEnd(event: TouchEvent): void {\n event.preventDefault();\n\n this.interactionApi?.endInteraction();\n\n this.isInteracting = false;\n\n window.removeEventListener('touchmove', this.handleTouchMove);\n window.removeEventListener('touchend', this.handleTouchEnd);\n }\n\n private handleOnePointTouchMove(touch: Touch): void {\n const position = Point.create(touch.screenX, touch.screenY);\n\n if (this.currentPosition1 != null) {\n const delta = Point.subtract(position, this.currentPosition1);\n const threshold = this.interactionApi?.pixelThreshold(true) || 2;\n if (\n Point.distance(position, this.currentPosition1) >= threshold ||\n this.isInteracting\n ) {\n this.interactionApi?.beginInteraction();\n this.interactionApi?.rotateCamera(delta);\n this.isInteracting = true;\n }\n }\n\n this.currentPosition1 = position;\n }\n}\n"]}
1
+ {"version":3,"file":"touchInteractionHandler.js","sourceRoot":"","sources":["../../../src/lib/interactions/touchInteractionHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import { Point } from '@vertexvis/geometry';\n\nimport { InteractionApi } from './interactionApi';\nimport { MultiTouchInteractionHandler } from './multiTouchInteractionHandler';\n\nexport class TouchInteractionHandler extends MultiTouchInteractionHandler {\n private currentPosition1?: Point.Point;\n private isInteracting?: boolean;\n\n public constructor() {\n super();\n this.handleTouchStart = this.handleTouchStart.bind(this);\n this.handleTouchMove = this.handleTouchMove.bind(this);\n this.handleTouchEnd = this.handleTouchEnd.bind(this);\n }\n\n public dispose(): void {\n this.element?.removeEventListener('touchstart', this.handleTouchStart);\n super.dispose();\n }\n\n public initialize(element: HTMLElement, api: InteractionApi): void {\n super.initialize(element, api);\n\n element.addEventListener('touchstart', this.handleTouchStart);\n }\n\n private handleTouchStart(event: TouchEvent): void {\n if (event.touches.length >= 1) {\n event.preventDefault();\n\n const touch1 = event.touches[0];\n\n this.currentPosition1 = Point.create(touch1.screenX, touch1.screenY);\n\n if (event.touches[1] != null) {\n this.beginTwoPointTouch(\n this.currentPosition1,\n Point.create(event.touches[1].screenX, event.touches[1].screenY)\n );\n }\n\n window.addEventListener('touchmove', this.handleTouchMove, {\n passive: false,\n });\n window.addEventListener('touchend', this.handleTouchEnd);\n }\n }\n\n private handleTouchMove(event: TouchEvent): void {\n event.preventDefault();\n\n if (event.touches.length === 1) {\n this.handleOnePointTouchMove(event.touches[0]);\n } else if (event.touches.length === 2) {\n const point1 = Point.create(\n event.touches[0].clientX,\n event.touches[0].clientY\n );\n const point2 = Point.create(\n event.touches[1].clientX,\n event.touches[1].clientY\n );\n\n this.handleTwoPointTouchMove(point1, point2);\n }\n }\n\n private handleTouchEnd(event: TouchEvent): void {\n event.preventDefault();\n\n this.interactionApi?.endInteraction();\n\n this.isInteracting = false;\n\n window.removeEventListener('touchmove', this.handleTouchMove);\n window.removeEventListener('touchend', this.handleTouchEnd);\n\n this.endTwoPointTouch();\n }\n\n private handleOnePointTouchMove(touch: Touch): void {\n const position = Point.create(touch.screenX, touch.screenY);\n\n if (this.currentPosition1 != null) {\n const delta = Point.subtract(position, this.currentPosition1);\n const threshold = this.interactionApi?.pixelThreshold(true) || 2;\n if (\n Point.distance(position, this.currentPosition1) >= threshold ||\n this.isInteracting\n ) {\n this.interactionApi?.beginInteraction();\n this.interactionApi?.rotateCamera(delta);\n this.isInteracting = true;\n }\n }\n\n this.currentPosition1 = position;\n }\n}\n"]}
@@ -2,4 +2,5 @@
2
2
  * Copyright (c) 2024 Vertex Software LLC. All rights reserved.
3
3
  */
4
4
  export * from './controller';
5
+ export * from './model';
5
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/volume-intersection/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC","sourcesContent":["export * from './controller';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/volume-intersection/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC","sourcesContent":["export * from './controller';\nexport * from './model';\n"]}
@@ -0,0 +1,7 @@
1
+ /*!
2
+ * Copyright (c) 2024 Vertex Software LLC. All rights reserved.
3
+ */
4
+ export function requestAnimationFrame(callback) {
5
+ window.requestAnimationFrame(callback);
6
+ }
7
+ //# sourceMappingURL=window.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"window.js","sourceRoot":"","sources":["../../src/lib/window.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,qBAAqB,CAAC,QAAsB;EAC1D,MAAM,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC","sourcesContent":["export function requestAnimationFrame(callback: VoidFunction): void {\n window.requestAnimationFrame(callback);\n}\n"]}
@@ -15,7 +15,7 @@ export { T as TransformController } from './controller2.js';
15
15
  export { A as AngleUnits, g as AreaUnits, c as CrossSectioning, D as DistanceUnits, E as EntityType, F as FrameCameraBase, a as ReceivedFrame, b as ReceivedFrameImage, d as ReceivedFrameScene, e as ReceivedOrthographicCamera, f as ReceivedPerspectiveCamera, S as StandardView } from './streamAttributes.js';
16
16
  export { A as ArrowMarkup, C as CircleMarkup, F as FreeformMarkup } from './markup.js';
17
17
  export { V as Viewport } from './viewport.js';
18
- export { V as VolumeIntersectionQueryController } from './controller3.js';
18
+ export { V as VolumeIntersectionQueryController, a as VolumeIntersectionQueryModel } from './model2.js';
19
19
  import { c as createCommonjsModule } from './_commonjsHelpers.js';
20
20
 
21
21
  const ALMOST_ONE = 0.9999;