@cornerstonejs/tools 2.0.0-beta.2 → 2.0.0-beta.3

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 (265) hide show
  1. package/dist/cjs/drawingSvg/getSvgDrawingHelper.js +1 -1
  2. package/dist/cjs/drawingSvg/getSvgDrawingHelper.js.map +1 -1
  3. package/dist/cjs/enums/Events.d.ts +1 -0
  4. package/dist/cjs/enums/Events.js +1 -0
  5. package/dist/cjs/enums/Events.js.map +1 -1
  6. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDown.js +6 -1
  7. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDown.js.map +1 -1
  8. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDownAnnotationAction.d.ts +2 -0
  9. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDownAnnotationAction.js +41 -0
  10. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDownAnnotationAction.js.map +1 -0
  11. package/dist/cjs/eventDispatchers/shared/getToolsWithActionsForMouseEvent.d.ts +3 -0
  12. package/dist/cjs/eventDispatchers/shared/getToolsWithActionsForMouseEvent.js +39 -0
  13. package/dist/cjs/eventDispatchers/shared/getToolsWithActionsForMouseEvent.js.map +1 -0
  14. package/dist/cjs/eventListeners/mouse/mouseDownListener.js +5 -1
  15. package/dist/cjs/eventListeners/mouse/mouseDownListener.js.map +1 -1
  16. package/dist/cjs/eventListeners/mouse/mouseMoveListener.js +5 -1
  17. package/dist/cjs/eventListeners/mouse/mouseMoveListener.js.map +1 -1
  18. package/dist/cjs/index.d.ts +2 -2
  19. package/dist/cjs/index.js +5 -2
  20. package/dist/cjs/index.js.map +1 -1
  21. package/dist/cjs/store/ToolGroupManager/ToolGroup.d.ts +2 -0
  22. package/dist/cjs/store/ToolGroupManager/ToolGroup.js +35 -0
  23. package/dist/cjs/store/ToolGroupManager/ToolGroup.js.map +1 -1
  24. package/dist/cjs/synchronizers/callbacks/stackImageSyncCallback.js +1 -1
  25. package/dist/cjs/synchronizers/callbacks/stackImageSyncCallback.js.map +1 -1
  26. package/dist/cjs/tools/AdvancedMagnifyTool.d.ts +36 -0
  27. package/dist/cjs/tools/AdvancedMagnifyTool.js +448 -0
  28. package/dist/cjs/tools/AdvancedMagnifyTool.js.map +1 -0
  29. package/dist/cjs/tools/AdvancedMagnifyViewport.d.ts +76 -0
  30. package/dist/cjs/tools/AdvancedMagnifyViewport.js +352 -0
  31. package/dist/cjs/tools/AdvancedMagnifyViewport.js.map +1 -0
  32. package/dist/cjs/tools/AdvancedMagnifyViewportManager.d.ts +36 -0
  33. package/dist/cjs/tools/AdvancedMagnifyViewportManager.js +133 -0
  34. package/dist/cjs/tools/AdvancedMagnifyViewportManager.js.map +1 -0
  35. package/dist/cjs/tools/MagnifyTool.js +2 -2
  36. package/dist/cjs/tools/MagnifyTool.js.map +1 -1
  37. package/dist/cjs/tools/OrientationMarkerTool.d.ts +88 -0
  38. package/dist/cjs/tools/OrientationMarkerTool.js +193 -0
  39. package/dist/cjs/tools/OrientationMarkerTool.js.map +1 -0
  40. package/dist/cjs/tools/OverlayGridTool.d.ts +31 -0
  41. package/dist/cjs/tools/OverlayGridTool.js +170 -0
  42. package/dist/cjs/tools/OverlayGridTool.js.map +1 -0
  43. package/dist/cjs/tools/ReferenceLinesTool.d.ts +3 -0
  44. package/dist/cjs/tools/ReferenceLinesTool.js +71 -2
  45. package/dist/cjs/tools/ReferenceLinesTool.js.map +1 -1
  46. package/dist/cjs/tools/annotation/AngleTool.js +2 -1
  47. package/dist/cjs/tools/annotation/AngleTool.js.map +1 -1
  48. package/dist/cjs/tools/annotation/BidirectionalTool.js +1 -1
  49. package/dist/cjs/tools/annotation/BidirectionalTool.js.map +1 -1
  50. package/dist/cjs/tools/annotation/CircleROITool.d.ts +1 -2
  51. package/dist/cjs/tools/annotation/CircleROITool.js +8 -8
  52. package/dist/cjs/tools/annotation/CircleROITool.js.map +1 -1
  53. package/dist/cjs/tools/annotation/CobbAngleTool.d.ts +31 -5
  54. package/dist/cjs/tools/annotation/CobbAngleTool.js +268 -71
  55. package/dist/cjs/tools/annotation/CobbAngleTool.js.map +1 -1
  56. package/dist/cjs/tools/annotation/DragProbeTool.js +4 -3
  57. package/dist/cjs/tools/annotation/DragProbeTool.js.map +1 -1
  58. package/dist/cjs/tools/annotation/EllipticalROITool.d.ts +2 -3
  59. package/dist/cjs/tools/annotation/EllipticalROITool.js +20 -16
  60. package/dist/cjs/tools/annotation/EllipticalROITool.js.map +1 -1
  61. package/dist/cjs/tools/annotation/LengthTool.js +1 -1
  62. package/dist/cjs/tools/annotation/LengthTool.js.map +1 -1
  63. package/dist/cjs/tools/annotation/PlanarFreehandROITool.d.ts +1 -2
  64. package/dist/cjs/tools/annotation/PlanarFreehandROITool.js +22 -9
  65. package/dist/cjs/tools/annotation/PlanarFreehandROITool.js.map +1 -1
  66. package/dist/cjs/tools/annotation/ProbeTool.d.ts +1 -2
  67. package/dist/cjs/tools/annotation/ProbeTool.js +10 -9
  68. package/dist/cjs/tools/annotation/ProbeTool.js.map +1 -1
  69. package/dist/cjs/tools/annotation/RectangleROITool.d.ts +1 -1
  70. package/dist/cjs/tools/annotation/RectangleROITool.js +9 -9
  71. package/dist/cjs/tools/annotation/RectangleROITool.js.map +1 -1
  72. package/dist/cjs/tools/base/AnnotationDisplayTool.js +4 -0
  73. package/dist/cjs/tools/base/AnnotationDisplayTool.js.map +1 -1
  74. package/dist/cjs/tools/base/AnnotationTool.d.ts +1 -1
  75. package/dist/cjs/tools/base/AnnotationTool.js.map +1 -1
  76. package/dist/cjs/tools/displayTools/Contour/contourDisplay.js +3 -0
  77. package/dist/cjs/tools/displayTools/Contour/contourDisplay.js.map +1 -1
  78. package/dist/cjs/tools/displayTools/Labelmap/labelmapDisplay.js +1 -1
  79. package/dist/cjs/tools/displayTools/Labelmap/labelmapDisplay.js.map +1 -1
  80. package/dist/cjs/tools/index.d.ts +4 -1
  81. package/dist/cjs/tools/index.js +7 -1
  82. package/dist/cjs/tools/index.js.map +1 -1
  83. package/dist/cjs/types/EventTypes.d.ts +9 -1
  84. package/dist/cjs/types/IToolGroup.d.ts +3 -0
  85. package/dist/cjs/types/ToolAction.d.ts +8 -0
  86. package/dist/cjs/types/ToolAction.js +3 -0
  87. package/dist/cjs/types/ToolAction.js.map +1 -0
  88. package/dist/cjs/types/ToolSpecificAnnotationTypes.d.ts +55 -0
  89. package/dist/cjs/types/index.d.ts +2 -1
  90. package/dist/cjs/utilities/getModalityUnit.js +5 -2
  91. package/dist/cjs/utilities/getModalityUnit.js.map +1 -1
  92. package/dist/cjs/utilities/index.d.ts +2 -2
  93. package/dist/cjs/utilities/index.js +4 -3
  94. package/dist/cjs/utilities/index.js.map +1 -1
  95. package/dist/cjs/utilities/math/angle/angleBetweenLines.d.ts +3 -1
  96. package/dist/cjs/utilities/math/angle/angleBetweenLines.js +18 -1
  97. package/dist/cjs/utilities/math/angle/angleBetweenLines.js.map +1 -1
  98. package/dist/cjs/utilities/stackPrefetch/index.d.ts +3 -2
  99. package/dist/cjs/utilities/stackPrefetch/index.js +8 -6
  100. package/dist/cjs/utilities/stackPrefetch/index.js.map +1 -1
  101. package/dist/cjs/utilities/stackPrefetch/stackContextPrefetch.d.ts +16 -0
  102. package/dist/cjs/utilities/stackPrefetch/stackContextPrefetch.js +227 -0
  103. package/dist/cjs/utilities/stackPrefetch/stackContextPrefetch.js.map +1 -0
  104. package/dist/cjs/utilities/stackPrefetch/stackPrefetch.d.ts +7 -1
  105. package/dist/cjs/utilities/stackPrefetch/stackPrefetch.js +23 -93
  106. package/dist/cjs/utilities/stackPrefetch/stackPrefetch.js.map +1 -1
  107. package/dist/cjs/utilities/stackPrefetch/stackPrefetchUtils.d.ts +14 -0
  108. package/dist/cjs/utilities/stackPrefetch/stackPrefetchUtils.js +85 -0
  109. package/dist/cjs/utilities/stackPrefetch/stackPrefetchUtils.js.map +1 -0
  110. package/dist/esm/drawingSvg/getSvgDrawingHelper.js +1 -1
  111. package/dist/esm/drawingSvg/getSvgDrawingHelper.js.map +1 -1
  112. package/dist/esm/enums/Events.d.ts +1 -0
  113. package/dist/esm/enums/Events.js +1 -0
  114. package/dist/esm/enums/Events.js.map +1 -1
  115. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDown.js +6 -1
  116. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDown.js.map +1 -1
  117. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDownAnnotationAction.d.ts +2 -0
  118. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDownAnnotationAction.js +35 -0
  119. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDownAnnotationAction.js.map +1 -0
  120. package/dist/esm/eventDispatchers/shared/getToolsWithActionsForMouseEvent.d.ts +3 -0
  121. package/dist/esm/eventDispatchers/shared/getToolsWithActionsForMouseEvent.js +32 -0
  122. package/dist/esm/eventDispatchers/shared/getToolsWithActionsForMouseEvent.js.map +1 -0
  123. package/dist/esm/eventListeners/mouse/mouseDownListener.js +5 -1
  124. package/dist/esm/eventListeners/mouse/mouseDownListener.js.map +1 -1
  125. package/dist/esm/eventListeners/mouse/mouseMoveListener.js +5 -1
  126. package/dist/esm/eventListeners/mouse/mouseMoveListener.js.map +1 -1
  127. package/dist/esm/index.d.ts +2 -2
  128. package/dist/esm/index.js +2 -2
  129. package/dist/esm/index.js.map +1 -1
  130. package/dist/esm/store/ToolGroupManager/ToolGroup.d.ts +2 -0
  131. package/dist/esm/store/ToolGroupManager/ToolGroup.js +35 -1
  132. package/dist/esm/store/ToolGroupManager/ToolGroup.js.map +1 -1
  133. package/dist/esm/synchronizers/callbacks/stackImageSyncCallback.js +1 -1
  134. package/dist/esm/synchronizers/callbacks/stackImageSyncCallback.js.map +1 -1
  135. package/dist/esm/tools/AdvancedMagnifyTool.d.ts +36 -0
  136. package/dist/esm/tools/AdvancedMagnifyTool.js +440 -0
  137. package/dist/esm/tools/AdvancedMagnifyTool.js.map +1 -0
  138. package/dist/esm/tools/AdvancedMagnifyViewport.d.ts +76 -0
  139. package/dist/esm/tools/AdvancedMagnifyViewport.js +346 -0
  140. package/dist/esm/tools/AdvancedMagnifyViewport.js.map +1 -0
  141. package/dist/esm/tools/AdvancedMagnifyViewportManager.d.ts +36 -0
  142. package/dist/esm/tools/AdvancedMagnifyViewportManager.js +128 -0
  143. package/dist/esm/tools/AdvancedMagnifyViewportManager.js.map +1 -0
  144. package/dist/esm/tools/MagnifyTool.js +2 -2
  145. package/dist/esm/tools/MagnifyTool.js.map +1 -1
  146. package/dist/esm/tools/OrientationMarkerTool.d.ts +88 -0
  147. package/dist/esm/tools/OrientationMarkerTool.js +185 -0
  148. package/dist/esm/tools/OrientationMarkerTool.js.map +1 -0
  149. package/dist/esm/tools/OverlayGridTool.d.ts +31 -0
  150. package/dist/esm/tools/OverlayGridTool.js +165 -0
  151. package/dist/esm/tools/OverlayGridTool.js.map +1 -0
  152. package/dist/esm/tools/ReferenceLinesTool.d.ts +3 -0
  153. package/dist/esm/tools/ReferenceLinesTool.js +71 -2
  154. package/dist/esm/tools/ReferenceLinesTool.js.map +1 -1
  155. package/dist/esm/tools/annotation/AngleTool.js +2 -1
  156. package/dist/esm/tools/annotation/AngleTool.js.map +1 -1
  157. package/dist/esm/tools/annotation/BidirectionalTool.js +1 -1
  158. package/dist/esm/tools/annotation/BidirectionalTool.js.map +1 -1
  159. package/dist/esm/tools/annotation/CircleROITool.d.ts +1 -2
  160. package/dist/esm/tools/annotation/CircleROITool.js +8 -8
  161. package/dist/esm/tools/annotation/CircleROITool.js.map +1 -1
  162. package/dist/esm/tools/annotation/CobbAngleTool.d.ts +31 -5
  163. package/dist/esm/tools/annotation/CobbAngleTool.js +275 -72
  164. package/dist/esm/tools/annotation/CobbAngleTool.js.map +1 -1
  165. package/dist/esm/tools/annotation/DragProbeTool.js +4 -3
  166. package/dist/esm/tools/annotation/DragProbeTool.js.map +1 -1
  167. package/dist/esm/tools/annotation/EllipticalROITool.d.ts +2 -3
  168. package/dist/esm/tools/annotation/EllipticalROITool.js +20 -16
  169. package/dist/esm/tools/annotation/EllipticalROITool.js.map +1 -1
  170. package/dist/esm/tools/annotation/LengthTool.js +1 -1
  171. package/dist/esm/tools/annotation/LengthTool.js.map +1 -1
  172. package/dist/esm/tools/annotation/PlanarFreehandROITool.d.ts +1 -2
  173. package/dist/esm/tools/annotation/PlanarFreehandROITool.js +22 -9
  174. package/dist/esm/tools/annotation/PlanarFreehandROITool.js.map +1 -1
  175. package/dist/esm/tools/annotation/ProbeTool.d.ts +1 -2
  176. package/dist/esm/tools/annotation/ProbeTool.js +10 -9
  177. package/dist/esm/tools/annotation/ProbeTool.js.map +1 -1
  178. package/dist/esm/tools/annotation/RectangleROITool.d.ts +1 -1
  179. package/dist/esm/tools/annotation/RectangleROITool.js +9 -9
  180. package/dist/esm/tools/annotation/RectangleROITool.js.map +1 -1
  181. package/dist/esm/tools/base/AnnotationDisplayTool.js +3 -0
  182. package/dist/esm/tools/base/AnnotationDisplayTool.js.map +1 -1
  183. package/dist/esm/tools/base/AnnotationTool.d.ts +1 -1
  184. package/dist/esm/tools/base/AnnotationTool.js.map +1 -1
  185. package/dist/esm/tools/displayTools/Contour/contourDisplay.js +4 -1
  186. package/dist/esm/tools/displayTools/Contour/contourDisplay.js.map +1 -1
  187. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js +1 -1
  188. package/dist/esm/tools/displayTools/Labelmap/labelmapDisplay.js.map +1 -1
  189. package/dist/esm/tools/index.d.ts +4 -1
  190. package/dist/esm/tools/index.js +4 -1
  191. package/dist/esm/tools/index.js.map +1 -1
  192. package/dist/esm/types/EventTypes.d.ts +9 -1
  193. package/dist/esm/types/IToolGroup.d.ts +3 -0
  194. package/dist/esm/types/ToolAction.d.ts +8 -0
  195. package/dist/esm/types/ToolAction.js +2 -0
  196. package/dist/esm/types/ToolAction.js.map +1 -0
  197. package/dist/esm/types/ToolSpecificAnnotationTypes.d.ts +55 -0
  198. package/dist/esm/types/index.d.ts +2 -1
  199. package/dist/esm/utilities/getModalityUnit.js +5 -2
  200. package/dist/esm/utilities/getModalityUnit.js.map +1 -1
  201. package/dist/esm/utilities/index.d.ts +2 -2
  202. package/dist/esm/utilities/index.js +2 -2
  203. package/dist/esm/utilities/index.js.map +1 -1
  204. package/dist/esm/utilities/math/angle/angleBetweenLines.d.ts +3 -1
  205. package/dist/esm/utilities/math/angle/angleBetweenLines.js +19 -2
  206. package/dist/esm/utilities/math/angle/angleBetweenLines.js.map +1 -1
  207. package/dist/esm/utilities/stackPrefetch/index.d.ts +3 -2
  208. package/dist/esm/utilities/stackPrefetch/index.js +3 -2
  209. package/dist/esm/utilities/stackPrefetch/index.js.map +1 -1
  210. package/dist/esm/utilities/stackPrefetch/stackContextPrefetch.d.ts +16 -0
  211. package/dist/esm/utilities/stackPrefetch/stackContextPrefetch.js +220 -0
  212. package/dist/esm/utilities/stackPrefetch/stackContextPrefetch.js.map +1 -0
  213. package/dist/esm/utilities/stackPrefetch/stackPrefetch.d.ts +7 -1
  214. package/dist/esm/utilities/stackPrefetch/stackPrefetch.js +12 -79
  215. package/dist/esm/utilities/stackPrefetch/stackPrefetch.js.map +1 -1
  216. package/dist/esm/utilities/stackPrefetch/stackPrefetchUtils.d.ts +14 -0
  217. package/dist/esm/utilities/stackPrefetch/stackPrefetchUtils.js +77 -0
  218. package/dist/esm/utilities/stackPrefetch/stackPrefetchUtils.js.map +1 -0
  219. package/dist/umd/index.js +1 -1
  220. package/dist/umd/index.js.map +1 -1
  221. package/package.json +3 -3
  222. package/src/drawingSvg/getSvgDrawingHelper.ts +4 -1
  223. package/src/enums/Events.ts +9 -0
  224. package/src/eventDispatchers/mouseEventHandlers/mouseDown.ts +11 -2
  225. package/src/eventDispatchers/mouseEventHandlers/mouseDownAnnotationAction.ts +72 -0
  226. package/src/eventDispatchers/shared/getToolsWithActionsForMouseEvent.ts +66 -0
  227. package/src/eventListeners/mouse/mouseDownListener.ts +7 -1
  228. package/src/eventListeners/mouse/mouseMoveListener.ts +7 -1
  229. package/src/index.ts +6 -0
  230. package/src/store/ToolGroupManager/ToolGroup.ts +79 -2
  231. package/src/synchronizers/callbacks/stackImageSyncCallback.ts +1 -1
  232. package/src/tools/AdvancedMagnifyTool.ts +725 -0
  233. package/src/tools/AdvancedMagnifyViewport.ts +624 -0
  234. package/src/tools/AdvancedMagnifyViewportManager.ts +291 -0
  235. package/src/tools/MagnifyTool.ts +2 -2
  236. package/src/tools/OrientationMarkerTool.ts +235 -0
  237. package/src/tools/OverlayGridTool.ts +357 -0
  238. package/src/tools/ReferenceLinesTool.ts +131 -3
  239. package/src/tools/annotation/AngleTool.ts +4 -1
  240. package/src/tools/annotation/BidirectionalTool.ts +1 -1
  241. package/src/tools/annotation/CircleROITool.ts +13 -20
  242. package/src/tools/annotation/CobbAngleTool.ts +422 -99
  243. package/src/tools/annotation/DragProbeTool.ts +6 -13
  244. package/src/tools/annotation/EllipticalROITool.ts +28 -29
  245. package/src/tools/annotation/LengthTool.ts +1 -1
  246. package/src/tools/annotation/PlanarFreehandROITool.ts +35 -20
  247. package/src/tools/annotation/ProbeTool.ts +17 -30
  248. package/src/tools/annotation/RectangleROITool.ts +15 -19
  249. package/src/tools/base/AnnotationDisplayTool.ts +4 -0
  250. package/src/tools/base/AnnotationTool.ts +2 -1
  251. package/src/tools/displayTools/Contour/contourDisplay.ts +8 -0
  252. package/src/tools/displayTools/Labelmap/labelmapDisplay.ts +1 -1
  253. package/src/tools/index.ts +6 -0
  254. package/src/types/EventTypes.ts +23 -0
  255. package/src/types/IToolGroup.ts +7 -0
  256. package/src/types/ToolAction.ts +54 -0
  257. package/src/types/ToolSpecificAnnotationTypes.ts +58 -0
  258. package/src/types/index.ts +2 -0
  259. package/src/utilities/getModalityUnit.ts +8 -2
  260. package/src/utilities/index.ts +2 -1
  261. package/src/utilities/math/angle/angleBetweenLines.ts +39 -9
  262. package/src/utilities/stackPrefetch/index.ts +3 -7
  263. package/src/utilities/stackPrefetch/stackContextPrefetch.ts +380 -0
  264. package/src/utilities/stackPrefetch/stackPrefetch.ts +29 -151
  265. package/src/utilities/stackPrefetch/stackPrefetchUtils.ts +114 -0
