import * as cornerstoneTools from 'cornerstone-tools' const external = cornerstoneTools.external // Drawing const getNewContext = cornerstoneTools.import('drawing/getNewContext') const draw = cornerstoneTools.import('drawing/draw') const setShadow = cornerstoneTools.import('drawing/setShadow') const drawLine = cornerstoneTools.import('drawing/drawLine') const toolStyle = cornerstoneTools.toolStyle // const toolColors = cornerstoneTools.toolColors const color = '#fff' /** * @public * @class ScaleOverlayTool * @memberof Tools * * @classdesc Tool for displaying a scale overlay on the image. * @extends Tools.Base.BaseTool */ export default class ScaleOverlayTool extends cornerstoneTools.ScaleOverlayTool { constructor(props = {}) { const defaultProps = { name: 'ScaleOverlay', configuration: { minorTickLength: 5, majorTickLength: 10 }, mixins: ['enabledOrDisabledBinaryTool'] } super(props, defaultProps) } enabledCallback(element) { this.forceImageUpdate(element) } disabledCallback(element) { this.forceImageUpdate(element) } forceImageUpdate(element) { const enabledElement = external.cornerstone.getEnabledElement(element) if (enabledElement.image) { external.cornerstone.updateImage(element) } } renderToolData(evt) { const eventData = evt.detail const context = getNewContext(eventData.canvasContext.canvas) const { image, viewport, element } = eventData let rowPixelSpacing = image.rowPixelSpacing let colPixelSpacing = image.columnPixelSpacing const imagePlane = external.cornerstone.metaData.get( 'imagePlaneModule', image.imageId ) if (imagePlane) { rowPixelSpacing = imagePlane.rowPixelSpacing || imagePlane.rowImagePixelSpacing colPixelSpacing = imagePlane.columnPixelSpacing || imagePlane.colImagePixelSpacing } // Check whether pixel spacing is defined if (!rowPixelSpacing || !colPixelSpacing) { // logger.warn( // `unable to define rowPixelSpacing or colPixelSpacing from data on ${this.name}'s renderToolData` // ) return } const canvasSize = { width: context.canvas.width, height: context.canvas.height } // Distance between intervals is 10mm const verticalIntervalScale = (10.0 / rowPixelSpacing) * viewport.scale const horizontalIntervalScale = (10.0 / colPixelSpacing) * viewport.scale // 0.1 and 0.05 gives margin to horizontal and vertical lines // const hscaleBounds = computeScaleBounds(canvasSize, 0.25, 0.05) // const vscaleBounds = computeScaleBounds(canvasSize, 0.05, 0.15) const hscaleBounds = computeScaleBounds(canvasSize, 0.4, 0.04) const vscaleBounds = computeScaleBounds(canvasSize, 0.04, 0.4) if ( !canvasSize.width || !canvasSize.height || !hscaleBounds || !vscaleBounds ) { return } // const color = toolColors.getToolColor() const lineWidth = toolStyle.getToolWidth() const imageAttributes = Object.assign( {}, { hscaleBounds, vscaleBounds, verticalMinorTick: verticalIntervalScale, horizontalMinorTick: horizontalIntervalScale, verticalLine: { start: { x: vscaleBounds.bottomRight.x, y: vscaleBounds.topLeft.y }, end: { x: vscaleBounds.bottomRight.x, y: vscaleBounds.bottomRight.y } }, horizontalLine: { start: { x: hscaleBounds.topLeft.x, y: hscaleBounds.bottomRight.y }, end: { x: hscaleBounds.bottomRight.x, y: hscaleBounds.bottomRight.y } }, color, lineWidth }, this.configuration ) draw(context, context => { setShadow(context, imageAttributes) // Draw vertical line drawLine( context, element, imageAttributes.verticalLine.start, imageAttributes.verticalLine.end, { color: imageAttributes.color, lineWidth: imageAttributes.lineWidth }, 'canvas' ) drawVerticalScalebarIntervals(context, element, imageAttributes) // Draw horizontal line drawLine( context, element, imageAttributes.horizontalLine.start, imageAttributes.horizontalLine.end, { color: imageAttributes.color, lineWidth: imageAttributes.lineWidth }, 'canvas' ) drawHorizontalScalebarIntervals(context, element, imageAttributes) }) } } /** * Computes the max bound for scales on the image * @param {{width: number, height: number}} canvasSize * @param {number} horizontalReduction * @param {number} verticalReduction * @returns {Object.} */ const computeScaleBounds = ( canvasSize, horizontalReduction, verticalReduction ) => { const hReduction = horizontalReduction * Math.min(1000, canvasSize.width) const vReduction = verticalReduction * Math.min(1000, canvasSize.height) const canvasBounds = { left: hReduction, top: vReduction, width: canvasSize.width - 2 * hReduction, height: canvasSize.height - 2 * vReduction } return { topLeft: { x: canvasBounds.left, y: canvasBounds.top }, bottomRight: { x: canvasBounds.left + canvasBounds.width, y: canvasBounds.top + canvasBounds.height } } } /** * @param {CanvasRenderingContext2D} context * @param {HTMLElement} element * @param {Object} imageAttributes * @returns {void} */ const drawVerticalScalebarIntervals = (context, element, imageAttributes) => { let i = 0 while ( imageAttributes.verticalLine.start.y + i * imageAttributes.verticalMinorTick <= imageAttributes.vscaleBounds.bottomRight.y ) { const { color, lineWidth } = imageAttributes const startPoint = { x: imageAttributes.verticalLine.start.x, y: imageAttributes.verticalLine.start.y + i * imageAttributes.verticalMinorTick } const endPoint = { x: 0, y: imageAttributes.verticalLine.start.y + i * imageAttributes.verticalMinorTick } if (i % 5 === 0) { endPoint.x = imageAttributes.verticalLine.start.x - imageAttributes.majorTickLength } else { endPoint.x = imageAttributes.verticalLine.start.x - imageAttributes.minorTickLength } drawLine( context, element, startPoint, endPoint, { color, lineWidth }, 'canvas' ) i++ } } /** * @param {CanvasRenderingContext2D} context * @param {HTMLElement} element * @param {Object} imageAttributes * @returns {void} */ const drawHorizontalScalebarIntervals = (context, element, imageAttributes) => { let i = 0 while ( imageAttributes.horizontalLine.start.x + i * imageAttributes.horizontalMinorTick <= imageAttributes.hscaleBounds.bottomRight.x ) { const { color, lineWidth } = imageAttributes const startPoint = { x: imageAttributes.horizontalLine.start.x + i * imageAttributes.horizontalMinorTick, y: imageAttributes.horizontalLine.start.y } const endPoint = { x: imageAttributes.horizontalLine.start.x + i * imageAttributes.horizontalMinorTick, y: 0 } if (i % 5 === 0) { endPoint.y = imageAttributes.horizontalLine.start.y - imageAttributes.majorTickLength } else { endPoint.y = imageAttributes.horizontalLine.start.y - imageAttributes.minorTickLength } drawLine( context, element, startPoint, endPoint, { color, lineWidth }, 'canvas' ) i++ } }