UNPKG

mv-cornerstone-tools

Version:

Medical imaging tools for the Cornerstone library

1,509 lines (1,131 loc) 651 kB
/*! mv-cornerstone-tools - 2.3.21 - 2018-11-23 | (c) 2017 Chris Hafey | https://github.com/tonyrapozo/cornerstoneTools */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define("cornerstoneTools", [], factory); else if(typeof exports === 'object') exports["cornerstoneTools"] = factory(); else root["cornerstoneTools"] = factory(); })(window, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = "./index.js"); /******/ }) /************************************************************************/ /******/ ({ /***/ "./events.js": /*!*******************!*\ !*** ./events.js ***! \*******************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var EVENTS = { // Events from Cornerstone Core IMAGE_RENDERED: 'cornerstoneimagerendered', NEW_IMAGE: 'cornerstonenewimage', IMAGE_CACHE_PROMISE_REMOVED: 'cornerstoneimagecachepromiseremoved', ELEMENT_DISABLED: 'cornerstoneelementdisabled', // Mouse events MOUSE_DOWN: 'cornerstonetoolsmousedown', MOUSE_UP: 'cornerstonetoolsmouseup', MOUSE_DOWN_ACTIVATE: 'cornerstonetoolsmousedownactivate', MOUSE_DRAG: 'cornerstonetoolsmousedrag', MOUSE_MOVE: 'cornerstonetoolsmousemove', MOUSE_CLICK: 'cornerstonetoolsmouseclick', MOUSE_DOUBLE_CLICK: 'cornerstonetoolsmousedoubleclick', MOUSE_WHEEL: 'cornerstonetoolsmousewheel', // Touch events TOUCH_START: 'cornerstonetoolstouchstart', TOUCH_START_ACTIVE: 'cornerstonetoolstouchstartactive', TOUCH_END: 'cornerstonetoolstouchend', TOUCH_DRAG: 'cornerstonetoolstouchdrag', TOUCH_DRAG_END: 'cornerstonetoolstouchdragend', TOUCH_PINCH: 'cornerstonetoolstouchpinch', TOUCH_ROTATE: 'cornerstonetoolstouchrotate', TOUCH_PRESS: 'cornerstonetoolstouchpress', TAP: 'cornerstonetoolstap', DOUBLE_TAP: 'cornerstonetoolsdoubletap', MULTI_TOUCH_START: 'cornerstonetoolsmultitouchstart', MULTI_TOUCH_START_ACTIVE: 'cornerstonetoolsmultitouchstartactive', MULTI_TOUCH_DRAG: 'cornerstonetoolsmultitouchdrag', // Keyboard events KEY_DOWN: 'cornerstonetoolskeydown', KEY_UP: 'cornerstonetoolskeyup', KEY_PRESS: 'cornerstonetoolskeypress', // Measurement / tool events MEASUREMENT_ADDED: 'cornerstonetoolsmeasurementadded', MEASUREMENT_MODIFIED: 'cornerstonetoolsmeasurementmodified', MEASUREMENT_REMOVED: 'cornerstonemeasurementremoved', TOOL_DEACTIVATED: 'cornerstonetoolstooldeactivated', CLIP_STOPPED: 'cornerstonetoolsclipstopped', STACK_SCROLL: 'cornerstonestackscroll', // Should be renamed LINE_SAMPLE_UPDATED: 'cornerstonelinesampleupdated', IMAGE_PREFETCHED: 'cornerstoneimageprefethed' }; exports.default = EVENTS; /***/ }), /***/ "./externalModules.js": /*!****************************!*\ !*** ./externalModules.js ***! \****************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var cornerstone = window.cornerstone; var cornerstoneMath = window.cornerstoneMath; var Hammer = window.Hammer; exports.default = { set cornerstone(cs) { cornerstone = cs; }, get cornerstone() { return cornerstone; }, set cornerstoneMath(cm) { cornerstoneMath = cm; }, get cornerstoneMath() { return cornerstoneMath; }, set Hammer(module) { Hammer = module; }, get Hammer() { return Hammer; } }; /***/ }), /***/ "./imageTools/angleTool.js": /*!*********************************!*\ !*** ./imageTools/angleTool.js ***! \*********************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.angleTouch = exports.angle = undefined; var _externalModules = __webpack_require__(/*! ../externalModules.js */ "./externalModules.js"); var _externalModules2 = _interopRequireDefault(_externalModules); var _mouseButtonTool = __webpack_require__(/*! ./mouseButtonTool.js */ "./imageTools/mouseButtonTool.js"); var _mouseButtonTool2 = _interopRequireDefault(_mouseButtonTool); var _touchTool = __webpack_require__(/*! ./touchTool.js */ "./imageTools/touchTool.js"); var _touchTool2 = _interopRequireDefault(_touchTool); var _drawTextBox = __webpack_require__(/*! ../util/drawTextBox.js */ "./util/drawTextBox.js"); var _drawTextBox2 = _interopRequireDefault(_drawTextBox); var _roundToDecimal = __webpack_require__(/*! ../util/roundToDecimal.js */ "./util/roundToDecimal.js"); var _roundToDecimal2 = _interopRequireDefault(_roundToDecimal); var _toolStyle = __webpack_require__(/*! ../stateManagement/toolStyle.js */ "./stateManagement/toolStyle.js"); var _toolStyle2 = _interopRequireDefault(_toolStyle); var _textStyle = __webpack_require__(/*! ../stateManagement/textStyle.js */ "./stateManagement/textStyle.js"); var _textStyle2 = _interopRequireDefault(_textStyle); var _toolColors = __webpack_require__(/*! ../stateManagement/toolColors.js */ "./stateManagement/toolColors.js"); var _toolColors2 = _interopRequireDefault(_toolColors); var _drawHandles = __webpack_require__(/*! ../manipulators/drawHandles.js */ "./manipulators/drawHandles.js"); var _drawHandles2 = _interopRequireDefault(_drawHandles); var _toolState = __webpack_require__(/*! ../stateManagement/toolState.js */ "./stateManagement/toolState.js"); var _lineSegDistance = __webpack_require__(/*! ../util/lineSegDistance.js */ "./util/lineSegDistance.js"); var _lineSegDistance2 = _interopRequireDefault(_lineSegDistance); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var toolType = 'angle'; // /////// BEGIN ACTIVE TOOL /////// function createNewMeasurement(mouseEventData) { // Create the measurement data for this tool with the end handle activated var angleData = { visible: true, active: true, color: undefined, handles: { start: { x: mouseEventData.currentPoints.image.x - 20, y: mouseEventData.currentPoints.image.y + 10, highlight: true, active: false }, end: { x: mouseEventData.currentPoints.image.x, y: mouseEventData.currentPoints.image.y, highlight: true, active: true }, start2: { x: mouseEventData.currentPoints.image.x - 20, y: mouseEventData.currentPoints.image.y + 10, highlight: true, active: false }, end2: { x: mouseEventData.currentPoints.image.x, y: mouseEventData.currentPoints.image.y + 20, highlight: true, active: false } } }; return angleData; } // /////// END ACTIVE TOOL /////// function pointNearTool(element, data, coords) { if (data.visible === false) { return false; } return (0, _lineSegDistance2.default)(element, data.handles.start, data.handles.end, coords) < 5 || (0, _lineSegDistance2.default)(element, data.handles.start2, data.handles.end2, coords) < 5; } // /////// BEGIN IMAGE RENDERING /////// function onImageRendered(e) { var eventData = e.detail; // If we have no toolData for this element, return immediately as there is nothing to do var toolData = (0, _toolState.getToolState)(e.currentTarget, toolType); if (toolData === undefined) { return; } // We have tool data for this element - iterate over each one and draw it var context = eventData.canvasContext.canvas.getContext('2d'); context.setTransform(1, 0, 0, 1, 0, 0); var lineWidth = _toolStyle2.default.getToolWidth(); var font = _textStyle2.default.getFont(); var config = angle.getConfiguration(); var cornerstone = _externalModules2.default.cornerstone; for (var i = 0; i < toolData.data.length; i++) { context.save(); // Configurable shadow if (config && config.shadow) { context.shadowColor = config.shadowColor || '#000000'; context.shadowOffsetX = config.shadowOffsetX || 1; context.shadowOffsetY = config.shadowOffsetY || 1; } var data = toolData.data[i]; if (data.visible === false) { continue; } // Differentiate the color of activation tool var color = _toolColors2.default.getColorIfActive(data); // Draw the line context.beginPath(); context.strokeStyle = color; context.lineWidth = lineWidth; var handleStartCanvas = cornerstone.pixelToCanvas(eventData.element, data.handles.start); var handleEndCanvas = cornerstone.pixelToCanvas(eventData.element, data.handles.end); context.moveTo(handleStartCanvas.x, handleStartCanvas.y); context.lineTo(handleEndCanvas.x, handleEndCanvas.y); handleStartCanvas = cornerstone.pixelToCanvas(eventData.element, data.handles.start2); handleEndCanvas = cornerstone.pixelToCanvas(eventData.element, data.handles.end2); context.moveTo(handleStartCanvas.x, handleStartCanvas.y); context.lineTo(handleEndCanvas.x, handleEndCanvas.y); context.stroke(); // Draw the handles (0, _drawHandles2.default)(context, eventData, data.handles); // Draw the text context.fillStyle = color; // Need to work on correct angle to measure. This is a cobb angle and we need to determine // Where lines cross to measure angle. For now it will show smallest angle. var dx1 = (Math.ceil(data.handles.start.x) - Math.ceil(data.handles.end.x)) * eventData.image.columnPixelSpacing; var dy1 = (Math.ceil(data.handles.start.y) - Math.ceil(data.handles.end.y)) * eventData.image.rowPixelSpacing; var dx2 = (Math.ceil(data.handles.start2.x) - Math.ceil(data.handles.end2.x)) * eventData.image.columnPixelSpacing; var dy2 = (Math.ceil(data.handles.start2.y) - Math.ceil(data.handles.end2.y)) * eventData.image.rowPixelSpacing; var _angle = Math.acos(Math.abs((dx1 * dx2 + dy1 * dy2) / (Math.sqrt(dx1 * dx1 + dy1 * dy1) * Math.sqrt(dx2 * dx2 + dy2 * dy2)))); _angle *= 180 / Math.PI; var rAngle = (0, _roundToDecimal2.default)(_angle, 2); var str = '00B0'; // Degrees symbol var text = rAngle.toString() + String.fromCharCode(parseInt(str, 16)); var textX = (handleStartCanvas.x + handleEndCanvas.x) / 2; var textY = (handleStartCanvas.y + handleEndCanvas.y) / 2; context.font = font; (0, _drawTextBox2.default)(context, text, textX, textY, color); context.restore(); } } // /////// END IMAGE RENDERING /////// // Module exports var angle = (0, _mouseButtonTool2.default)({ createNewMeasurement: createNewMeasurement, onImageRendered: onImageRendered, pointNearTool: pointNearTool, toolType: toolType }); var angleTouch = (0, _touchTool2.default)({ createNewMeasurement: createNewMeasurement, onImageRendered: onImageRendered, pointNearTool: pointNearTool, toolType: toolType }); exports.angle = angle; exports.angleTouch = angleTouch; /***/ }), /***/ "./imageTools/arrowAnnotate.js": /*!*************************************!*\ !*** ./imageTools/arrowAnnotate.js ***! \*************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.arrowAnnotateTouch = exports.arrowAnnotate = undefined; var _events = __webpack_require__(/*! ../events.js */ "./events.js"); var _events2 = _interopRequireDefault(_events); var _externalModules = __webpack_require__(/*! ../externalModules.js */ "./externalModules.js"); var _externalModules2 = _interopRequireDefault(_externalModules); var _mouseButtonTool = __webpack_require__(/*! ./mouseButtonTool.js */ "./imageTools/mouseButtonTool.js"); var _mouseButtonTool2 = _interopRequireDefault(_mouseButtonTool); var _touchTool = __webpack_require__(/*! ./touchTool.js */ "./imageTools/touchTool.js"); var _touchTool2 = _interopRequireDefault(_touchTool); var _toolStyle = __webpack_require__(/*! ../stateManagement/toolStyle.js */ "./stateManagement/toolStyle.js"); var _toolStyle2 = _interopRequireDefault(_toolStyle); var _textStyle = __webpack_require__(/*! ../stateManagement/textStyle.js */ "./stateManagement/textStyle.js"); var _textStyle2 = _interopRequireDefault(_textStyle); var _toolColors = __webpack_require__(/*! ../stateManagement/toolColors.js */ "./stateManagement/toolColors.js"); var _toolColors2 = _interopRequireDefault(_toolColors); var _drawHandles = __webpack_require__(/*! ../manipulators/drawHandles.js */ "./manipulators/drawHandles.js"); var _drawHandles2 = _interopRequireDefault(_drawHandles); var _drawArrow = __webpack_require__(/*! ../util/drawArrow.js */ "./util/drawArrow.js"); var _drawArrow2 = _interopRequireDefault(_drawArrow); var _moveNewHandle = __webpack_require__(/*! ../manipulators/moveNewHandle.js */ "./manipulators/moveNewHandle.js"); var _moveNewHandle2 = _interopRequireDefault(_moveNewHandle); var _moveNewHandleTouch = __webpack_require__(/*! ../manipulators/moveNewHandleTouch.js */ "./manipulators/moveNewHandleTouch.js"); var _moveNewHandleTouch2 = _interopRequireDefault(_moveNewHandleTouch); var _anyHandlesOutsideImage = __webpack_require__(/*! ../manipulators/anyHandlesOutsideImage.js */ "./manipulators/anyHandlesOutsideImage.js"); var _anyHandlesOutsideImage2 = _interopRequireDefault(_anyHandlesOutsideImage); var _isMouseButtonEnabled = __webpack_require__(/*! ../util/isMouseButtonEnabled.js */ "./util/isMouseButtonEnabled.js"); var _isMouseButtonEnabled2 = _interopRequireDefault(_isMouseButtonEnabled); var _pointInsideBoundingBox = __webpack_require__(/*! ../util/pointInsideBoundingBox.js */ "./util/pointInsideBoundingBox.js"); var _pointInsideBoundingBox2 = _interopRequireDefault(_pointInsideBoundingBox); var _drawLinkedTextBox = __webpack_require__(/*! ../util/drawLinkedTextBox.js */ "./util/drawLinkedTextBox.js"); var _drawLinkedTextBox2 = _interopRequireDefault(_drawLinkedTextBox); var _toolState = __webpack_require__(/*! ../stateManagement/toolState.js */ "./stateManagement/toolState.js"); var _toolOptions = __webpack_require__(/*! ../toolOptions.js */ "./toolOptions.js"); var _lineSegDistance = __webpack_require__(/*! ../util/lineSegDistance.js */ "./util/lineSegDistance.js"); var _lineSegDistance2 = _interopRequireDefault(_lineSegDistance); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* eslint no-alert:0 */ var toolType = 'arrowAnnotate'; // Define a callback to get your text annotation // This could be used, e.g. to open a modal function getTextCallback(doneChangingTextCallback) { doneChangingTextCallback(prompt('Enter your annotation:')); } function changeTextCallback(data, eventData, doneChangingTextCallback) { doneChangingTextCallback(prompt('Change your annotation:')); } var configuration = { getTextCallback: getTextCallback, changeTextCallback: changeTextCallback, drawHandles: false, drawHandlesOnHover: true, arrowFirst: true }; // / --- Mouse Tool --- /// // /////// BEGIN ACTIVE TOOL /////// function addNewMeasurement(mouseEventData) { var element = mouseEventData.element; var measurementData = createNewMeasurement(mouseEventData); var cornerstone = _externalModules2.default.cornerstone; function doneChangingTextCallback(text) { if (text === null) { (0, _toolState.removeToolState)(element, toolType, measurementData); } else { measurementData.text = text; } measurementData.active = false; cornerstone.updateImage(element); element.addEventListener(_events2.default.MOUSE_MOVE, arrowAnnotate.mouseMoveCallback); element.addEventListener(_events2.default.MOUSE_DOWN, arrowAnnotate.mouseDownCallback); element.addEventListener(_events2.default.MOUSE_DOWN_ACTIVATE, arrowAnnotate.mouseDownActivateCallback); element.addEventListener(_events2.default.MOUSE_DOUBLE_CLICK, arrowAnnotate.mouseDoubleClickCallback); } // Associate this data with this imageId so we can render it and manipulate it (0, _toolState.addToolState)(element, toolType, measurementData); // Since we are dragging to another place to drop the end point, we can just activate // The end point and let the moveHandle move it for us. element.removeEventListener(_events2.default.MOUSE_MOVE, arrowAnnotate.mouseMoveCallback); element.removeEventListener(_events2.default.MOUSE_DOWN, arrowAnnotate.mouseDownCallback); element.removeEventListener(_events2.default.MOUSE_DOWN_ACTIVATE, arrowAnnotate.mouseDownActivateCallback); element.removeEventListener(_events2.default.MOUSE_DOUBLE_CLICK, arrowAnnotate.mouseDoubleClickCallback); cornerstone.updateImage(element); (0, _moveNewHandle2.default)(mouseEventData, toolType, measurementData, measurementData.handles.end, function () { if ((0, _anyHandlesOutsideImage2.default)(mouseEventData, measurementData.handles)) { // Delete the measurement (0, _toolState.removeToolState)(element, toolType, measurementData); } var config = arrowAnnotate.getConfiguration(); if (measurementData.text === undefined) { config.getTextCallback(doneChangingTextCallback); } cornerstone.updateImage(element); }); } function createNewMeasurement(eventData) { // Create the measurement data for this tool with the end handle activated var measurementData = { visible: true, active: true, color: undefined, handles: { start: { x: eventData.currentPoints.image.x, y: eventData.currentPoints.image.y, highlight: true, active: false }, end: { x: eventData.currentPoints.image.x, y: eventData.currentPoints.image.y, highlight: true, active: false }, textBox: { active: false, hasMoved: false, movesIndependently: false, drawnIndependently: true, allowedOutsideImage: true, hasBoundingBox: true } } }; return measurementData; } // /////// END ACTIVE TOOL /////// function pointNearTool(element, data, coords) { if (data.visible === false) { return false; } return (0, _lineSegDistance2.default)(element, data.handles.start, data.handles.end, coords) < 25; } // /////// BEGIN IMAGE RENDERING /////// function onImageRendered(e) { var eventData = e.detail; // If we have no toolData for this element, return immediately as there is nothing to do var toolData = (0, _toolState.getToolState)(e.currentTarget, toolType); if (!toolData) { return; } var enabledElement = eventData.enabledElement; var cornerstone = _externalModules2.default.cornerstone; // We have tool data for this element - iterate over each one and draw it var context = eventData.canvasContext.canvas.getContext('2d'); context.setTransform(1, 0, 0, 1, 0, 0); var lineWidth = _toolStyle2.default.getToolWidth(); var font = _textStyle2.default.getFont(); var config = arrowAnnotate.getConfiguration(); for (var i = 0; i < toolData.data.length; i++) { context.save(); if (config && config.shadow) { context.shadowColor = config.shadowColor || '#000000'; context.shadowOffsetX = config.shadowOffsetX || 1; context.shadowOffsetY = config.shadowOffsetY || 1; } var data = toolData.data[i]; if (data.visible === false) { continue; } var color = _toolColors2.default.getColorIfActive(data); // Draw the arrow var handleStartCanvas = cornerstone.pixelToCanvas(eventData.element, data.handles.start); var handleEndCanvas = cornerstone.pixelToCanvas(eventData.element, data.handles.end); // Config.arrowFirst = false; if (config.arrowFirst) { (0, _drawArrow2.default)(context, handleEndCanvas, handleStartCanvas, color, lineWidth); } else { (0, _drawArrow2.default)(context, handleStartCanvas, handleEndCanvas, color, lineWidth); } var handleOptions = { drawHandlesIfActive: config && config.drawHandlesOnHover }; if (config.drawHandles) { (0, _drawHandles2.default)(context, eventData, data.handles, color, handleOptions); } var text = textBoxText(data); // Draw the text if (text && text !== '') { context.font = font; // Calculate the text coordinates. var textWidth = context.measureText(text).width + 10; var textHeight = _textStyle2.default.getFontSize() + 10; var distance = Math.max(textWidth, textHeight) / 2 + 5; if (handleEndCanvas.x < handleStartCanvas.x) { distance = -distance; } if (!data.handles.textBox.hasMoved) { var textCoords = void 0; if (config.arrowFirst) { textCoords = { x: handleEndCanvas.x - textWidth / 2 + distance, y: handleEndCanvas.y - textHeight / 2 }; } else { // If the arrow is at the End position, the text should // Be placed near the Start position textCoords = { x: handleStartCanvas.x - textWidth / 2 - distance, y: handleStartCanvas.y - textHeight / 2 }; } var transform = cornerstone.internal.getTransform(enabledElement); transform.invert(); var coords = transform.transformPoint(textCoords.x, textCoords.y); data.handles.textBox.x = coords.x; data.handles.textBox.y = coords.y; } (0, _drawLinkedTextBox2.default)(context, eventData.element, data.handles.textBox, text, data.handles, textBoxAnchorPoints, color, lineWidth, 0, false); } context.restore(); } function textBoxText(data) { return data.text; } function textBoxAnchorPoints(handles) { var midpoint = { x: (handles.start.x + handles.end.x) / 2, y: (handles.start.y + handles.end.y) / 2 }; return [handles.start, midpoint, handles.end]; } } // ---- Touch tool ---- // /////// BEGIN ACTIVE TOOL /////// function addNewMeasurementTouch(touchEventData) { var element = touchEventData.element; var measurementData = createNewMeasurement(touchEventData); var cornerstone = _externalModules2.default.cornerstone; function doneChangingTextCallback(text) { if (text === null) { (0, _toolState.removeToolState)(element, toolType, measurementData); } else { measurementData.text = text; } measurementData.active = false; cornerstone.updateImage(element); element.addEventListener(_events2.default.TOUCH_PRESS, arrowAnnotateTouch.pressCallback); element.addEventListener(_events2.default.TOUCH_START_ACTIVE, arrowAnnotateTouch.touchDownActivateCallback); element.addEventListener(_events2.default.TAP, arrowAnnotateTouch.tapCallback); } (0, _toolState.addToolState)(element, toolType, measurementData); element.removeEventListener(_events2.default.TOUCH_PRESS, arrowAnnotateTouch.pressCallback); element.removeEventListener(_events2.default.TOUCH_START_ACTIVE, arrowAnnotateTouch.touchDownActivateCallback); element.removeEventListener(_events2.default.TAP, arrowAnnotateTouch.tapCallback); cornerstone.updateImage(element); (0, _moveNewHandleTouch2.default)(touchEventData, toolType, measurementData, measurementData.handles.end, function () { cornerstone.updateImage(element); if ((0, _anyHandlesOutsideImage2.default)(touchEventData, measurementData.handles)) { // Delete the measurement (0, _toolState.removeToolState)(element, toolType, measurementData); } var config = arrowAnnotate.getConfiguration(); if (measurementData.text === undefined) { config.getTextCallback(doneChangingTextCallback); } }); } function doubleClickCallback(e) { var eventData = e.detail; var element = eventData.element; var cornerstone = _externalModules2.default.cornerstone; var options = (0, _toolOptions.getToolOptions)(toolType, element); var data = void 0; if (!(0, _isMouseButtonEnabled2.default)(eventData.which, options.mouseButtonMask)) { return; } function doneChangingTextCallback(data, updatedText, deleteTool) { if (deleteTool === true) { (0, _toolState.removeToolState)(element, toolType, data); } else { data.text = updatedText; } data.active = false; cornerstone.updateImage(element); } var config = arrowAnnotate.getConfiguration(); var coords = eventData.currentPoints.canvas; var toolData = (0, _toolState.getToolState)(element, toolType); // Now check to see if there is a handle we can move if (!toolData) { return; } for (var i = 0; i < toolData.data.length; i++) { data = toolData.data[i]; if (pointNearTool(element, data, coords) || (0, _pointInsideBoundingBox2.default)(data.handles.textBox, coords)) { data.active = true; cornerstone.updateImage(element); // Allow relabelling via a callback config.changeTextCallback(data, eventData, doneChangingTextCallback); e.stopImmediatePropagation(); return false; } } } function pressCallback(e) { var eventData = e.detail; var element = eventData.element; var cornerstone = _externalModules2.default.cornerstone; var data = void 0; function doneChangingTextCallback(data, updatedText, deleteTool) { console.log('pressCallback doneChangingTextCallback'); if (deleteTool === true) { (0, _toolState.removeToolState)(element, toolType, data); } else { data.text = updatedText; } data.active = false; cornerstone.updateImage(element); element.addEventListener(_events2.default.TOUCH_START, arrowAnnotateTouch.touchStartCallback); element.addEventListener(_events2.default.TOUCH_START_ACTIVE, arrowAnnotateTouch.touchDownActivateCallback); element.addEventListener(_events2.default.TAP, arrowAnnotateTouch.tapCallback); } var config = arrowAnnotate.getConfiguration(); var coords = eventData.currentPoints.canvas; var toolData = (0, _toolState.getToolState)(element, toolType); // Now check to see if there is a handle we can move if (!toolData) { return; } if (eventData.handlePressed) { element.removeEventListener(_events2.default.TOUCH_START, arrowAnnotateTouch.touchStartCallback); element.removeEventListener(_events2.default.TOUCH_START_ACTIVE, arrowAnnotateTouch.touchDownActivateCallback); element.removeEventListener(_events2.default.TAP, arrowAnnotateTouch.tapCallback); // Allow relabelling via a callback config.changeTextCallback(eventData.handlePressed, eventData, doneChangingTextCallback); e.stopImmediatePropagation(); return false; } for (var i = 0; i < toolData.data.length; i++) { data = toolData.data[i]; if (pointNearTool(element, data, coords) || (0, _pointInsideBoundingBox2.default)(data.handles.textBox, coords)) { data.active = true; cornerstone.updateImage(element); element.removeEventListener(_events2.default.TOUCH_START, arrowAnnotateTouch.touchStartCallback); element.removeEventListener(_events2.default.TOUCH_START_ACTIVE, arrowAnnotateTouch.touchDownActivateCallback); element.removeEventListener(_events2.default.TAP, arrowAnnotateTouch.tapCallback); // Allow relabelling via a callback config.changeTextCallback(data, eventData, doneChangingTextCallback); e.stopImmediatePropagation(); return false; } } e.preventDefault(); e.stopPropagation(); } var arrowAnnotate = (0, _mouseButtonTool2.default)({ addNewMeasurement: addNewMeasurement, createNewMeasurement: createNewMeasurement, onImageRendered: onImageRendered, pointNearTool: pointNearTool, toolType: toolType, mouseDoubleClickCallback: doubleClickCallback }); arrowAnnotate.setConfiguration(configuration); var arrowAnnotateTouch = (0, _touchTool2.default)({ addNewMeasurement: addNewMeasurementTouch, createNewMeasurement: createNewMeasurement, onImageRendered: onImageRendered, pointNearTool: pointNearTool, toolType: toolType, pressCallback: pressCallback }); exports.arrowAnnotate = arrowAnnotate; exports.arrowAnnotateTouch = arrowAnnotateTouch; /***/ }), /***/ "./imageTools/crosshairs.js": /*!**********************************!*\ !*** ./imageTools/crosshairs.js ***! \**********************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.crosshairsTouch = exports.crosshairs = undefined; var _events = __webpack_require__(/*! ../events.js */ "./events.js"); var _events2 = _interopRequireDefault(_events); var _externalModules = __webpack_require__(/*! ../externalModules.js */ "./externalModules.js"); var _externalModules2 = _interopRequireDefault(_externalModules); var _loadHandlerManager = __webpack_require__(/*! ../stateManagement/loadHandlerManager.js */ "./stateManagement/loadHandlerManager.js"); var _loadHandlerManager2 = _interopRequireDefault(_loadHandlerManager); var _toolState = __webpack_require__(/*! ../stateManagement/toolState.js */ "./stateManagement/toolState.js"); var _isMouseButtonEnabled = __webpack_require__(/*! ../util/isMouseButtonEnabled.js */ "./util/isMouseButtonEnabled.js"); var _isMouseButtonEnabled2 = _interopRequireDefault(_isMouseButtonEnabled); var _pointProjector = __webpack_require__(/*! ../util/pointProjector.js */ "./util/pointProjector.js"); var _convertToVector = __webpack_require__(/*! ../util/convertToVector3.js */ "./util/convertToVector3.js"); var _convertToVector2 = _interopRequireDefault(_convertToVector); var _toolOptions = __webpack_require__(/*! ../toolOptions.js */ "./toolOptions.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var toolType = 'crosshairs'; function chooseLocation(e) { var eventData = e.detail; e.stopImmediatePropagation(); // Prevent CornerstoneToolsTouchStartActive from killing any press events // If we have no toolData for this element, return immediately as there is nothing to do var toolData = (0, _toolState.getToolState)(e.currentTarget, toolType); if (!toolData) { return; } // Get current element target information var cornerstone = _externalModules2.default.cornerstone; var sourceElement = e.currentTarget; var sourceEnabledElement = cornerstone.getEnabledElement(sourceElement); var sourceImageId = sourceEnabledElement.image.imageId; var sourceImagePlane = cornerstone.metaData.get('imagePlaneModule', sourceImageId); if (!sourceImagePlane) { return; } // Get currentPoints from mouse cursor on selected element var sourceImagePoint = eventData.currentPoints.image; // Transfer this to a patientPoint given imagePlane metadata var patientPoint = (0, _pointProjector.imagePointToPatientPoint)(sourceImagePoint, sourceImagePlane); // Get the enabled elements associated with this synchronization context var syncContext = toolData.data[0].synchronizationContext; var enabledElements = syncContext.getSourceElements(); // Iterate over each synchronized element enabledElements.forEach(function (targetElement) { // Don't do anything if the target is the same as the source if (targetElement === sourceElement) { return; } var minDistance = Number.MAX_VALUE; var newImageIdIndex = -1; var stackToolDataSource = (0, _toolState.getToolState)(targetElement, 'stack'); if (stackToolDataSource === undefined) { return; } var stackData = stackToolDataSource.data[0]; // Find within the element's stack the closest image plane to selected location stackData.imageIds.forEach(function (imageId, index) { var imagePlane = cornerstone.metaData.get('imagePlaneModule', imageId); // Skip if the image plane is not ready if (!imagePlane || !imagePlane.imagePositionPatient || !imagePlane.rowCosines || !imagePlane.columnCosines) { return; } var imagePosition = (0, _convertToVector2.default)(imagePlane.imagePositionPatient); var row = (0, _convertToVector2.default)(imagePlane.rowCosines); var column = (0, _convertToVector2.default)(imagePlane.columnCosines); var normal = column.clone().cross(row.clone()); var distance = Math.abs(normal.clone().dot(imagePosition) - normal.clone().dot(patientPoint)); // Console.log(index + '=' + distance); if (distance < minDistance) { minDistance = distance; newImageIdIndex = index; } }); if (newImageIdIndex === stackData.currentImageIdIndex) { return; } // Switch the loaded image to the required image if (newImageIdIndex !== -1 && stackData.imageIds[newImageIdIndex] !== undefined) { var startLoadingHandler = _loadHandlerManager2.default.getStartLoadHandler(); var endLoadingHandler = _loadHandlerManager2.default.getEndLoadHandler(); var errorLoadingHandler = _loadHandlerManager2.default.getErrorLoadingHandler(); if (startLoadingHandler) { startLoadingHandler(targetElement); } var loader = void 0; if (stackData.preventCache === true) { loader = cornerstone.loadImage(stackData.imageIds[newImageIdIndex]); } else { loader = cornerstone.loadAndCacheImage(stackData.imageIds[newImageIdIndex]); } loader.then(function (image) { var viewport = cornerstone.getViewport(targetElement); stackData.currentImageIdIndex = newImageIdIndex; cornerstone.displayImage(targetElement, image, viewport); if (endLoadingHandler) { endLoadingHandler(targetElement, image); } }, function (error) { var imageId = stackData.imageIds[newImageIdIndex]; if (errorLoadingHandler) { errorLoadingHandler(targetElement, imageId, error); } }); } }); } function mouseUpCallback(e) { var eventData = e.detail; var element = eventData.element; element.removeEventListener(_events2.default.MOUSE_DRAG, mouseDragCallback); element.removeEventListener(_events2.default.MOUSE_UP, mouseUpCallback); } function mouseDownCallback(e) { var eventData = e.detail; var element = eventData.element; var options = (0, _toolOptions.getToolOptions)(toolType, element); if ((0, _isMouseButtonEnabled2.default)(eventData.which, options.mouseButtonMask)) { element.addEventListener(_events2.default.MOUSE_DRAG, mouseDragCallback); element.addEventListener(_events2.default.MOUSE_UP, mouseUpCallback); chooseLocation(e); e.preventDefault(); e.stopPropagation(); } } function mouseDragCallback(e) { chooseLocation(e); e.preventDefault(); e.stopPropagation(); } function enable(element, mouseButtonMask, synchronizationContext) { (0, _toolOptions.setToolOptions)(toolType, element, { mouseButtonMask: mouseButtonMask }); // Clear any currently existing toolData (0, _toolState.clearToolState)(element, toolType); (0, _toolState.addToolState)(element, toolType, { synchronizationContext: synchronizationContext }); element.removeEventListener(_events2.default.MOUSE_DOWN, mouseDownCallback); element.addEventListener(_events2.default.MOUSE_DOWN, mouseDownCallback); } // Disables the reference line tool for the given element function disable(element) { element.removeEventListener(_events2.default.MOUSE_DOWN, mouseDownCallback); } // Module/private exports var crosshairs = { activate: enable, deactivate: disable, enable: enable, disable: disable }; function dragEndCallback(e) { var eventData = e.detail; var element = eventData.element; element.removeEventListener(_events2.default.TOUCH_DRAG, dragCallback); element.removeEventListener(_events2.default.TOUCH_DRAG_END, dragEndCallback); } function dragStartCallback(e) { var eventData = e.detail; var element = eventData.element; element.addEventListener(_events2.default.TOUCH_DRAG, dragCallback); element.addEventListener(_events2.default.TOUCH_DRAG_END, dragEndCallback); chooseLocation(e); return false; } function dragCallback(e) { chooseLocation(e); e.preventDefault(); e.stopPropagation(); } function enableTouch(element, synchronizationContext) { // Clear any currently existing toolData (0, _toolState.clearToolState)(element, toolType); (0, _toolState.addToolState)(element, toolType, { synchronizationContext: synchronizationContext }); element.removeEventListener(_events2.default.TOUCH_START, dragStartCallback); element.addEventListener(_events2.default.TOUCH_START, dragStartCallback); } // Disables the reference line tool for the given element function disableTouch(element) { element.removeEventListener(_events2.default.TOUCH_START, dragStartCallback); } var crosshairsTouch = { activate: enableTouch, deactivate: disableTouch, enable: enableTouch, disable: disableTouch }; exports.crosshairs = crosshairs; exports.crosshairsTouch = crosshairsTouch; /***/ }), /***/ "./imageTools/displayTool.js": /*!***********************************!*\ !*** ./imageTools/displayTool.js ***! \***********************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = function (onImageRendered) { var configuration = {}; return { disable: function disable(element) { element.removeEventListener(_events2.default.IMAGE_RENDERED, onImageRendered); }, enable: function enable(element) { element.removeEventListener(_events2.default.IMAGE_RENDERED, onImageRendered); element.addEventListener(_events2.default.IMAGE_RENDERED, onImageRendered); _externalModules2.default.cornerstone.updateImage(element); }, getConfiguration: function getConfiguration() { return configuration; }, setConfiguration: function setConfiguration(config) { configuration = config; } }; }; var _events = __webpack_require__(/*! ../events.js */ "./events.js"); var _events2 = _interopRequireDefault(_events); var _externalModules = __webpack_require__(/*! ../externalModules.js */ "./externalModules.js"); var _externalModules2 = _interopRequireDefault(_externalModules); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), /***/ "./imageTools/doubleTapTool.js": /*!*************************************!*\ !*** ./imageTools/doubleTapTool.js ***! \*************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = function (doubleTapCallback) { return { activate: function activate(element) { element.removeEventListener(_events2.default.DOUBLE_TAP, doubleTapCallback); element.addEventListener(_events2.default.DOUBLE_TAP, doubleTapCallback); }, disable: function disable(element) { element.removeEventListener(_events2.default.DOUBLE_TAP, doubleTapCallback); }, enable: function enable(element) { element.removeEventListener(_events2.default.DOUBLE_TAP, doubleTapCallback); }, deactivate: function deactivate(element) { element.removeEventListener(_events2.default.DOUBLE_TAP, doubleTapCallback); } }; }; var _events = __webpack_require__(/*! ../events.js */ "./events.js"); var _events2 = _interopRequireDefault(_events); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /***/ }), /***/ "./imageTools/doubleTapZoom.js": /*!*************************************!*\ !*** ./imageTools/doubleTapZoom.js ***! \*************************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _externalModules = __webpack_require__(/*! ../externalModules.js */ "./externalModules.js"); var _externalModules2 = _interopRequireDefault(_externalModules); var _doubleTapTool = __webpack_require__(/*! ./doubleTapTool.js */ "./imageTools/doubleTapTool.js"); var _doubleTapTool2 = _interopRequireDefault(_doubleTapTool); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function fitToWindowStrategy(eventData) { _externalModules2.default.cornerstone.fitToWindow(eventData.element); } function doubleTapCallback(e) { var eventData = e.detail; doubleTapZoom.strategy(eventData); e.preventDefault(); e.stopPropagation(); } var doubleTapZoom = (0, _doubleTapTool2.default)(doubleTapCallback); doubleTapZoom.strategies = { default: fitToWindowStrategy }; doubleTapZoom.strategy = fitToWindowStrategy; exports.default = doubleTapZoom; /***/ }), /***/ "./imageTools/dragProbe.js": /*!*********************************!*\ !*** ./imageTools/dragProbe.js ***! \*********************************/ /*! no static exports found */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dragProbeTouch = exports.dragProbe = undefined; var _events = __webpack_require__(/*! ../events.js */ "./events.js"); var _events2 = _interopRequireDefault(_events); var _externalModules = __webpack_require__(/*! ../externalModules.js */ "./externalModules.js"); var _externalModules2 = _interopRequireDefault(_externalModules); var _simpleMouseButtonTool = __webpack_require__(/*! ./simpleMouseButtonTool.js */ "./imageTools/simpleMouseButtonTool.js"); var _simpleMouseButtonTool2 = _interopRequireDefault(_simpleMouseButtonTool); var _touchDragTool = __webpack_require__(/*! ./touchDragTool.js */ "./imageTools/touchDragTool.js"); var _touchDragTool2 = _interopRequireDefault(_touchDragTool); var _textStyle = __webpack_require__(/*! ../stateManagement/textStyle.js */ "./stateManagement/textStyle.js"); var _textStyle2 = _interopRequireDefault(_textStyle); var _toolColors = __webpack_require__(/*! ../stateManagement/toolColors.js */ "./stateManagement/toolColors.js"); var _toolColors2 = _interopRequireDefault(_toolColors); var _drawTextBox = __webpack_require__(/*! ../util/drawTextBox.js */ "./util/drawTextBox.js"); var _drawTextBox2 = _interopRequireDefault(_drawTextBox); var _getRGBPixels = __webpack_require__(/*! ../util/getRGBPixels.js */ "./util/getRGBPixels.js"); var _getRGBPixels2 = _interopRequireDefault(_getRGBPixels); var _calculateSUV = __webpack_require__(/*! ../util/calculateSUV.js */ "./util/calculateSUV.js"); var _calculateSUV2 = _interopRequireDefault(_calculateSUV); var _isMouseButtonEnabled = __webpack_require__(/*! ../util/isMouseButtonEnabled.js */ "./util/isMouseButtonEnabled.js"); var _isMouseButtonEnabled2 = _interopRequireDefault(_isMouseButtonEnabled); var _toolOptions = __webpack_require__(/*! ../toolOptions.js */ "./toolOptions.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var toolType = 'dragProbe'; var dragEventData = void 0; function defaultStrategy(eventData) { var cornerstone = _externalModules2.default.cornerstone; var enabledElement = cornerstone.getEnabledElement(eventData.element); var context = enabledElement.canvas.getContext('2d'); context.setTransform(1, 0, 0, 1, 0, 0); var color = _toolColors2.default.getActiveColor(); var font = _textStyle2.default.getFont(); var fontHeight = _textStyle2.default.getFontSize(); var config = dragProbe.getConfiguration(); context.save(); if (config && config.shadow) { context.shadowColor = config.shadowColor || '#000000'; context.shadowOffsetX = config.shadowOffsetX || 1; context.shadowOffsetY = config.shadowOffsetY || 1; } var x = Math.round(eventData.currentPoints.image.x); var y = Math.round(eventData.currentPoints.image.y); var storedPixels = void 0; var text = void 0, str = void 0; if (x < 0 || y < 0 || x >= eventData.image.columns || y >= eventData.image.rows) { return; } if (eventData.image.color) { storedPixels = (0, _getRGBPixels2.default)(eventData.element, x, y, 1, 1); text = x + ', ' + y; str = 'R: ' + storedPixels[0] + ' G: ' + storedPixels[1] + ' B: ' + storedPixels[2] + ' A: ' + storedPixels[3]; } else { storedPixels = cornerstone.getStoredPixels(eventData.element, x, y, 1, 1); var sp = storedPixels[0]; var mo = sp * eventData.image.slope + eventData.image.intercept; var suv = (0, _calculateSUV2.default)(eventData.image, sp); // Draw text text = x + ', ' + y; str = 'SP: ' + sp + ' MO: ' + parseFloat(mo.toFixed(3)); if (suv) { str += ' SUV: ' + parseFloat(suv.toFixed(3)); } } // Draw text var coords = { // Translate the x/y away from the cursor x: eventData.currentPoints.image.x + 3, y: eventData.currentPoints.image.y - 3 }; var textCoords = cornerstone.pixelToCanvas(eventData.element, coords); context.font = font; context.fillStyle = color; (0, _drawTextBox2.default)(context, str, textCoords.x, textCoords.y + fontHeight + 5, color); (0, _drawTextBox2.default)(context, text, textCoords.x, textCoords.y, color); context.restore(); } function minimalStrategy(eventData) { var cornerstone = _externalModules2.default.cornerstone; var element = eventData.element; var enabledElement = cornerstone.getEnabledElement(element); var image = enabledElement.image; var context = enabledElement.canvas.getContext('2d'); context.setTransform(1, 0, 0, 1, 0, 0); var color = _toolColors2.default.getActiveColor(); var font = _textStyle2.default.getFont(); var config = dragProbe.getConfiguration(); context.save(); if (config && config.shadow) { context.shadowColor = config.shadowColor || '#000000'; context.shadowOffsetX = config.shadowOffsetX || 1; context.shadowOffsetY = config.shadowOffsetY || 1; } var seriesModule = cornerstone.metaData.get('generalSeriesModule', image.imageId); var modality = void 0; if (seriesModule) { modality = seriesModule.modality; } var toolCoords = void 0; if (eventData.isTouchEvent === true) { toolCoords = cornerstone.pageToPixel(element, eventData.currentPoints.page.x, eventData.currentPoints.page.y - _textStyle2.default.getFontSize() * 4); } else { toolCoords = cornerstone.pageToPixel(element, eventData.currentPoints.page.x, eventData.currentPoints.page.y - _textStyle2.default.getFontSize() / 2); } var storedPixels = void 0; var text = ''; if (toolCoords.x < 0 || toolCoords.y < 0 || toolCoords.x >= image.columns || toolCoords.y >= image.rows) { return; } if (image.color) { storedPixels = (0, _getRGBPixels2.default)(element, toolCoords.x, toolCoords.y, 1, 1); text = 'R: ' + storedPixels[0] + ' G: ' + storedPixels[1] + ' B: ' + storedPixels[2]; } else { storedPixels = cornerstone.getStoredPixels(element, toolCoords.x, toolCoords.y, 1, 1); var sp = storedPixels[0]; var mo = sp * eventData.image.slope + eventData.image.intercept; var modalityPixelValueText = parseFloat(mo.toFixed(2)); if (modality === 'CT') { text += 'HU: ' + modalityPixelValueText; } else if (modality === 'PT') { text += moda