@cornerstonejs/tools 0.56.2 → 0.56.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -4
- package/src/constants/COLOR_LUT.ts +262 -0
- package/src/constants/index.ts +3 -0
- package/src/cursors/ImageMouseCursor.ts +39 -0
- package/src/cursors/MouseCursor.ts +114 -0
- package/src/cursors/SVGCursorDescriptor.ts +462 -0
- package/src/cursors/SVGMouseCursor.ts +145 -0
- package/src/cursors/elementCursor.ts +69 -0
- package/src/cursors/index.ts +24 -0
- package/src/cursors/setCursorForElement.ts +33 -0
- package/src/drawingSvg/_getHash.ts +9 -0
- package/src/drawingSvg/_setAttributesIfNecessary.ts +13 -0
- package/src/drawingSvg/_setNewAttributesIfValid.ts +10 -0
- package/src/drawingSvg/clearByToolType.ts +26 -0
- package/src/drawingSvg/draw.ts +16 -0
- package/src/drawingSvg/drawArrow.ts +82 -0
- package/src/drawingSvg/drawCircle.ts +62 -0
- package/src/drawingSvg/drawEllipse.ts +71 -0
- package/src/drawingSvg/drawHandles.ts +87 -0
- package/src/drawingSvg/drawLine.ts +70 -0
- package/src/drawingSvg/drawLink.ts +76 -0
- package/src/drawingSvg/drawLinkedTextBox.ts +64 -0
- package/src/drawingSvg/drawPolyline.ts +80 -0
- package/src/drawingSvg/drawRect.ts +70 -0
- package/src/drawingSvg/drawTextBox.ts +213 -0
- package/src/drawingSvg/getSvgDrawingHelper.ts +98 -0
- package/src/drawingSvg/index.ts +23 -0
- package/src/enums/AnnotationStyleStates.ts +22 -0
- package/src/enums/Events.ts +242 -0
- package/src/enums/SegmentationRepresentations.ts +12 -0
- package/src/enums/ToolBindings.ts +37 -0
- package/src/enums/ToolModes.ts +31 -0
- package/src/enums/Touch.ts +8 -0
- package/src/enums/index.js +16 -0
- package/src/eventDispatchers/annotationModifiedEventDispatcher.ts +41 -0
- package/src/eventDispatchers/cameraModifiedEventDispatcher.ts +41 -0
- package/src/eventDispatchers/imageRenderedEventDispatcher.ts +37 -0
- package/src/eventDispatchers/imageSpacingCalibratedEventDispatcher.ts +50 -0
- package/src/eventDispatchers/index.js +15 -0
- package/src/eventDispatchers/keyboardEventHandlers/index.js +4 -0
- package/src/eventDispatchers/keyboardEventHandlers/keyDown.ts +29 -0
- package/src/eventDispatchers/keyboardEventHandlers/keyUp.ts +33 -0
- package/src/eventDispatchers/keyboardToolEventDispatcher.ts +28 -0
- package/src/eventDispatchers/mouseEventHandlers/index.js +19 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseClick.ts +13 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseDoubleClick.ts +13 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseDown.ts +196 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseDownActivate.ts +35 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseDrag.ts +25 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseMove.ts +70 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseUp.ts +9 -0
- package/src/eventDispatchers/mouseEventHandlers/mouseWheel.ts +13 -0
- package/src/eventDispatchers/mouseToolEventDispatcher.ts +64 -0
- package/src/eventDispatchers/shared/customCallbackHandler.ts +73 -0
- package/src/eventDispatchers/shared/getActiveToolForKeyboardEvent.ts +58 -0
- package/src/eventDispatchers/shared/getActiveToolForMouseEvent.ts +61 -0
- package/src/eventDispatchers/shared/getActiveToolForTouchEvent.ts +64 -0
- package/src/eventDispatchers/shared/getMouseModifier.ts +30 -0
- package/src/eventDispatchers/shared/getToolsWithModesForMouseEvent.ts +56 -0
- package/src/eventDispatchers/shared/getToolsWithModesForTouchEvent.ts +54 -0
- package/src/eventDispatchers/touchEventHandlers/index.js +15 -0
- package/src/eventDispatchers/touchEventHandlers/touchDrag.ts +23 -0
- package/src/eventDispatchers/touchEventHandlers/touchEnd.ts +9 -0
- package/src/eventDispatchers/touchEventHandlers/touchPress.ts +13 -0
- package/src/eventDispatchers/touchEventHandlers/touchStart.ts +174 -0
- package/src/eventDispatchers/touchEventHandlers/touchStartActivate.ts +36 -0
- package/src/eventDispatchers/touchEventHandlers/touchTap.ts +9 -0
- package/src/eventDispatchers/touchToolEventDispatcher.ts +51 -0
- package/src/eventListeners/annotations/annotationModifiedListener.ts +22 -0
- package/src/eventListeners/annotations/annotationSelectionListener.ts +29 -0
- package/src/eventListeners/annotations/index.ts +4 -0
- package/src/eventListeners/index.ts +28 -0
- package/src/eventListeners/keyboard/index.ts +16 -0
- package/src/eventListeners/keyboard/keyDownListener.ts +99 -0
- package/src/eventListeners/mouse/getMouseEventPoints.ts +66 -0
- package/src/eventListeners/mouse/index.ts +55 -0
- package/src/eventListeners/mouse/mouseDoubleClickListener.ts +55 -0
- package/src/eventListeners/mouse/mouseDownListener.ts +519 -0
- package/src/eventListeners/mouse/mouseMoveListener.ts +33 -0
- package/src/eventListeners/segmentation/index.ts +11 -0
- package/src/eventListeners/segmentation/segmentationDataModifiedEventListener.ts +61 -0
- package/src/eventListeners/segmentation/segmentationModifiedEventListener.ts +32 -0
- package/src/eventListeners/segmentation/segmentationRepresentationModifiedEventListener.ts +15 -0
- package/src/eventListeners/segmentation/segmentationRepresentationRemovedEventListener.ts +16 -0
- package/src/eventListeners/touch/getTouchEventPoints.ts +75 -0
- package/src/eventListeners/touch/index.ts +37 -0
- package/src/eventListeners/touch/preventGhostClick.js +72 -0
- package/src/eventListeners/touch/touchStartListener.ts +499 -0
- package/src/eventListeners/wheel/index.ts +27 -0
- package/src/eventListeners/wheel/normalizeWheel.ts +69 -0
- package/src/eventListeners/wheel/wheelListener.ts +51 -0
- package/src/index.ts +133 -0
- package/src/init.ts +187 -0
- package/src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts +399 -0
- package/src/stateManagement/annotation/annotationLocking.ts +178 -0
- package/src/stateManagement/annotation/annotationSelection.ts +163 -0
- package/src/stateManagement/annotation/annotationState.ts +180 -0
- package/src/stateManagement/annotation/annotationVisibility.ts +156 -0
- package/src/stateManagement/annotation/config/ToolStyle.ts +265 -0
- package/src/stateManagement/annotation/config/getFont.ts +36 -0
- package/src/stateManagement/annotation/config/getState.ts +26 -0
- package/src/stateManagement/annotation/config/helpers.ts +55 -0
- package/src/stateManagement/annotation/config/index.ts +5 -0
- package/src/stateManagement/annotation/helpers/state.ts +83 -0
- package/src/stateManagement/annotation/index.ts +15 -0
- package/src/stateManagement/index.js +40 -0
- package/src/stateManagement/segmentation/SegmentationStateManager.ts +491 -0
- package/src/stateManagement/segmentation/activeSegmentation.ts +60 -0
- package/src/stateManagement/segmentation/addSegmentationRepresentations.ts +77 -0
- package/src/stateManagement/segmentation/addSegmentations.ts +27 -0
- package/src/stateManagement/segmentation/config/index.ts +29 -0
- package/src/stateManagement/segmentation/config/segmentationColor.ts +132 -0
- package/src/stateManagement/segmentation/config/segmentationConfig.ts +195 -0
- package/src/stateManagement/segmentation/config/segmentationVisibility.ts +171 -0
- package/src/stateManagement/segmentation/helpers/index.ts +3 -0
- package/src/stateManagement/segmentation/helpers/normalizeSegmentationInput.ts +35 -0
- package/src/stateManagement/segmentation/helpers/validateSegmentationInput.ts +41 -0
- package/src/stateManagement/segmentation/index.ts +22 -0
- package/src/stateManagement/segmentation/removeSegmentationsFromToolGroup.ts +85 -0
- package/src/stateManagement/segmentation/segmentIndex.ts +38 -0
- package/src/stateManagement/segmentation/segmentLocking.ts +72 -0
- package/src/stateManagement/segmentation/segmentationState.ts +429 -0
- package/src/stateManagement/segmentation/triggerSegmentationEvents.ts +157 -0
- package/src/store/SynchronizerManager/Synchronizer.ts +344 -0
- package/src/store/SynchronizerManager/createSynchronizer.ts +41 -0
- package/src/store/SynchronizerManager/destroy.ts +14 -0
- package/src/store/SynchronizerManager/destroySynchronizer.ts +25 -0
- package/src/store/SynchronizerManager/getAllSynchronizers.ts +12 -0
- package/src/store/SynchronizerManager/getSynchronizer.ts +13 -0
- package/src/store/SynchronizerManager/getSynchronizersForViewport.ts +44 -0
- package/src/store/SynchronizerManager/index.js +15 -0
- package/src/store/ToolGroupManager/ToolGroup.ts +679 -0
- package/src/store/ToolGroupManager/createToolGroup.ts +33 -0
- package/src/store/ToolGroupManager/destroy.ts +24 -0
- package/src/store/ToolGroupManager/destroyToolGroup.ts +26 -0
- package/src/store/ToolGroupManager/getAllToolGroups.ts +12 -0
- package/src/store/ToolGroupManager/getToolGroup.ts +14 -0
- package/src/store/ToolGroupManager/getToolGroupForViewport.ts +44 -0
- package/src/store/ToolGroupManager/getToolGroupsWithToolName.ts +33 -0
- package/src/store/ToolGroupManager/index.ts +17 -0
- package/src/store/addEnabledElement.ts +137 -0
- package/src/store/addTool.ts +56 -0
- package/src/store/cancelActiveManipulations.ts +30 -0
- package/src/store/filterMoveableAnnotationTools.ts +61 -0
- package/src/store/filterToolsWithAnnotationsForElement.ts +51 -0
- package/src/store/filterToolsWithMoveableHandles.ts +51 -0
- package/src/store/index.ts +29 -0
- package/src/store/removeEnabledElement.ts +132 -0
- package/src/store/state.ts +57 -0
- package/src/store/svgNodeCache.ts +7 -0
- package/src/synchronizers/callbacks/areViewportsCoplanar .ts +12 -0
- package/src/synchronizers/callbacks/cameraSyncCallback.ts +33 -0
- package/src/synchronizers/callbacks/stackImageSyncCallback.ts +157 -0
- package/src/synchronizers/callbacks/voiSyncCallback.ts +51 -0
- package/src/synchronizers/callbacks/zoomPanSyncCallback.ts +43 -0
- package/src/synchronizers/index.ts +11 -0
- package/src/synchronizers/synchronizers/createCameraPositionSynchronizer.ts +25 -0
- package/src/synchronizers/synchronizers/createStackImageSynchronizer.ts +25 -0
- package/src/synchronizers/synchronizers/createVOISynchronizer.ts +24 -0
- package/src/synchronizers/synchronizers/createZoomPanSynchronizer.ts +25 -0
- package/src/synchronizers/synchronizers/index.ts +11 -0
- package/src/tools/CrosshairsTool.ts +2693 -0
- package/src/tools/MIPJumpToClickTool.ts +99 -0
- package/src/tools/MagnifyTool.ts +319 -0
- package/src/tools/PanTool.ts +58 -0
- package/src/tools/PlanarRotateTool.ts +77 -0
- package/src/tools/ReferenceCursors.ts +466 -0
- package/src/tools/ReferenceLinesTool.ts +279 -0
- package/src/tools/ScaleOverlayTool.ts +685 -0
- package/src/tools/StackScrollTool.ts +97 -0
- package/src/tools/StackScrollToolMouseWheelTool.ts +58 -0
- package/src/tools/TrackballRotateTool.ts +141 -0
- package/src/tools/VolumeRotateMouseWheelTool.ts +86 -0
- package/src/tools/WindowLevelTool.ts +260 -0
- package/src/tools/ZoomTool.ts +293 -0
- package/src/tools/annotation/AngleTool.ts +835 -0
- package/src/tools/annotation/ArrowAnnotateTool.ts +820 -0
- package/src/tools/annotation/BidirectionalTool.ts +1350 -0
- package/src/tools/annotation/CircleROITool.ts +1070 -0
- package/src/tools/annotation/CobbAngleTool.ts +815 -0
- package/src/tools/annotation/DragProbeTool.ts +213 -0
- package/src/tools/annotation/EllipticalROITool.ts +1223 -0
- package/src/tools/annotation/LengthTool.ts +861 -0
- package/src/tools/annotation/PlanarFreehandROITool.ts +636 -0
- package/src/tools/annotation/ProbeTool.ts +681 -0
- package/src/tools/annotation/RectangleROITool.ts +1028 -0
- package/src/tools/annotation/planarFreehandROITool/closedContourEditLoop.ts +488 -0
- package/src/tools/annotation/planarFreehandROITool/drawLoop.ts +462 -0
- package/src/tools/annotation/planarFreehandROITool/editLoopCommon.ts +331 -0
- package/src/tools/annotation/planarFreehandROITool/findOpenUShapedContourVectorToPeak.ts +74 -0
- package/src/tools/annotation/planarFreehandROITool/openContourEditLoop.ts +612 -0
- package/src/tools/annotation/planarFreehandROITool/openContourEndEditLoop.ts +74 -0
- package/src/tools/annotation/planarFreehandROITool/renderMethods.ts +407 -0
- package/src/tools/base/AnnotationDisplayTool.ts +228 -0
- package/src/tools/base/AnnotationTool.ts +307 -0
- package/src/tools/base/BaseTool.ts +215 -0
- package/src/tools/base/index.ts +4 -0
- package/src/tools/displayTools/Contour/addContourToElement.ts +135 -0
- package/src/tools/displayTools/Contour/contourDisplay.ts +252 -0
- package/src/tools/displayTools/Contour/index.ts +3 -0
- package/src/tools/displayTools/Contour/removeContourFromElement.ts +35 -0
- package/src/tools/displayTools/Labelmap/addLabelmapToElement.ts +57 -0
- package/src/tools/displayTools/Labelmap/index.ts +4 -0
- package/src/tools/displayTools/Labelmap/labelmapConfig.ts +37 -0
- package/src/tools/displayTools/Labelmap/labelmapDisplay.ts +461 -0
- package/src/tools/displayTools/Labelmap/removeLabelmapFromElement.ts +27 -0
- package/src/tools/displayTools/Labelmap/validateRepresentationData.ts +30 -0
- package/src/tools/displayTools/SegmentationDisplayTool.ts +198 -0
- package/src/tools/index.ts +84 -0
- package/src/tools/segmentation/BrushTool.ts +474 -0
- package/src/tools/segmentation/CircleScissorsTool.ts +365 -0
- package/src/tools/segmentation/PaintFillTool.ts +370 -0
- package/src/tools/segmentation/RectangleROIStartEndThresholdTool.ts +471 -0
- package/src/tools/segmentation/RectangleROIThresholdTool.ts +281 -0
- package/src/tools/segmentation/RectangleScissorsTool.ts +382 -0
- package/src/tools/segmentation/SphereScissorsTool.ts +368 -0
- package/src/tools/segmentation/strategies/eraseCircle.ts +30 -0
- package/src/tools/segmentation/strategies/eraseRectangle.ts +81 -0
- package/src/tools/segmentation/strategies/eraseSphere.ts +27 -0
- package/src/tools/segmentation/strategies/fillCircle.ts +185 -0
- package/src/tools/segmentation/strategies/fillRectangle.ts +110 -0
- package/src/tools/segmentation/strategies/fillSphere.ts +88 -0
- package/src/tools/segmentation/strategies/index.ts +9 -0
- package/src/types/AnnotationGroupSelector.ts +7 -0
- package/src/types/AnnotationStyle.ts +42 -0
- package/src/types/AnnotationTypes.ts +109 -0
- package/src/types/BoundsIJK.ts +5 -0
- package/src/types/CINETypes.ts +32 -0
- package/src/types/ContourTypes.ts +26 -0
- package/src/types/CursorTypes.ts +12 -0
- package/src/types/EventTypes.ts +657 -0
- package/src/types/FloodFillTypes.ts +19 -0
- package/src/types/IAnnotationManager.ts +89 -0
- package/src/types/IDistance.ts +16 -0
- package/src/types/IPoints.ts +18 -0
- package/src/types/ISetToolModeOptions.ts +29 -0
- package/src/types/ISynchronizerEventHandler.ts +11 -0
- package/src/types/IToolClassReference.ts +5 -0
- package/src/types/IToolGroup.ts +72 -0
- package/src/types/ITouchPoints.ts +14 -0
- package/src/types/InteractionTypes.ts +6 -0
- package/src/types/InternalToolTypes.ts +19 -0
- package/src/types/JumpToSliceOptions.ts +7 -0
- package/src/types/LabelmapTypes.ts +41 -0
- package/src/types/PlanarBoundingBox.ts +8 -0
- package/src/types/SVGDrawingHelper.ts +10 -0
- package/src/types/ScrollOptions.ts +9 -0
- package/src/types/SegmentationStateTypes.ts +248 -0
- package/src/types/ToolHandle.ts +26 -0
- package/src/types/ToolProps.ts +16 -0
- package/src/types/ToolSpecificAnnotationTypes.ts +311 -0
- package/src/types/index.ts +115 -0
- package/src/utilities/boundingBox/extend2DBoundingBoxInViewAxis.ts +29 -0
- package/src/utilities/boundingBox/getBoundingBoxAroundShape.ts +57 -0
- package/src/utilities/boundingBox/index.ts +4 -0
- package/src/utilities/calibrateImageSpacing.ts +46 -0
- package/src/utilities/cine/events.ts +9 -0
- package/src/utilities/cine/index.ts +5 -0
- package/src/utilities/cine/playClip.ts +435 -0
- package/src/utilities/cine/state.ts +18 -0
- package/src/utilities/clip.js +30 -0
- package/src/utilities/debounce.js +217 -0
- package/src/utilities/drawing/getTextBoxCoordsCanvas.ts +45 -0
- package/src/utilities/drawing/index.ts +3 -0
- package/src/utilities/dynamicVolume/getDataInTime.ts +110 -0
- package/src/utilities/dynamicVolume/index.ts +2 -0
- package/src/utilities/getAnnotationNearPoint.ts +130 -0
- package/src/utilities/getModalityUnit.ts +11 -0
- package/src/utilities/getToolsWithModesForElement.ts +52 -0
- package/src/utilities/index.ts +68 -0
- package/src/utilities/isObject.js +29 -0
- package/src/utilities/math/angle/angleBetweenLines.ts +29 -0
- package/src/utilities/math/circle/_types.ts +6 -0
- package/src/utilities/math/circle/getCanvasCircleCorners.ts +23 -0
- package/src/utilities/math/circle/getCanvasCircleRadius.ts +16 -0
- package/src/utilities/math/circle/index.ts +4 -0
- package/src/utilities/math/ellipse/getCanvasEllipseCorners.ts +26 -0
- package/src/utilities/math/ellipse/index.ts +4 -0
- package/src/utilities/math/ellipse/pointInEllipse.ts +38 -0
- package/src/utilities/math/ellipse/pointInEllipsoidWithConstraint.ts +35 -0
- package/src/utilities/math/index.ts +8 -0
- package/src/utilities/math/line/distanceToPoint.ts +24 -0
- package/src/utilities/math/line/distanceToPointSquared.ts +44 -0
- package/src/utilities/math/line/index.ts +5 -0
- package/src/utilities/math/line/intersectLine.ts +92 -0
- package/src/utilities/math/midPoint.ts +24 -0
- package/src/utilities/math/point/distanceToPoint.ts +22 -0
- package/src/utilities/math/point/index.ts +3 -0
- package/src/utilities/math/polyline/addCanvasPointsToArray.ts +62 -0
- package/src/utilities/math/polyline/calculateAreaOfPoints.ts +23 -0
- package/src/utilities/math/polyline/getIntersectionWithPolyline.ts +182 -0
- package/src/utilities/math/polyline/getSubPixelSpacingAndXYDirections.ts +99 -0
- package/src/utilities/math/polyline/index.ts +19 -0
- package/src/utilities/math/polyline/planarFreehandROIInternalTypes.ts +36 -0
- package/src/utilities/math/polyline/pointCanProjectOnLine.ts +57 -0
- package/src/utilities/math/polyline/pointsAreWithinCloseContourProximity.ts +15 -0
- package/src/utilities/math/rectangle/distanceToPoint.ts +82 -0
- package/src/utilities/math/rectangle/index.ts +3 -0
- package/src/utilities/math/sphere/index.ts +3 -0
- package/src/utilities/math/sphere/pointInSphere.ts +31 -0
- package/src/utilities/math/vec2/findClosestPoint.ts +40 -0
- package/src/utilities/math/vec2/index.ts +4 -0
- package/src/utilities/math/vec2/liangBarksyClip.ts +84 -0
- package/src/utilities/orientation/getOrientationStringLPS.ts +52 -0
- package/src/utilities/orientation/index.ts +4 -0
- package/src/utilities/orientation/invertOrientationStringLPS.ts +21 -0
- package/src/utilities/planar/filterAnnotationsForDisplay.ts +68 -0
- package/src/utilities/planar/filterAnnotationsWithinSlice.ts +85 -0
- package/src/utilities/planar/getPointInLineOfSightWithCriteria.ts +104 -0
- package/src/utilities/planar/getWorldWidthAndHeightFromCorners.ts +51 -0
- package/src/utilities/planar/getWorldWidthAndHeightFromTwoPoints.ts +51 -0
- package/src/utilities/planar/index.ts +18 -0
- package/src/utilities/planarFreehandROITool/index.ts +7 -0
- package/src/utilities/planarFreehandROITool/interpolateAnnotation.ts +87 -0
- package/src/utilities/planarFreehandROITool/interpolatePoints.ts +214 -0
- package/src/utilities/planarFreehandROITool/interpolation/algorithms/bspline.ts +55 -0
- package/src/utilities/planarFreehandROITool/interpolation/interpolateSegmentPoints.ts +90 -0
- package/src/utilities/pointInShapeCallback.ts +138 -0
- package/src/utilities/pointInSurroundingSphereCallback.ts +188 -0
- package/src/utilities/rectangleROITool/getBoundsIJKFromRectangleAnnotations.ts +76 -0
- package/src/utilities/rectangleROITool/index.ts +3 -0
- package/src/utilities/scroll.ts +62 -0
- package/src/utilities/segmentation/brushSizeForToolGroup.ts +72 -0
- package/src/utilities/segmentation/brushThresholdForToolGroup.ts +65 -0
- package/src/utilities/segmentation/createLabelmapVolumeForViewport.ts +74 -0
- package/src/utilities/segmentation/createMergedLabelmapForIndex.ts +65 -0
- package/src/utilities/segmentation/floodFill.ts +194 -0
- package/src/utilities/segmentation/getDefaultRepresentationConfig.ts +20 -0
- package/src/utilities/segmentation/index.ts +33 -0
- package/src/utilities/segmentation/isValidRepresentationConfig.ts +22 -0
- package/src/utilities/segmentation/rectangleROIThresholdVolumeByRange.ts +91 -0
- package/src/utilities/segmentation/thresholdSegmentationByRange.ts +129 -0
- package/src/utilities/segmentation/thresholdVolumeByRange.ts +150 -0
- package/src/utilities/segmentation/triggerSegmentationRender.ts +206 -0
- package/src/utilities/segmentation/utilities.ts +116 -0
- package/src/utilities/stackPrefetch/index.ts +8 -0
- package/src/utilities/stackPrefetch/stackPrefetch.ts +405 -0
- package/src/utilities/stackPrefetch/state.ts +17 -0
- package/src/utilities/throttle.js +69 -0
- package/src/utilities/touch/index.ts +246 -0
- package/src/utilities/triggerAnnotationRender.ts +237 -0
- package/src/utilities/triggerAnnotationRenderForViewportIds.ts +18 -0
- package/src/utilities/viewport/index.ts +5 -0
- package/src/utilities/viewport/isViewportPreScaled.ts +24 -0
- package/src/utilities/viewport/jumpToSlice.ts +73 -0
- package/src/utilities/viewport/jumpToWorld.ts +58 -0
- package/src/utilities/viewportFilters/filterViewportsWithFrameOfReferenceUID.ts +28 -0
- package/src/utilities/viewportFilters/filterViewportsWithParallelNormals.ts +26 -0
- package/src/utilities/viewportFilters/filterViewportsWithSameOrientation.ts +15 -0
- package/src/utilities/viewportFilters/filterViewportsWithToolEnabled.ts +72 -0
- package/src/utilities/viewportFilters/getViewportIdsWithToolToRender.ts +45 -0
- package/src/utilities/viewportFilters/index.ts +11 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { getEnabledElement } from '@cornerstonejs/core';
|
|
2
|
+
import type { Types } from '@cornerstonejs/core';
|
|
3
|
+
|
|
4
|
+
import { ITouchPoints } from '../../types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Given a native touch event, get the associated cornerstone3D enabled element
|
|
8
|
+
* and derive a set of coordinates useful for tools.
|
|
9
|
+
* @param evt - The Touch event.
|
|
10
|
+
* @param element - The DOM HTMLDivElement that the event was triggered on.
|
|
11
|
+
* @returns The points related to the event in the form of a `IPoints` object containing
|
|
12
|
+
* the following properties: `page`, `client`, `canvas`, and `world` details of the event.
|
|
13
|
+
*/
|
|
14
|
+
export default function getTouchEventPoints(
|
|
15
|
+
evt: TouchEvent,
|
|
16
|
+
element?: HTMLDivElement
|
|
17
|
+
): ITouchPoints[] {
|
|
18
|
+
const elementToUse = element || (evt.currentTarget as HTMLDivElement);
|
|
19
|
+
const touches = evt.type === 'touchend' ? evt.changedTouches : evt.touches;
|
|
20
|
+
return Object.keys(touches).map((i) => {
|
|
21
|
+
const clientPoint = _clientToPoint(touches[i]);
|
|
22
|
+
const pagePoint = _pageToPoint(touches[i]);
|
|
23
|
+
const canvasPoint = _pagePointsToCanvasPoints(elementToUse, pagePoint);
|
|
24
|
+
const { viewport } = getEnabledElement(elementToUse);
|
|
25
|
+
const worldPoint = viewport.canvasToWorld(canvasPoint);
|
|
26
|
+
return {
|
|
27
|
+
page: pagePoint,
|
|
28
|
+
client: clientPoint,
|
|
29
|
+
canvas: canvasPoint,
|
|
30
|
+
world: worldPoint,
|
|
31
|
+
touch: {
|
|
32
|
+
identifier: i,
|
|
33
|
+
radiusX: touches[i].radiusX,
|
|
34
|
+
radiusY: touches[i].radiusY,
|
|
35
|
+
force: touches[i].force,
|
|
36
|
+
rotationAngle: touches[i].rotationAngle,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Converts point from page coordinates to canvas coordinates.
|
|
44
|
+
* @param element - HTMLDivElement
|
|
45
|
+
* @param pagePoint - Point in page coordinates pageX and pageY
|
|
46
|
+
*
|
|
47
|
+
* @returns The canvas coordinate points
|
|
48
|
+
*/
|
|
49
|
+
function _pagePointsToCanvasPoints(
|
|
50
|
+
element: HTMLDivElement,
|
|
51
|
+
pagePoint: Types.Point2
|
|
52
|
+
): Types.Point2 {
|
|
53
|
+
const rect = element.getBoundingClientRect();
|
|
54
|
+
return [
|
|
55
|
+
pagePoint[0] - rect.left - window.pageXOffset,
|
|
56
|
+
pagePoint[1] - rect.top - window.pageYOffset,
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Converts the event's `pageX` and `pageY` properties to Types.Point2 format
|
|
62
|
+
*
|
|
63
|
+
* @param touch - The Touch
|
|
64
|
+
*/
|
|
65
|
+
function _pageToPoint(touch: Touch): Types.Point2 {
|
|
66
|
+
return [touch.pageX, touch.pageY];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Converts the event's `clientX` and `clientY` properties to Types.Point2 format
|
|
71
|
+
* @param evt - The Touch `Event`
|
|
72
|
+
*/
|
|
73
|
+
function _clientToPoint(touch: Touch): Types.Point2 {
|
|
74
|
+
return [touch.clientX, touch.clientY];
|
|
75
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import preventGhostClick from './preventGhostClick';
|
|
2
|
+
import touchStartListener from './touchStartListener';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Removes touch event listeners for native touch event. Enables
|
|
6
|
+
* vtk.js tools flavored events that build on top of existing events to
|
|
7
|
+
* provide more helpful information.
|
|
8
|
+
*
|
|
9
|
+
* @private
|
|
10
|
+
* @param element - The DOM element to remove event listeners from.
|
|
11
|
+
*/
|
|
12
|
+
function disable(element: HTMLDivElement): void {
|
|
13
|
+
preventGhostClick.disable(element);
|
|
14
|
+
element.removeEventListener('touchstart', touchStartListener);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Registers touch event listeners for native touch event. Enables
|
|
19
|
+
* vtk.js tools flavored events that build on top of existing events to
|
|
20
|
+
* provide more helpful information.
|
|
21
|
+
*
|
|
22
|
+
* @private
|
|
23
|
+
* @param element - The DOM element to register event listeners on.
|
|
24
|
+
*/
|
|
25
|
+
function enable(element: HTMLDivElement): void {
|
|
26
|
+
// Prevent handlers from being attached multiple times
|
|
27
|
+
disable(element);
|
|
28
|
+
preventGhostClick.enable(element);
|
|
29
|
+
element.addEventListener('touchstart', touchStartListener, {
|
|
30
|
+
passive: false,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default {
|
|
35
|
+
enable,
|
|
36
|
+
disable,
|
|
37
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Functions to prevent ghost clicks following a touch
|
|
2
|
+
// Since the event lifecycle is touchstart, mousedown, touchend, mouseup
|
|
3
|
+
// we want to prevent mousedown and mouseup events after touch events
|
|
4
|
+
// All credit to @kosich
|
|
5
|
+
// https://gist.github.com/kosich/23188dd86633b6c2efb7
|
|
6
|
+
|
|
7
|
+
const antiGhostDelay = 2000,
|
|
8
|
+
pointerType = {
|
|
9
|
+
mouse: 0,
|
|
10
|
+
touch: 1,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
let lastInteractionType, lastInteractionTime;
|
|
14
|
+
|
|
15
|
+
function handleTap(type, e) {
|
|
16
|
+
const now = Date.now();
|
|
17
|
+
|
|
18
|
+
if (type !== lastInteractionType) {
|
|
19
|
+
if (now - lastInteractionTime <= antiGhostDelay) {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
e.stopPropagation();
|
|
22
|
+
e.stopImmediatePropagation();
|
|
23
|
+
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
lastInteractionType = type;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
lastInteractionTime = now;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Cacheing the function references
|
|
34
|
+
// Necessary because a new function reference is created after .bind() is called
|
|
35
|
+
// http://stackoverflow.com/questions/11565471/removing-event-listener-which-was-added-with-bind
|
|
36
|
+
const handleTapMouse = handleTap.bind(null, pointerType.mouse);
|
|
37
|
+
const handleTapTouch = handleTap.bind(null, pointerType.touch);
|
|
38
|
+
|
|
39
|
+
function attachEvents(element, eventList, interactionType) {
|
|
40
|
+
const tapHandler = interactionType ? handleTapMouse : handleTapTouch;
|
|
41
|
+
|
|
42
|
+
eventList.forEach(function (eventName) {
|
|
43
|
+
element.addEventListener(eventName, tapHandler, { passive: false });
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function removeEvents(element, eventList, interactionType) {
|
|
48
|
+
const tapHandler = interactionType ? handleTapMouse : handleTapTouch;
|
|
49
|
+
|
|
50
|
+
eventList.forEach(function (eventName) {
|
|
51
|
+
element.removeEventListener(eventName, tapHandler);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const mouseEvents = ['mousedown', 'mouseup', 'mousemove'];
|
|
56
|
+
const touchEvents = ['touchstart', 'touchend'];
|
|
57
|
+
|
|
58
|
+
function disable(element) {
|
|
59
|
+
removeEvents(element, mouseEvents, pointerType.mouse);
|
|
60
|
+
removeEvents(element, touchEvents, pointerType.touch);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function enable(element) {
|
|
64
|
+
disable(element);
|
|
65
|
+
attachEvents(element, mouseEvents, pointerType.mouse);
|
|
66
|
+
attachEvents(element, touchEvents, pointerType.touch);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default {
|
|
70
|
+
enable,
|
|
71
|
+
disable,
|
|
72
|
+
};
|
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import { getEnabledElement, triggerEvent } from '@cornerstonejs/core';
|
|
2
|
+
import Events from '../../enums/Events';
|
|
3
|
+
import { Swipe } from '../../enums/Touch';
|
|
4
|
+
|
|
5
|
+
import { EventTypes, ITouchPoints, IPoints, IDistance } from '../../types';
|
|
6
|
+
|
|
7
|
+
import getTouchEventPoints from './getTouchEventPoints';
|
|
8
|
+
import {
|
|
9
|
+
copyPoints,
|
|
10
|
+
copyPointsList,
|
|
11
|
+
getDeltaDistanceBetweenIPoints,
|
|
12
|
+
getDeltaDistance,
|
|
13
|
+
getDeltaPoints,
|
|
14
|
+
getMeanTouchPoints,
|
|
15
|
+
// getRotation
|
|
16
|
+
} from '../../utilities/touch';
|
|
17
|
+
import { Settings } from '@cornerstonejs/core';
|
|
18
|
+
|
|
19
|
+
const runtimeSettings = Settings.getRuntimeSettings();
|
|
20
|
+
|
|
21
|
+
const {
|
|
22
|
+
TOUCH_START,
|
|
23
|
+
TOUCH_START_ACTIVATE,
|
|
24
|
+
TOUCH_PRESS,
|
|
25
|
+
TOUCH_DRAG,
|
|
26
|
+
TOUCH_END,
|
|
27
|
+
TOUCH_TAP,
|
|
28
|
+
TOUCH_SWIPE,
|
|
29
|
+
} = Events;
|
|
30
|
+
|
|
31
|
+
interface ITouchTapListnenerState {
|
|
32
|
+
element: HTMLDivElement;
|
|
33
|
+
renderingEngineId: string;
|
|
34
|
+
viewportId: string;
|
|
35
|
+
startPointsList: ITouchPoints[];
|
|
36
|
+
tapMaxDistance: number;
|
|
37
|
+
tapTimeout: ReturnType<typeof setTimeout>;
|
|
38
|
+
taps: number;
|
|
39
|
+
tapToleranceMs: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface ITouchStartListenerState {
|
|
43
|
+
element: HTMLDivElement;
|
|
44
|
+
renderingEngineId: string;
|
|
45
|
+
viewportId: string;
|
|
46
|
+
startPointsList: ITouchPoints[];
|
|
47
|
+
lastPointsList: ITouchPoints[];
|
|
48
|
+
|
|
49
|
+
// only trigger one touch event in the case the user puts down multiple fingers
|
|
50
|
+
isTouchStart: boolean;
|
|
51
|
+
startTime: Date;
|
|
52
|
+
|
|
53
|
+
// handle long press
|
|
54
|
+
pressTimeout: ReturnType<typeof setTimeout>;
|
|
55
|
+
pressDelay: number;
|
|
56
|
+
pressMaxDistance: number;
|
|
57
|
+
accumulatedDistance: IDistance;
|
|
58
|
+
|
|
59
|
+
// handle swipes
|
|
60
|
+
swipeDistanceThreshold: number;
|
|
61
|
+
swiped: boolean;
|
|
62
|
+
swipeToleranceMs: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const zeroIPoint: IPoints = {
|
|
66
|
+
page: [0, 0],
|
|
67
|
+
client: [0, 0],
|
|
68
|
+
canvas: [0, 0],
|
|
69
|
+
world: [0, 0, 0],
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const zeroIDistance: IDistance = {
|
|
73
|
+
page: 0,
|
|
74
|
+
client: 0,
|
|
75
|
+
canvas: 0,
|
|
76
|
+
world: 0,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// STATE
|
|
80
|
+
const defaultState: ITouchStartListenerState = {
|
|
81
|
+
renderingEngineId: undefined,
|
|
82
|
+
viewportId: undefined,
|
|
83
|
+
element: null,
|
|
84
|
+
startPointsList: [
|
|
85
|
+
{
|
|
86
|
+
...zeroIPoint,
|
|
87
|
+
touch: null,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
lastPointsList: [
|
|
91
|
+
{
|
|
92
|
+
...zeroIPoint,
|
|
93
|
+
touch: null,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
isTouchStart: false,
|
|
97
|
+
startTime: null,
|
|
98
|
+
|
|
99
|
+
pressTimeout: null,
|
|
100
|
+
pressDelay: 700,
|
|
101
|
+
pressMaxDistance: 5,
|
|
102
|
+
accumulatedDistance: zeroIDistance,
|
|
103
|
+
|
|
104
|
+
swipeDistanceThreshold: 48,
|
|
105
|
+
swiped: false,
|
|
106
|
+
swipeToleranceMs: 300, // user has 300ms to swipe after touch start or no swipe will trigger
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// TODO: these values should be configurable to handle different use cases such
|
|
110
|
+
// as pen, left/right handed, index finger vs thumb, etc. These current values
|
|
111
|
+
// assume thumb usage for single finger and index/middle finger for two finger
|
|
112
|
+
// gestures in an attempt to cover the 90% use case.
|
|
113
|
+
const defaultTapState: ITouchTapListnenerState = {
|
|
114
|
+
renderingEngineId: undefined,
|
|
115
|
+
viewportId: undefined,
|
|
116
|
+
element: null,
|
|
117
|
+
startPointsList: [
|
|
118
|
+
{
|
|
119
|
+
...zeroIPoint,
|
|
120
|
+
touch: null,
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
taps: 0,
|
|
124
|
+
tapTimeout: null,
|
|
125
|
+
tapMaxDistance: 24,
|
|
126
|
+
tapToleranceMs: 300,
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
let state: ITouchStartListenerState = JSON.parse(JSON.stringify(defaultState));
|
|
130
|
+
let tapState: ITouchTapListnenerState = JSON.parse(
|
|
131
|
+
JSON.stringify(defaultTapState)
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
function triggerEventCallback(ele, name, eventDetail) {
|
|
135
|
+
if (runtimeSettings.get('debug')) {
|
|
136
|
+
if (name === 'CORNERSTONE_TOOLS_TOUCH_DRAG') {
|
|
137
|
+
console.debug(name);
|
|
138
|
+
} else {
|
|
139
|
+
console.debug(name, eventDetail);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return triggerEvent(ele, name, eventDetail);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Listens to touch events from the DOM (touchstart, touchmove, touchend)
|
|
147
|
+
* and depending on interaction and further interaction can emit the
|
|
148
|
+
* following touch events:
|
|
149
|
+
*
|
|
150
|
+
* - TOUCH_START
|
|
151
|
+
* - TOUCH_START_ACTIVATE
|
|
152
|
+
* - TOUCH_PRESS
|
|
153
|
+
* - TOUCH_DRAG (move while down)
|
|
154
|
+
* - TOUCH_SWIPE
|
|
155
|
+
* - TOUCH_END (also an end for multi touch)
|
|
156
|
+
*
|
|
157
|
+
* - TOUCH_TAP
|
|
158
|
+
*
|
|
159
|
+
* @param evt - The Touch event (touchstart).
|
|
160
|
+
* @private
|
|
161
|
+
*/
|
|
162
|
+
function touchStartListener(evt: TouchEvent) {
|
|
163
|
+
// if a user adds an extra finger when a touch/multi touch has already started
|
|
164
|
+
// don't trigger another touch.
|
|
165
|
+
state.element = <HTMLDivElement>evt.currentTarget;
|
|
166
|
+
const enabledElement = getEnabledElement(state.element);
|
|
167
|
+
const { renderingEngineId, viewportId } = enabledElement;
|
|
168
|
+
state.renderingEngineId = renderingEngineId;
|
|
169
|
+
state.viewportId = viewportId;
|
|
170
|
+
// this prevents multiple start firing
|
|
171
|
+
if (state.isTouchStart) return;
|
|
172
|
+
// this will clear on touchstart and touchend
|
|
173
|
+
clearTimeout(state.pressTimeout);
|
|
174
|
+
state.pressTimeout = setTimeout(() => _onTouchPress(evt), state.pressDelay);
|
|
175
|
+
|
|
176
|
+
_onTouchStart(evt);
|
|
177
|
+
document.addEventListener('touchmove', _onTouchDrag); // also checks for swipe
|
|
178
|
+
document.addEventListener('touchend', _onTouchEnd); // also checks for tap
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* _onTouchPress - Handle emission of touchstart events which are held down for a longer
|
|
183
|
+
* period of time
|
|
184
|
+
*
|
|
185
|
+
* @private
|
|
186
|
+
* @param evt - The touch event (touchstart)
|
|
187
|
+
*/
|
|
188
|
+
function _onTouchPress(evt: TouchEvent) {
|
|
189
|
+
const totalDistance = state.accumulatedDistance.canvas;
|
|
190
|
+
if (totalDistance > state.pressMaxDistance) return;
|
|
191
|
+
const eventDetail: EventTypes.TouchPressEventDetail = {
|
|
192
|
+
event: evt, // touchstart native event
|
|
193
|
+
eventName: TOUCH_PRESS,
|
|
194
|
+
renderingEngineId: state.renderingEngineId,
|
|
195
|
+
viewportId: state.viewportId,
|
|
196
|
+
camera: {},
|
|
197
|
+
element: state.element,
|
|
198
|
+
startPointsList: copyPointsList(state.startPointsList),
|
|
199
|
+
lastPointsList: copyPointsList(state.lastPointsList),
|
|
200
|
+
startPoints: copyPoints(getMeanTouchPoints(state.startPointsList)),
|
|
201
|
+
lastPoints: copyPoints(getMeanTouchPoints(state.lastPointsList)),
|
|
202
|
+
};
|
|
203
|
+
triggerEventCallback(eventDetail.element, TOUCH_PRESS, eventDetail);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* _onTouchStart - Handle emission of touchstart events.
|
|
208
|
+
*
|
|
209
|
+
* @private
|
|
210
|
+
* @param evt - The touch event (touchstart)
|
|
211
|
+
*/
|
|
212
|
+
function _onTouchStart(evt: TouchEvent) {
|
|
213
|
+
state.isTouchStart = true;
|
|
214
|
+
state.startTime = new Date();
|
|
215
|
+
const startPointsList = getTouchEventPoints(evt, state.element);
|
|
216
|
+
const startPoints = getMeanTouchPoints(startPointsList);
|
|
217
|
+
const deltaPoints = zeroIPoint;
|
|
218
|
+
const deltaDistance = zeroIDistance;
|
|
219
|
+
// deltaRotation same as deltaDistance but values are theta
|
|
220
|
+
const eventDetail: EventTypes.TouchStartEventDetail = {
|
|
221
|
+
event: evt,
|
|
222
|
+
eventName: TOUCH_START,
|
|
223
|
+
element: state.element,
|
|
224
|
+
renderingEngineId: state.renderingEngineId,
|
|
225
|
+
viewportId: state.viewportId,
|
|
226
|
+
camera: {},
|
|
227
|
+
startPointsList: startPointsList,
|
|
228
|
+
lastPointsList: startPointsList,
|
|
229
|
+
currentPointsList: startPointsList,
|
|
230
|
+
startPoints: startPoints,
|
|
231
|
+
lastPoints: startPoints,
|
|
232
|
+
currentPoints: startPoints,
|
|
233
|
+
deltaPoints,
|
|
234
|
+
deltaDistance,
|
|
235
|
+
// deltaRotation
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
state.startPointsList = copyPointsList(eventDetail.startPointsList);
|
|
239
|
+
state.lastPointsList = copyPointsList(eventDetail.lastPointsList);
|
|
240
|
+
// by triggering TOUCH_START it checks if this is toolSelection, handle modification etc.
|
|
241
|
+
// of already existing tools
|
|
242
|
+
const eventDidPropagate = triggerEventCallback(
|
|
243
|
+
eventDetail.element,
|
|
244
|
+
TOUCH_START,
|
|
245
|
+
eventDetail
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
// if no tools responded to this event and prevented its default propagation behavior,
|
|
249
|
+
// create a new tool
|
|
250
|
+
if (eventDidPropagate) {
|
|
251
|
+
triggerEventCallback(
|
|
252
|
+
eventDetail.element,
|
|
253
|
+
TOUCH_START_ACTIVATE,
|
|
254
|
+
eventDetail
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* _onTouchDrag - Handle emission of drag events whilst the touch is depressed.
|
|
261
|
+
*
|
|
262
|
+
* @private
|
|
263
|
+
* @param evt - The touch event (touchmove)
|
|
264
|
+
*/
|
|
265
|
+
function _onTouchDrag(evt: TouchEvent) {
|
|
266
|
+
const currentPointsList = getTouchEventPoints(evt, state.element);
|
|
267
|
+
const lastPointsList = _updateTouchEventsLastPoints(
|
|
268
|
+
state.element,
|
|
269
|
+
state.lastPointsList
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
const deltaPoints =
|
|
273
|
+
currentPointsList.length === lastPointsList.length
|
|
274
|
+
? getDeltaPoints(currentPointsList, lastPointsList)
|
|
275
|
+
: zeroIPoint;
|
|
276
|
+
|
|
277
|
+
const deltaDistance =
|
|
278
|
+
currentPointsList.length === lastPointsList.length
|
|
279
|
+
? getDeltaDistanceBetweenIPoints(currentPointsList, lastPointsList)
|
|
280
|
+
: zeroIDistance;
|
|
281
|
+
|
|
282
|
+
const totalDistance =
|
|
283
|
+
currentPointsList.length === lastPointsList.length
|
|
284
|
+
? getDeltaDistance(currentPointsList, state.lastPointsList)
|
|
285
|
+
: zeroIDistance;
|
|
286
|
+
|
|
287
|
+
state.accumulatedDistance = {
|
|
288
|
+
page: state.accumulatedDistance.page + totalDistance.page,
|
|
289
|
+
client: state.accumulatedDistance.client + totalDistance.client,
|
|
290
|
+
canvas: state.accumulatedDistance.canvas + totalDistance.canvas,
|
|
291
|
+
world: state.accumulatedDistance.world + totalDistance.world,
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* this is can be uncommented to make dragging smoother. In the future, these values
|
|
296
|
+
* should be in a configuration file. There may also need to be different
|
|
297
|
+
* profiles for left handed and right handed thumb use. These values
|
|
298
|
+
* are currently optimized for left handed use.
|
|
299
|
+
*
|
|
300
|
+
* const clamp = (num) => Math.min(Math.max(num, -15), 10);
|
|
301
|
+
* const deltaDistanceClamped = \{
|
|
302
|
+
* page: clamp(deltaDistance.page),
|
|
303
|
+
* client: clamp(deltaDistance.client),
|
|
304
|
+
* canvas: clamp(deltaDistance.canvas),
|
|
305
|
+
* world: clamp(deltaDistance.world),
|
|
306
|
+
* \};
|
|
307
|
+
*/
|
|
308
|
+
|
|
309
|
+
const eventDetail: EventTypes.TouchDragEventDetail = {
|
|
310
|
+
event: evt,
|
|
311
|
+
eventName: TOUCH_DRAG,
|
|
312
|
+
renderingEngineId: state.renderingEngineId,
|
|
313
|
+
viewportId: state.viewportId,
|
|
314
|
+
camera: {},
|
|
315
|
+
element: state.element,
|
|
316
|
+
startPoints: getMeanTouchPoints(state.startPointsList),
|
|
317
|
+
lastPoints: getMeanTouchPoints(lastPointsList),
|
|
318
|
+
currentPoints: getMeanTouchPoints(currentPointsList),
|
|
319
|
+
startPointsList: copyPointsList(state.startPointsList),
|
|
320
|
+
lastPointsList: copyPointsList(lastPointsList),
|
|
321
|
+
currentPointsList,
|
|
322
|
+
deltaPoints: deltaPoints,
|
|
323
|
+
deltaDistance: deltaDistance,
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
triggerEventCallback(state.element, TOUCH_DRAG, eventDetail);
|
|
327
|
+
|
|
328
|
+
// check for swipe events
|
|
329
|
+
_checkTouchSwipe(evt, deltaPoints);
|
|
330
|
+
|
|
331
|
+
// Update the last points
|
|
332
|
+
state.lastPointsList = copyPointsList(currentPointsList);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* _onTouchEnd - Handle emission of touch end events
|
|
337
|
+
*
|
|
338
|
+
* @private
|
|
339
|
+
* @param evt - The touch event.
|
|
340
|
+
*/
|
|
341
|
+
function _onTouchEnd(evt: TouchEvent): void {
|
|
342
|
+
// in case it was a tap event we don't want to fire the cornerstone normalized
|
|
343
|
+
// touch end event if the touch start never happend
|
|
344
|
+
clearTimeout(state.pressTimeout);
|
|
345
|
+
const currentPointsList = getTouchEventPoints(evt, state.element);
|
|
346
|
+
const lastPointsList = _updateTouchEventsLastPoints(
|
|
347
|
+
state.element,
|
|
348
|
+
state.lastPointsList
|
|
349
|
+
);
|
|
350
|
+
const deltaPoints =
|
|
351
|
+
currentPointsList.length === lastPointsList.length
|
|
352
|
+
? getDeltaPoints(currentPointsList, lastPointsList)
|
|
353
|
+
: getDeltaPoints(currentPointsList, currentPointsList);
|
|
354
|
+
const deltaDistance =
|
|
355
|
+
currentPointsList.length === lastPointsList.length
|
|
356
|
+
? getDeltaDistanceBetweenIPoints(currentPointsList, lastPointsList)
|
|
357
|
+
: getDeltaDistanceBetweenIPoints(currentPointsList, currentPointsList);
|
|
358
|
+
const eventDetail: EventTypes.TouchEndEventDetail = {
|
|
359
|
+
event: evt,
|
|
360
|
+
eventName: TOUCH_END,
|
|
361
|
+
element: state.element,
|
|
362
|
+
renderingEngineId: state.renderingEngineId,
|
|
363
|
+
viewportId: state.viewportId,
|
|
364
|
+
camera: {},
|
|
365
|
+
startPointsList: copyPointsList(state.startPointsList),
|
|
366
|
+
lastPointsList: copyPointsList(lastPointsList),
|
|
367
|
+
currentPointsList,
|
|
368
|
+
startPoints: getMeanTouchPoints(state.startPointsList),
|
|
369
|
+
lastPoints: getMeanTouchPoints(lastPointsList),
|
|
370
|
+
currentPoints: getMeanTouchPoints(currentPointsList),
|
|
371
|
+
deltaPoints,
|
|
372
|
+
deltaDistance,
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
triggerEventCallback(eventDetail.element, TOUCH_END, eventDetail);
|
|
376
|
+
_checkTouchTap(evt);
|
|
377
|
+
|
|
378
|
+
// reset to default state
|
|
379
|
+
state = JSON.parse(JSON.stringify(defaultState));
|
|
380
|
+
document.removeEventListener('touchmove', _onTouchDrag);
|
|
381
|
+
document.removeEventListener('touchend', _onTouchEnd);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function _checkTouchTap(evt: TouchEvent): void {
|
|
385
|
+
const currentTime = new Date().getTime();
|
|
386
|
+
const startTime = state.startTime.getTime();
|
|
387
|
+
if (currentTime - startTime > tapState.tapToleranceMs) return;
|
|
388
|
+
|
|
389
|
+
// first tap, initialize the state
|
|
390
|
+
if (tapState.taps === 0) {
|
|
391
|
+
tapState.element = state.element;
|
|
392
|
+
tapState.renderingEngineId = state.renderingEngineId;
|
|
393
|
+
tapState.viewportId = state.viewportId;
|
|
394
|
+
tapState.startPointsList = state.startPointsList;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// subsequent tap is on a different element
|
|
398
|
+
if (
|
|
399
|
+
tapState.taps > 0 &&
|
|
400
|
+
!(
|
|
401
|
+
tapState.element == state.element &&
|
|
402
|
+
tapState.renderingEngineId == state.renderingEngineId &&
|
|
403
|
+
tapState.viewportId == state.viewportId
|
|
404
|
+
)
|
|
405
|
+
) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const currentPointsList = getTouchEventPoints(evt, tapState.element);
|
|
410
|
+
const distanceFromStart = getDeltaDistance(
|
|
411
|
+
currentPointsList,
|
|
412
|
+
tapState.startPointsList
|
|
413
|
+
).canvas;
|
|
414
|
+
|
|
415
|
+
// if the tap is too far from starting tap, we can ignore it.
|
|
416
|
+
// TODO: in the case the user means to tap in two separate areas within the
|
|
417
|
+
// tapTolerance (300ms), the second tap will not trigger. This is because it
|
|
418
|
+
// is ignored below for simplicity to track multiple taps (double, triple etc)
|
|
419
|
+
// in order to support two separate single taps that occur < 300ms on the
|
|
420
|
+
// screen. One can create the concept of "TapChains". Our current implementation
|
|
421
|
+
// only supports a single tap chain on the screen. You can think of it as a
|
|
422
|
+
// region where the user has the option to perform unlimited multitaps as long
|
|
423
|
+
// as they are < the tapToleranceMs value. So a tap somewhere else on the screen
|
|
424
|
+
// that is > the tapMaxDistance will start a separate and new "TapChain".
|
|
425
|
+
if (distanceFromStart > tapState.tapMaxDistance) return;
|
|
426
|
+
|
|
427
|
+
clearTimeout(tapState.tapTimeout);
|
|
428
|
+
tapState.taps += 1;
|
|
429
|
+
|
|
430
|
+
tapState.tapTimeout = setTimeout(() => {
|
|
431
|
+
const eventDetail: EventTypes.TouchTapEventDetail = {
|
|
432
|
+
event: evt,
|
|
433
|
+
eventName: TOUCH_TAP,
|
|
434
|
+
element: tapState.element,
|
|
435
|
+
renderingEngineId: tapState.renderingEngineId,
|
|
436
|
+
viewportId: tapState.viewportId,
|
|
437
|
+
camera: {},
|
|
438
|
+
currentPointsList,
|
|
439
|
+
currentPoints: getMeanTouchPoints(currentPointsList),
|
|
440
|
+
taps: tapState.taps,
|
|
441
|
+
};
|
|
442
|
+
triggerEventCallback(eventDetail.element, TOUCH_TAP, eventDetail);
|
|
443
|
+
tapState = JSON.parse(JSON.stringify(defaultTapState));
|
|
444
|
+
}, tapState.tapToleranceMs);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function _checkTouchSwipe(evt: TouchEvent, deltaPoints: IPoints) {
|
|
448
|
+
const currentTime = new Date().getTime();
|
|
449
|
+
const startTime = state.startTime.getTime();
|
|
450
|
+
if (state.swiped || currentTime - startTime > state.swipeToleranceMs) return;
|
|
451
|
+
const [x, y] = deltaPoints.canvas;
|
|
452
|
+
const eventDetail: EventTypes.TouchSwipeEventDetail = {
|
|
453
|
+
event: evt,
|
|
454
|
+
eventName: TOUCH_SWIPE,
|
|
455
|
+
renderingEngineId: state.renderingEngineId,
|
|
456
|
+
viewportId: state.viewportId,
|
|
457
|
+
camera: {},
|
|
458
|
+
element: state.element,
|
|
459
|
+
swipe: null,
|
|
460
|
+
};
|
|
461
|
+
if (Math.abs(x) > state.swipeDistanceThreshold) {
|
|
462
|
+
eventDetail.swipe = x > 0 ? Swipe.RIGHT : Swipe.LEFT;
|
|
463
|
+
triggerEventCallback(eventDetail.element, TOUCH_SWIPE, eventDetail);
|
|
464
|
+
state.swiped = true;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (Math.abs(y) > state.swipeDistanceThreshold) {
|
|
468
|
+
eventDetail.swipe = y > 0 ? Swipe.DOWN : Swipe.UP;
|
|
469
|
+
triggerEventCallback(eventDetail.element, TOUCH_SWIPE, eventDetail);
|
|
470
|
+
state.swiped = true;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Recalculates the last world coordinate, as the linear transform from client
|
|
476
|
+
* to world could be different if the camera was updated.
|
|
477
|
+
* @param element - The HTML element
|
|
478
|
+
* @param lastPoints - The last points
|
|
479
|
+
*/
|
|
480
|
+
function _updateTouchEventsLastPoints(
|
|
481
|
+
element: HTMLDivElement,
|
|
482
|
+
lastPoints: ITouchPoints[]
|
|
483
|
+
): ITouchPoints[] {
|
|
484
|
+
const { viewport } = getEnabledElement(element);
|
|
485
|
+
// Need to update the world point to be calculated from the current reference frame,
|
|
486
|
+
// Which might have changed since the last interaction.
|
|
487
|
+
return lastPoints.map((lp) => {
|
|
488
|
+
const world = viewport.canvasToWorld(lp.canvas);
|
|
489
|
+
return {
|
|
490
|
+
page: lp.page,
|
|
491
|
+
client: lp.client,
|
|
492
|
+
canvas: lp.canvas,
|
|
493
|
+
world,
|
|
494
|
+
touch: lp.touch,
|
|
495
|
+
};
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
export default touchStartListener;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import wheelListener from './wheelListener';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Listens for the wheel event, and handles it. Handled event
|
|
5
|
+
* will be "normalized" and re-emitted as `Events.MOUSE_WHEEL`
|
|
6
|
+
*
|
|
7
|
+
* @param element - The HTML element
|
|
8
|
+
*/
|
|
9
|
+
function enable(element: HTMLDivElement) {
|
|
10
|
+
disable(element);
|
|
11
|
+
element.addEventListener('wheel', wheelListener, { passive: false });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Removes listener and handler for wheel event. `Events.MOUSE_WHEEL`
|
|
16
|
+
* will no longer be emitted.
|
|
17
|
+
*
|
|
18
|
+
* @param element - THe HTML element
|
|
19
|
+
*/
|
|
20
|
+
function disable(element: HTMLDivElement) {
|
|
21
|
+
element.removeEventListener('wheel', wheelListener);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default {
|
|
25
|
+
enable,
|
|
26
|
+
disable,
|
|
27
|
+
};
|