@@ -0,0 +1,725 @@
1
+ import { AnnotationTool } from './base';
2
+
3
+ import {
4
+ getEnabledElement,
5
+ eventTarget,
6
+ triggerEvent,
7
+ utilities as csUtils,
8
+ } from '@cornerstonejs/core';
9
+ import type { Types } from '@cornerstonejs/core';
10
+
11
+ import {
12
+ addAnnotation,
13
+ getAnnotations,
14
+ } from '../stateManagement/annotation/annotationState';
15
+ import { isAnnotationLocked } from '../stateManagement/annotation/annotationLocking';
16
+ import { isAnnotationVisible } from '../stateManagement/annotation/annotationVisibility';
17
+ import {
18
+ drawCircle as drawCircleSvg,
19
+ drawHandles as drawHandlesSvg,
20
+ } from '../drawingSvg';
21
+ import { state } from '../store';
22
+ import { Events, MouseBindings, KeyboardBindings } from '../enums';
23
+ import { getViewportIdsWithToolToRender } from '../utilities/viewportFilters';
24
+ import {
25
+ resetElementCursor,
26
+ hideElementCursor,
27
+ } from '../cursors/elementCursor';
28
+ import {
29
+ EventTypes,
30
+ ToolHandle,
31
+ PublicToolProps,
32
+ ToolProps,
33
+ SVGDrawingHelper,
34
+ } from '../types';
35
+ import { AdvancedMagnifyAnnotation } from '../types/ToolSpecificAnnotationTypes';
36
+
37
+ import { AnnotationCompletedEventDetail } from '../types/EventTypes';
38
+ import triggerAnnotationRenderForViewportIds from '../utilities/triggerAnnotationRenderForViewportIds';
39
+ import { StyleSpecifier } from '../types/AnnotationStyle';
40
+ import { getCanvasCircleRadius } from '../utilities/math/circle';
41
+ import AdvancedMagnifyViewportManager from './AdvancedMagnifyViewportManager';
42
+ import type { AutoPanCallbackData } from './AdvancedMagnifyViewport';
43
+
44
+ class AdvancedMagnifyTool extends AnnotationTool {
45
+ static toolName;
46
+
47
+ magnifyViewportManager: AdvancedMagnifyViewportManager;
48
+ touchDragCallback: any;
49
+ mouseDragCallback: any;
50
+ editData: {
51
+ annotation: any;
52
+ viewportIdsToRender: Array<string>;
53
+ handleIndex?: number;
54
+ newAnnotation?: boolean;
55
+ hasMoved?: boolean;
56
+ } | null;
57
+ isDrawing: boolean;
58
+
59
+ constructor(
60
+ toolProps: PublicToolProps = {},
61
+ defaultToolProps: ToolProps = {
62
+ supportedInteractionTypes: ['Mouse', 'Touch'],
63
+ configuration: {
64
+ shadow: true,
65
+ magnifyingGlass: {
66
+ radius: 125, // px
67
+ zoomFactor: 2.5,
68
+ zoomFactorList: [2.5, 3, 3.5, 4, 4.5, 5],
69
+ autoPan: {
70
+ enabled: true,
71
+ padding: 10, // px
72
+ },
73
+ },
74
+ actions: [
75
+ {
76
+ method: 'showZoomFactorsList',
77
+ bindings: [
78
+ {
79
+ mouseButton: MouseBindings.Secondary,
80
+ modifierKey: KeyboardBindings.Shift,
81
+ },
82
+ ],
83
+ },
84
+ ],
85
+ },
86
+ }
87
+ ) {
88
+ super(toolProps, defaultToolProps);
89
+ this.magnifyViewportManager = AdvancedMagnifyViewportManager.getInstance();
90
+ }
91
+
92
+ /**
93
+ * Based on the current position of the mouse and the current imageId to create
94
+ * a CircleROI Annotation and stores it in the annotationManager
95
+ *
96
+ * @param evt - EventTypes.NormalizedMouseEventType
97
+ * @returns The annotation object.
98
+ *
99
+ */
100
+ addNewAnnotation = (
101
+ evt: EventTypes.InteractionEventType
102
+ ): AdvancedMagnifyAnnotation => {
103
+ const eventDetail = evt.detail;
104
+ const { currentPoints, element } = eventDetail;
105
+ const enabledElement = getEnabledElement(element);
106
+ const { viewport, renderingEngine } = enabledElement;
107
+ const worldPos = currentPoints.world;
108
+ const canvasPos = currentPoints.canvas;
109
+ const { magnifyingGlass: config } = this.configuration;
110
+ const { radius, zoomFactor, autoPan } = config;
111
+
112
+ const worldHandlesPoints = this._getWorldHandlesPoints(
113
+ viewport,
114
+ canvasPos,
115
+ radius
116
+ );
117
+
118
+ const camera = viewport.getCamera();
119
+ const { viewPlaneNormal, viewUp } = camera;
120
+
121
+ const referencedImageId = this.getReferencedImageId(
122
+ viewport,
123
+ worldPos,
124
+ viewPlaneNormal,
125
+ viewUp
126
+ );
127
+
128
+ const annotationUID = csUtils.uuidv4();
129
+ const magnifyViewportId = csUtils.uuidv4();
130
+ const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();
131
+
132
+ const annotation: AdvancedMagnifyAnnotation = {
133
+ annotationUID,
134
+ highlighted: true,
135
+ invalidated: true,
136
+ metadata: {
137
+ toolName: this.getToolName(),
138
+ viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],
139
+ viewUp: <Types.Point3>[...viewUp],
140
+ FrameOfReferenceUID,
141
+ referencedImageId,
142
+ },
143
+ data: {
144
+ sourceViewportId: viewport.id,
145
+ magnifyViewportId,
146
+ zoomFactor,
147
+ handles: {
148
+ points: worldHandlesPoints,
149
+ activeHandleIndex: null,
150
+ },
151
+ },
152
+ };
153
+
154
+ this.magnifyViewportManager.createViewport(annotation, {
155
+ magnifyViewportId,
156
+ sourceEnabledElement: enabledElement,
157
+ position: canvasPos,
158
+ radius,
159
+ zoomFactor,
160
+ autoPan: {
161
+ enabled: autoPan.enabled,
162
+ padding: autoPan.padding,
163
+ callback: (data: AutoPanCallbackData) => {
164
+ const annotationPoints = annotation.data.handles.points;
165
+ const { world: worldDelta } = data.delta;
166
+
167
+ for (let i = 0, len = annotationPoints.length; i < len; i++) {
168
+ annotationPoints[i][0] += worldDelta[0];
169
+ annotationPoints[i][1] += worldDelta[1];
170
+ annotationPoints[i][2] += worldDelta[2];
171
+ }
172
+ },
173
+ },
174
+ });
175
+
176
+ addAnnotation(annotation, element);
177
+
178
+ const viewportIdsToRender = getViewportIdsWithToolToRender(
179
+ element,
180
+ this.getToolName()
181
+ );
182
+
183
+ evt.preventDefault();
184
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
185
+
186
+ return annotation;
187
+ };
188
+
189
+ /**
190
+ * It returns if the canvas point is near the provided annotation in the provided
191
+ * element or not. A proximity is passed to the function to determine the
192
+ * proximity of the point to the annotation in number of pixels.
193
+ *
194
+ * @param element - HTML Element
195
+ * @param annotation - Annotation
196
+ * @param canvasCoords - Canvas coordinates
197
+ * @param proximity - Proximity to tool to consider
198
+ * @returns Boolean, whether the canvas point is near tool
199
+ */
200
+ public isPointNearTool = (
201
+ element: HTMLDivElement,
202
+ annotation: AdvancedMagnifyAnnotation,
203
+ canvasCoords: Types.Point2,
204
+ proximity: number
205
+ ): boolean => {
206
+ const enabledElement = getEnabledElement(element);
207
+ const { viewport } = enabledElement;
208
+
209
+ const { data } = annotation;
210
+ const { points } = data.handles;
211
+
212
+ // For some reason Typescript doesn't understand this, so we need to be
213
+ // more specific about the type
214
+ const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p)) as [
215
+ Types.Point2,
216
+ Types.Point2,
217
+ Types.Point2,
218
+ Types.Point2
219
+ ];
220
+
221
+ const canvasTop = canvasCoordinates[0];
222
+ const canvasBottom = canvasCoordinates[2];
223
+ const canvasLeft = canvasCoordinates[3];
224
+ const radius = Math.abs(canvasBottom[1] - canvasTop[1]) * 0.5;
225
+ const center = [
226
+ canvasLeft[0] + radius,
227
+ canvasTop[1] + radius,
228
+ ] as Types.Point2;
229
+ const radiusPoint = getCanvasCircleRadius([center, canvasCoords]);
230
+
231
+ if (Math.abs(radiusPoint - radius) < proximity * 1.5) {
232
+ return true;
233
+ }
234
+
235
+ return false;
236
+ };
237
+
238
+ toolSelectedCallback = (
239
+ evt: EventTypes.InteractionEventType,
240
+ annotation: AdvancedMagnifyAnnotation
241
+ ): void => {
242
+ const eventDetail = evt.detail;
243
+ const { element } = eventDetail;
244
+
245
+ annotation.highlighted = true;
246
+
247
+ const viewportIdsToRender = getViewportIdsWithToolToRender(
248
+ element,
249
+ this.getToolName()
250
+ );
251
+
252
+ this.editData = {
253
+ annotation,
254
+ viewportIdsToRender,
255
+ };
256
+
257
+ hideElementCursor(element);
258
+
259
+ this._activateModify(element);
260
+
261
+ const enabledElement = getEnabledElement(element);
262
+ const { renderingEngine } = enabledElement;
263
+
264
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
265
+
266
+ evt.preventDefault();
267
+ };
268
+
269
+ handleSelectedCallback = (
270
+ evt: EventTypes.InteractionEventType,
271
+ annotation: AdvancedMagnifyAnnotation,
272
+ handle: ToolHandle
273
+ ): void => {
274
+ const eventDetail = evt.detail;
275
+ const { element } = eventDetail;
276
+ const { data } = annotation;
277
+
278
+ annotation.highlighted = true;
279
+
280
+ const { points } = data.handles;
281
+ const handleIndex = points.findIndex((p) => p === handle);
282
+
283
+ // Find viewports to render on drag.
284
+ const viewportIdsToRender = getViewportIdsWithToolToRender(
285
+ element,
286
+ this.getToolName()
287
+ );
288
+
289
+ this.editData = {
290
+ annotation,
291
+ viewportIdsToRender,
292
+ handleIndex,
293
+ };
294
+ this._activateModify(element);
295
+
296
+ hideElementCursor(element);
297
+
298
+ const enabledElement = getEnabledElement(element);
299
+ const { renderingEngine } = enabledElement;
300
+
301
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
302
+
303
+ evt.preventDefault();
304
+ };
305
+
306
+ _endCallback = (evt: EventTypes.InteractionEventType): void => {
307
+ const eventDetail = evt.detail;
308
+ const { element } = eventDetail;
309
+
310
+ const { annotation, viewportIdsToRender, newAnnotation } = this.editData;
311
+ const { data } = annotation;
312
+
313
+ data.handles.activeHandleIndex = null;
314
+
315
+ this._deactivateModify(element);
316
+
317
+ resetElementCursor(element);
318
+
319
+ const enabledElement = getEnabledElement(element);
320
+ const { renderingEngine } = enabledElement;
321
+
322
+ this.editData = null;
323
+ this.isDrawing = false;
324
+
325
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
326
+
327
+ if (newAnnotation) {
328
+ const eventType = Events.ANNOTATION_COMPLETED;
329
+
330
+ const eventDetail: AnnotationCompletedEventDetail = {
331
+ annotation,
332
+ };
333
+
334
+ triggerEvent(eventTarget, eventType, eventDetail);
335
+ }
336
+ };
337
+
338
+ _dragDrawCallback = (evt: EventTypes.InteractionEventType): void => {
339
+ this.isDrawing = true;
340
+ const eventDetail = evt.detail;
341
+ const { element, deltaPoints } = eventDetail;
342
+ const worldPosDelta = deltaPoints?.world ?? [0, 0, 0];
343
+ const enabledElement = getEnabledElement(element);
344
+ const { renderingEngine } = enabledElement;
345
+
346
+ const { annotation, viewportIdsToRender } = this.editData;
347
+ const { points } = annotation.data.handles;
348
+
349
+ points.forEach((point) => {
350
+ point[0] += worldPosDelta[0];
351
+ point[1] += worldPosDelta[1];
352
+ point[2] += worldPosDelta[2];
353
+ });
354
+
355
+ annotation.invalidated = true;
356
+ this.editData.hasMoved = true;
357
+
358
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
359
+ };
360
+
361
+ _dragModifyCallback = (evt: EventTypes.InteractionEventType): void => {
362
+ this.isDrawing = true;
363
+ const eventDetail = evt.detail;
364
+ const { element } = eventDetail;
365
+
366
+ const { annotation, viewportIdsToRender, handleIndex } = this.editData;
367
+ const { data } = annotation;
368
+
369
+ if (handleIndex === undefined) {
370
+ // Moving tool
371
+ const { deltaPoints } = eventDetail;
372
+ const worldPosDelta = deltaPoints.world;
373
+
374
+ const points = data.handles.points;
375
+
376
+ points.forEach((point) => {
377
+ point[0] += worldPosDelta[0];
378
+ point[1] += worldPosDelta[1];
379
+ point[2] += worldPosDelta[2];
380
+ });
381
+ annotation.invalidated = true;
382
+ } else {
383
+ this._dragHandle(evt);
384
+ annotation.invalidated = true;
385
+ }
386
+
387
+ const enabledElement = getEnabledElement(element);
388
+ const { renderingEngine } = enabledElement;
389
+
390
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
391
+ };
392
+
393
+ _dragHandle = (evt: EventTypes.InteractionEventType): void => {
394
+ const eventDetail = evt.detail;
395
+ const { element } = eventDetail;
396
+ const enabledElement = getEnabledElement(element);
397
+ const { viewport } = enabledElement;
398
+ const { worldToCanvas } = viewport;
399
+
400
+ const { annotation } = this.editData;
401
+ const { data } = annotation;
402
+ const { points } = data.handles;
403
+
404
+ const canvasCoordinates = points.map((p) => worldToCanvas(p));
405
+ const canvasTop = canvasCoordinates[0];
406
+ const canvasBottom = canvasCoordinates[2];
407
+ const canvasLeft = canvasCoordinates[3];
408
+ const radius = Math.abs(canvasBottom[1] - canvasTop[1]) * 0.5;
409
+ const canvasCenter: Types.Point2 = [
410
+ canvasLeft[0] + radius,
411
+ canvasTop[1] + radius,
412
+ ];
413
+
414
+ const { currentPoints } = eventDetail;
415
+ const currentCanvasPoints = currentPoints.canvas;
416
+
417
+ const newRadius = getCanvasCircleRadius([
418
+ canvasCenter,
419
+ currentCanvasPoints,
420
+ ]);
421
+ const newWorldHandlesPoints = this._getWorldHandlesPoints(
422
+ viewport,
423
+ canvasCenter,
424
+ newRadius
425
+ );
426
+
427
+ points[0] = newWorldHandlesPoints[0];
428
+ points[1] = newWorldHandlesPoints[1];
429
+ points[2] = newWorldHandlesPoints[2];
430
+ points[3] = newWorldHandlesPoints[3];
431
+ };
432
+
433
+ cancel = (element: HTMLDivElement) => {
434
+ // If it is mid-draw or mid-modify
435
+ if (!this.isDrawing) {
436
+ return;
437
+ }
438
+
439
+ this.isDrawing = false;
440
+ this._deactivateModify(element);
441
+ resetElementCursor(element);
442
+
443
+ const { annotation, viewportIdsToRender, newAnnotation } = this.editData;
444
+ const { data } = annotation;
445
+
446
+ annotation.highlighted = false;
447
+ data.handles.activeHandleIndex = null;
448
+
449
+ const enabledElement = getEnabledElement(element);
450
+ const { renderingEngine } = enabledElement;
451
+
452
+ triggerAnnotationRenderForViewportIds(renderingEngine, viewportIdsToRender);
453
+
454
+ if (newAnnotation) {
455
+ const eventType = Events.ANNOTATION_COMPLETED;
456
+
457
+ const eventDetail: AnnotationCompletedEventDetail = {
458
+ annotation,
459
+ };
460
+
461
+ triggerEvent(eventTarget, eventType, eventDetail);
462
+ }
463
+
464
+ this.editData = null;
465
+ return annotation.annotationUID;
466
+ };
467
+
468
+ _activateModify = (element) => {
469
+ state.isInteractingWithTool = true;
470
+
471
+ element.addEventListener(Events.MOUSE_UP, this._endCallback);
472
+ element.addEventListener(Events.MOUSE_DRAG, this._dragModifyCallback);
473
+ element.addEventListener(Events.MOUSE_CLICK, this._endCallback);
474
+
475
+ element.addEventListener(Events.TOUCH_END, this._endCallback);
476
+ element.addEventListener(Events.TOUCH_DRAG, this._dragModifyCallback);
477
+ element.addEventListener(Events.TOUCH_TAP, this._endCallback);
478
+ };
479
+
480
+ _deactivateModify = (element) => {
481
+ state.isInteractingWithTool = false;
482
+
483
+ element.removeEventListener(Events.MOUSE_UP, this._endCallback);
484
+ element.removeEventListener(Events.MOUSE_DRAG, this._dragModifyCallback);
485
+ element.removeEventListener(Events.MOUSE_CLICK, this._endCallback);
486
+
487
+ element.removeEventListener(Events.TOUCH_END, this._endCallback);
488
+ element.removeEventListener(Events.TOUCH_DRAG, this._dragModifyCallback);
489
+ element.removeEventListener(Events.TOUCH_TAP, this._endCallback);
490
+ };
491
+
492
+ /**
493
+ * it is used to draw the circleROI annotation in each
494
+ * request animation frame. It calculates the updated cached statistics if
495
+ * data is invalidated and cache it.
496
+ *
497
+ * @param enabledElement - The Cornerstone's enabledElement.
498
+ * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.
499
+ */
500
+ renderAnnotation = (
501
+ enabledElement: Types.IEnabledElement,
502
+ svgDrawingHelper: SVGDrawingHelper
503
+ ): boolean => {
504
+ let renderStatus = false;
505
+ const { viewport } = enabledElement;
506
+ const { element } = viewport;
507
+
508
+ let annotations = getAnnotations(this.getToolName(), element);
509
+
510
+ if (!annotations?.length) {
511
+ return renderStatus;
512
+ }
513
+
514
+ annotations = this.filterInteractableAnnotationsForElement(
515
+ element,
516
+ annotations
517
+ );
518
+
519
+ annotations = annotations?.filter(
520
+ (annotation) =>
521
+ (<AdvancedMagnifyAnnotation>annotation).data.sourceViewportId ===
522
+ viewport.id
523
+ );
524
+
525
+ if (!annotations?.length) {
526
+ return renderStatus;
527
+ }
528
+
529
+ const styleSpecifier: StyleSpecifier = {
530
+ toolGroupId: this.toolGroupId,
531
+ toolName: this.getToolName(),
532
+ viewportId: enabledElement.viewport.id,
533
+ };
534
+
535
+ for (let i = 0; i < annotations.length; i++) {
536
+ const annotation = annotations[i] as AdvancedMagnifyAnnotation;
537
+ const { annotationUID, data } = annotation;
538
+ const { magnifyViewportId, zoomFactor, handles } = data;
539
+ const { points, activeHandleIndex } = handles;
540
+
541
+ styleSpecifier.annotationUID = annotationUID;
542
+
543
+ const lineWidth = this.getStyle('lineWidth', styleSpecifier, annotation);
544
+ const lineDash = this.getStyle('lineDash', styleSpecifier, annotation);
545
+ const color = this.getStyle('color', styleSpecifier, annotation);
546
+
547
+ const canvasCoordinates = points.map((p) =>
548
+ viewport.worldToCanvas(p)
549
+ ) as Types.Point2[];
550
+ const canvasTop = canvasCoordinates[0];
551
+ const canvasBottom = canvasCoordinates[2];
552
+ const canvasLeft = canvasCoordinates[3];
553
+ const radius = Math.abs(canvasBottom[1] - canvasTop[1]) * 0.5;
554
+ const center = [
555
+ canvasLeft[0] + radius,
556
+ canvasTop[1] + radius,
557
+ ] as Types.Point2;
558
+
559
+ // If rendering engine has been destroyed while rendering
560
+ if (!viewport.getRenderingEngine()) {
561
+ console.warn('Rendering Engine has been destroyed');
562
+ return renderStatus;
563
+ }
564
+
565
+ let activeHandleCanvasCoords;
566
+
567
+ if (!isAnnotationVisible(annotationUID)) {
568
+ continue;
569
+ }
570
+
571
+ if (
572
+ !isAnnotationLocked(annotation) &&
573
+ !this.editData &&
574
+ activeHandleIndex !== null
575
+ ) {
576
+ // Not locked or creating and hovering over handle, so render handle.
577
+ activeHandleCanvasCoords = [canvasCoordinates[activeHandleIndex]];
578
+ }
579
+
580
+ if (activeHandleCanvasCoords) {
581
+ const handleGroupUID = '0';
582
+ drawHandlesSvg(
583
+ svgDrawingHelper,
584
+ annotationUID,
585
+ handleGroupUID,
586
+ activeHandleCanvasCoords,
587
+ {
588
+ color,
589
+ }
590
+ );
591
+ }
592
+
593
+ const dataId = `${annotationUID}-advancedMagnify`;
594
+ const circleUID = '0';
595
+ drawCircleSvg(
596
+ svgDrawingHelper,
597
+ annotationUID,
598
+ circleUID,
599
+ center,
600
+ radius,
601
+ {
602
+ color,
603
+ lineDash,
604
+ lineWidth,
605
+ },
606
+ dataId
607
+ );
608
+
609
+ const magnifyViewport =
610
+ this.magnifyViewportManager.getViewport(magnifyViewportId);
611
+
612
+ magnifyViewport.position = center;
613
+ magnifyViewport.radius = radius;
614
+ magnifyViewport.zoomFactor = zoomFactor;
615
+ magnifyViewport.update();
616
+
617
+ renderStatus = true;
618
+ }
619
+
620
+ return renderStatus;
621
+ };
622
+
623
+ // Basic dropdown component that allows the user to select a different zoom factor.
624
+ // configurations.actions may be changed to use a customized dropdown.
625
+ public showZoomFactorsList(
626
+ evt: EventTypes.InteractionEventType,
627
+ annotation: AdvancedMagnifyAnnotation
628
+ ) {
629
+ const { element, currentPoints } = evt.detail;
630
+ const enabledElement = getEnabledElement(element);
631
+ const { viewport } = enabledElement;
632
+ const { canvas: canvasPoint } = currentPoints;
633
+ const viewportElement = element.querySelector(':scope .viewport-element');
634
+ const currentZoomFactor = annotation.data.zoomFactor;
635
+ const remove = () => dropdown.parentElement.removeChild(dropdown);
636
+
637
+ const dropdown = this._getZoomFactorsListDropdown(
638
+ currentZoomFactor,
639
+ (newZoomFactor) => {
640
+ if (newZoomFactor !== undefined) {
641
+ annotation.data.zoomFactor = Number.parseFloat(newZoomFactor);
642
+ annotation.invalidated = true;
643
+ }
644
+
645
+ remove();
646
+ viewport.render();
647
+ }
648
+ );
649
+
650
+ Object.assign(dropdown.style, {
651
+ left: `${canvasPoint[0]}px`,
652
+ top: `${canvasPoint[1]}px`,
653
+ });
654
+
655
+ viewportElement.appendChild(dropdown);
656
+ dropdown.focus();
657
+ }
658
+
659
+ private _getZoomFactorsListDropdown(currentZoomFactor, onChangeCallback) {
660
+ const { zoomFactorList } = this.configuration.magnifyingGlass;
661
+ const dropdown = document.createElement('select');
662
+
663
+ dropdown.size = 5;
664
+ Object.assign(dropdown.style, {
665
+ width: '50px',
666
+ position: 'absolute',
667
+ });
668
+
669
+ ['mousedown', 'mouseup', 'mousemove', 'click'].forEach((eventName) => {
670
+ dropdown.addEventListener(eventName, (evt) => evt.stopPropagation());
671
+ });
672
+
673
+ dropdown.addEventListener('change', (evt) => {
674
+ evt.stopPropagation();
675
+ onChangeCallback(dropdown.value);
676
+ });
677
+
678
+ dropdown.addEventListener('keydown', (evt) => {
679
+ const shouldCancel =
680
+ (evt.keyCode ?? evt.which === 27) ||
681
+ evt.key?.toLowerCase() === 'escape';
682
+
683
+ if (shouldCancel) {
684
+ evt.stopPropagation();
685
+ onChangeCallback();
686
+ }
687
+ });
688
+
689
+ zoomFactorList.forEach((zoomFactor) => {
690
+ const option = document.createElement('option');
691
+
692
+ option.label = zoomFactor;
693
+ option.title = `Zoom factor ${zoomFactor.toFixed(1)}`;
694
+ option.value = zoomFactor;
695
+ option.defaultSelected = zoomFactor === currentZoomFactor;
696
+
697
+ dropdown.add(option);
698
+ });
699
+
700
+ return dropdown;
701
+ }
702
+
703
+ private _getWorldHandlesPoints = (
704
+ viewport,
705
+ canvasCenterPos,
706
+ canvasRadius
707
+ ): Types.Point3[] => {
708
+ const canvasHandlesPoints = [
709
+ [canvasCenterPos[0], canvasCenterPos[1] - canvasRadius], // top
710
+ [canvasCenterPos[0] + canvasRadius, canvasCenterPos[1]], // right
711
+ [canvasCenterPos[0], canvasCenterPos[1] + canvasRadius], // bottom
712
+ [canvasCenterPos[0] - canvasRadius, canvasCenterPos[1]], // left
713
+ ];
714
+
715
+ const worldHandlesPoints = canvasHandlesPoints.map((p) =>
716
+ viewport.canvasToWorld(p)
717
+ ) as Types.Point3[];
718
+
719
+ return worldHandlesPoints;
720
+ };
721
+ }
722
+
723
+ AdvancedMagnifyTool.toolName = 'AdvancedMagnify';
724
+
725
+ export { AdvancedMagnifyTool as default };