Make imageSlider range input use reactive variables instead of updating it manually. Add min/max zoom levels, remove unnecessary precision for Zoom
This commit is contained in:
parent
5763abf29b
commit
87cc2a5bc0
@ -1,7 +1,11 @@
|
|||||||
<template name="imageControls">
|
<template name="imageControls">
|
||||||
<div class="imageControls">
|
<div class="imageControls">
|
||||||
<div id="scrollbar">
|
<div id="scrollbar">
|
||||||
<input id="imageSlider" type="range" min="1" val="1"/>
|
<input id="imageSlider"
|
||||||
|
type="range"
|
||||||
|
min="1"
|
||||||
|
value="{{imageIndex}}"
|
||||||
|
max="{{numImages}}"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -1,6 +1,20 @@
|
|||||||
const slideTimeoutTime = 40;
|
const slideTimeoutTime = 40;
|
||||||
let slideTimeout;
|
let slideTimeout;
|
||||||
|
|
||||||
|
Template.imageControls.onRendered(() => {
|
||||||
|
const instance = Template.instance();
|
||||||
|
|
||||||
|
Meteor.defer(() => {
|
||||||
|
// Set the current imageSlider width to its parent's height
|
||||||
|
// (because webkit is stupid and can't style vertical sliders)
|
||||||
|
const $slider = instance.$('#imageSlider');
|
||||||
|
const $element = $slider.parents().eq(2).siblings('.imageViewerViewport');
|
||||||
|
const viewportHeight = $element.height();
|
||||||
|
|
||||||
|
$slider.width(viewportHeight - 20);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
Template.imageControls.events({
|
Template.imageControls.events({
|
||||||
'input #imageSlider, change #imageSlider': function(e) {
|
'input #imageSlider, change #imageSlider': function(e) {
|
||||||
// Note that we throttle requests to prevent the
|
// Note that we throttle requests to prevent the
|
||||||
|
|||||||
@ -17,6 +17,7 @@ $imageSliderCursor = grab
|
|||||||
padding: 5px
|
padding: 5px
|
||||||
|
|
||||||
#scrollbar
|
#scrollbar
|
||||||
|
height: calc(100% - 20px);
|
||||||
margin-top: 5px
|
margin-top: 5px
|
||||||
width: 31px
|
width: 31px
|
||||||
|
|
||||||
|
|||||||
@ -86,32 +86,6 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
imageIds: imageIds
|
imageIds: imageIds
|
||||||
};
|
};
|
||||||
|
|
||||||
// Show or hide the image scrollbar depending
|
|
||||||
// on the number of images in the stack
|
|
||||||
var currentOverlay = $(element).siblings('.imageViewerViewportOverlay');
|
|
||||||
var imageControls = currentOverlay.find('.imageControls');
|
|
||||||
currentOverlay.find('.imageControls').height($(element).height());
|
|
||||||
|
|
||||||
if (stack.imageIds.length === 1) {
|
|
||||||
imageControls.hide();
|
|
||||||
currentOverlay.find('.topright, .bottomright').css('right', '3px');
|
|
||||||
} else {
|
|
||||||
imageControls.show();
|
|
||||||
currentOverlay.find('.topright, .bottomright').css('right', '39px');
|
|
||||||
|
|
||||||
// Update the maximum value of the slider
|
|
||||||
var currentImageSlider = currentOverlay.find('#imageSlider');
|
|
||||||
currentImageSlider.attr('max', stack.imageIds.length);
|
|
||||||
currentImageSlider.val(1);
|
|
||||||
|
|
||||||
// Set it's width to its parent's height
|
|
||||||
// (because webkit is stupid and can't style vertical sliders)
|
|
||||||
var scrollbar = currentOverlay.find('#scrollbar');
|
|
||||||
scrollbar.height(scrollbar.parent().height() - 20);
|
|
||||||
var overlayHeight = currentImageSlider.parent().height();
|
|
||||||
currentImageSlider.width(overlayHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the current image ID for the stack that will be rendered
|
// Get the current image ID for the stack that will be rendered
|
||||||
imageId = imageIds[stack.currentImageIdIndex];
|
imageId = imageIds[stack.currentImageIdIndex];
|
||||||
|
|
||||||
@ -296,11 +270,6 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
|
|
||||||
var stack = toolData.data[0];
|
var stack = toolData.data[0];
|
||||||
|
|
||||||
// Update the imageSlider value
|
|
||||||
var currentOverlay = $(element).siblings('.imageViewerViewportOverlay');
|
|
||||||
var currentImageSlider = currentOverlay.find('#imageSlider');
|
|
||||||
currentImageSlider.val(stack.currentImageIdIndex + 1);
|
|
||||||
|
|
||||||
// If this viewport is displaying a stack of images, save the current image
|
// If this viewport is displaying a stack of images, save the current image
|
||||||
// index in the stack to the global ViewerData object, as well as the Meteor Session.
|
// index in the stack to the global ViewerData object, as well as the Meteor Session.
|
||||||
var stack = cornerstoneTools.getToolState(element, 'stack');
|
var stack = cornerstoneTools.getToolState(element, 'stack');
|
||||||
@ -319,27 +288,6 @@ function loadDisplaySetIntoViewport(data, templateData) {
|
|||||||
// Set a random value for the Session variable in order to trigger an overlay update
|
// Set a random value for the Session variable in order to trigger an overlay update
|
||||||
Session.set('CornerstoneNewImage' + viewportIndex, Random.id());
|
Session.set('CornerstoneNewImage' + viewportIndex, Random.id());
|
||||||
|
|
||||||
function OnStackScroll(e, eventData) {
|
|
||||||
// Get the element and stack data
|
|
||||||
var element = e.target;
|
|
||||||
var toolData = cornerstoneTools.getToolState(element, 'stack');
|
|
||||||
if (!toolData || !toolData.data || !toolData.data.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var stack = toolData.data[0];
|
|
||||||
|
|
||||||
// Update the imageSlider value
|
|
||||||
var currentOverlay = $(element).siblings('.imageViewerViewportOverlay');
|
|
||||||
var currentImageSlider = currentOverlay.find('#imageSlider');
|
|
||||||
currentImageSlider.val(stack.currentImageIdIndex + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
$(element).off('CornerstoneStackScroll', OnStackScroll);
|
|
||||||
if (stack.imageIds.length > 1) {
|
|
||||||
$(element).on('CornerstoneStackScroll', OnStackScroll);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define a function to trigger an event whenever a new viewport is being used
|
// Define a function to trigger an event whenever a new viewport is being used
|
||||||
// This is used to update the value of the "active viewport", when the user interacts
|
// This is used to update the value of the "active viewport", when the user interacts
|
||||||
// with a new viewport element
|
// with a new viewport element
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template name="viewportOverlay">
|
<template name="viewportOverlay">
|
||||||
<div class="imageViewerViewportOverlay noselect">
|
<div class="imageViewerViewportOverlay noselect {{#if gt numImages 1}}controlsVisible{{/if}}">
|
||||||
{{ #unless tagDisplaySpecified }}
|
{{ #unless tagDisplaySpecified }}
|
||||||
<div class="topleft dicomTag">
|
<div class="topleft dicomTag">
|
||||||
<div>{{formatPN patientName}}</div>
|
<div>{{formatPN patientName}}</div>
|
||||||
@ -11,13 +11,13 @@
|
|||||||
<div>{{formatDA studyDate}} {{formatTM studyTime}}</div>
|
<div>{{formatDA studyDate}} {{formatTM studyTime}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bottomright dicomTag">
|
<div class="bottomright dicomTag">
|
||||||
<div>{{#if zoom}}Zoom: {{formatNumberPrecision zoom 2}}%{{/if}}</div>
|
<div>{{#if zoom}}Zoom: {{formatNumberPrecision zoom 0}}%{{/if}}</div>
|
||||||
<div>{{compression}}</div>
|
<div>{{compression}}</div>
|
||||||
<div>{{wwwc}}</div>
|
<div>{{wwwc}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bottomleft dicomTag">
|
<div class="bottomleft dicomTag">
|
||||||
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
||||||
<div>{{#if numImages}}Img: {{imageNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
<div>{{#if gt numImages 1}}Img: {{imageNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
||||||
<div>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
<div>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
||||||
<div>{{imageDimensions}}</div>
|
<div>{{imageDimensions}}</div>
|
||||||
<div>{{seriesDescription}}</div>
|
<div>{{seriesDescription}}</div>
|
||||||
@ -34,11 +34,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="bottomright dicomTag">
|
<div class="bottomright dicomTag">
|
||||||
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
||||||
<div>{{#if numImages}}Img: {{imageNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
<div>{{#if gt numImages 1}}Img: {{imageNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
||||||
<div>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
<div>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
||||||
<div>{{imageDimensions}}</div>
|
<div>{{imageDimensions}}</div>
|
||||||
<div>{{seriesDescription}}</div>
|
<div>{{seriesDescription}}</div>
|
||||||
<div>{{#if zoom}}Zoom: {{formatNumberPrecision zoom 2}}%{{/if}}</div>
|
<div>{{#if zoom}}Zoom: {{formatNumberPrecision zoom 0}}%{{/if}}</div>
|
||||||
<div>{{compression}}</div>
|
<div>{{compression}}</div>
|
||||||
<div>{{wwwc}}</div>
|
<div>{{wwwc}}</div>
|
||||||
</div>
|
</div>
|
||||||
@ -54,15 +54,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="bottomleft dicomTag">
|
<div class="bottomleft dicomTag">
|
||||||
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
<div>{{#if seriesNumber}}Ser: {{seriesNumber}}{{/if}}</div>
|
||||||
<div>{{#if numImages}}Img: {{imageNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
<div>{{#if gt numImages 1}}Img: {{imageNumber}} ({{imageIndex}}/{{numImages}}){{/if}}</div>
|
||||||
<div>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
<div>{{#if frameRate}}{{frameRate}} FPS{{/if}}</div>
|
||||||
<div>{{imageDimensions}}</div>
|
<div>{{imageDimensions}}</div>
|
||||||
<div>{{seriesDescription}}</div>
|
<div>{{seriesDescription}}</div>
|
||||||
<div>{{#if zoom}}Zoom: {{formatNumberPrecision zoom 2}}%{{/if}}</div>
|
<div>{{#if zoom}}Zoom: {{formatNumberPrecision zoom 0}}%{{/if}}</div>
|
||||||
<div>{{compression}}</div>
|
<div>{{compression}}</div>
|
||||||
<div>{{wwwc}}</div>
|
<div>{{wwwc}}</div>
|
||||||
</div>
|
</div>
|
||||||
{{ /if }}
|
{{ /if }}
|
||||||
{{>imageControls}}
|
|
||||||
|
{{#if gt numImages 1}}
|
||||||
|
{{> imageControls imageIndex=imageIndex numImages=numImages}}
|
||||||
|
{{ /if }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -219,9 +219,6 @@ Template.viewportOverlay.helpers({
|
|||||||
imageIndex: function() {
|
imageIndex: function() {
|
||||||
return getInstance.call(this, 'index');
|
return getInstance.call(this, 'index');
|
||||||
},
|
},
|
||||||
numImages: function() {
|
|
||||||
return getSeries.call(this, 'numImages');
|
|
||||||
},
|
|
||||||
imageIndex: function() {
|
imageIndex: function() {
|
||||||
Session.get('CornerstoneNewImage' + this.viewportIndex);
|
Session.get('CornerstoneNewImage' + this.viewportIndex);
|
||||||
var stack = getStackDataIfNotEmpty(this.viewportIndex);
|
var stack = getStackDataIfNotEmpty(this.viewportIndex);
|
||||||
|
|||||||
@ -30,4 +30,8 @@ $viewportTagPadding = 20px
|
|||||||
|
|
||||||
.priorIndicator
|
.priorIndicator
|
||||||
font-weight: bold
|
font-weight: bold
|
||||||
color: yellow
|
color: yellow
|
||||||
|
|
||||||
|
&.controlsVisible
|
||||||
|
.topright, .bottomright
|
||||||
|
right: "calc(%s + 19px)" % $viewportTagPadding
|
||||||
@ -37,13 +37,19 @@ function configureTools() {
|
|||||||
cornerstoneTools.toolColors.setActiveColor('#00ffff'); //rgb(0, 255, 0)'
|
cornerstoneTools.toolColors.setActiveColor('#00ffff'); //rgb(0, 255, 0)'
|
||||||
|
|
||||||
// Set the configuration values for the text annotation (Arrow) tool
|
// Set the configuration values for the text annotation (Arrow) tool
|
||||||
var annotateConfig = {
|
const annotateConfig = {
|
||||||
getTextCallback: getAnnotationTextCallback,
|
getTextCallback: getAnnotationTextCallback,
|
||||||
changeTextCallback: changeAnnotationTextCallback,
|
changeTextCallback: changeAnnotationTextCallback,
|
||||||
drawHandles: false,
|
drawHandles: false,
|
||||||
arrowFirst: true
|
arrowFirst: true
|
||||||
};
|
};
|
||||||
cornerstoneTools.arrowAnnotate.setConfiguration(annotateConfig);
|
cornerstoneTools.arrowAnnotate.setConfiguration(annotateConfig);
|
||||||
|
|
||||||
|
const zoomConfig = {
|
||||||
|
minScale: 0.05,
|
||||||
|
maxScale: 10
|
||||||
|
};
|
||||||
|
cornerstoneTools.zoom.setConfiguration(zoomConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
toolManager = {
|
toolManager = {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user