larvitar 2.0.14 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/imaging/imageStore.d.ts +2 -2
- package/dist/imaging/tools/custom/customMouseWheelScrollTool.d.ts +30 -0
- package/dist/larvitar.js +338 -90
- package/dist/larvitar.js.map +1 -1
- package/imaging/tools/types.d.ts +1 -0
- package/imaging/types.d.ts +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
## Dicom Image Toolkit for CornerstoneJS
|
|
10
10
|
|
|
11
|
-
### Current version: 2.0
|
|
12
|
-
|
|
11
|
+
### Current version: 2.1.0
|
|
12
|
+
|
|
13
|
+
### Latest Published Release: 2.1.0
|
|
13
14
|
|
|
14
15
|
This library provides common DICOM functionalities to be used in web-applications: it's wrapper that simplifies the use of cornerstone-js environment.
|
|
15
16
|
|
|
@@ -25,10 +25,10 @@ type SetPayload = ["errorLog" | "leftActiveTool" | "rightActiveTool", string] |
|
|
|
25
25
|
string,
|
|
26
26
|
boolean
|
|
27
27
|
] | [
|
|
28
|
-
("progress" | "loading" | "minPixelValue" | "maxPixelValue" | "minSliceId" | "maxSliceId" | "minTimeId" | "maxTimeId" | "rotation" | "scale" | "sliceId" | "timeId" | "thickness"),
|
|
28
|
+
("progress" | "loading" | "minPixelValue" | "maxPixelValue" | "minSliceId" | "maxSliceId" | "minTimeId" | "maxTimeId" | "rotation" | "scale" | "sliceId" | "timeId" | "thickness" | "numberOfFrames" | "numberOfTemporalPositions"),
|
|
29
29
|
string,
|
|
30
30
|
number
|
|
31
|
-
] | ["timestamp", string, number | undefined] | ["pendingSliceId", string, number | undefined] | ["timestamps" | "timeIds", string, number[]] | [
|
|
31
|
+
] | ["timestamp", string, number | undefined] | ["seriesUID", string, string | undefined] | ["pendingSliceId", string, number | undefined] | ["timestamps" | "timeIds", string, number[]] | [
|
|
32
32
|
"contrast" | "dimensions" | "spacing" | "translation",
|
|
33
33
|
string,
|
|
34
34
|
number,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** @module tools/custom/customMouseWheelScrollTool
|
|
2
|
+
* @desc This file provides functionalities for
|
|
3
|
+
* custom DICOM Loader
|
|
4
|
+
*/
|
|
5
|
+
import { Image } from "cornerstone-core";
|
|
6
|
+
declare const BaseTool: any;
|
|
7
|
+
type StackData = {
|
|
8
|
+
currentImageIdIndex: number;
|
|
9
|
+
imageIds: string[];
|
|
10
|
+
pending: any[];
|
|
11
|
+
};
|
|
12
|
+
type ToolEventDetail = {
|
|
13
|
+
element: HTMLElement;
|
|
14
|
+
image: Image;
|
|
15
|
+
direction: number;
|
|
16
|
+
};
|
|
17
|
+
export default class CustomMouseWheelScrollTool extends BaseTool {
|
|
18
|
+
currentMode: string;
|
|
19
|
+
framesNumber: number;
|
|
20
|
+
slicesnumber: number;
|
|
21
|
+
is4D: boolean;
|
|
22
|
+
isMultiframe: boolean;
|
|
23
|
+
constructor(props?: {});
|
|
24
|
+
verify4D(): void;
|
|
25
|
+
handleToggle(newcurrentMode: string): void;
|
|
26
|
+
toggleScrollMode(element: HTMLElement): void;
|
|
27
|
+
mouseWheelCallback(evt?: CustomEvent<ToolEventDetail>): void;
|
|
28
|
+
scrollWithoutSkipping(stackData: StackData, pendingEvent: any, element: HTMLElement): void;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
package/dist/larvitar.js
CHANGED
|
@@ -1971,7 +1971,7 @@ const addDefaultTools = function (toolToActivate) {
|
|
|
1971
1971
|
});
|
|
1972
1972
|
|
|
1973
1973
|
// set wheel scroll active
|
|
1974
|
-
setToolActive("
|
|
1974
|
+
setToolActive("CustomMouseWheelScroll", {
|
|
1975
1975
|
loop: false,
|
|
1976
1976
|
// default false
|
|
1977
1977
|
allowSkipping: false,
|
|
@@ -2970,7 +2970,7 @@ class BorderMagnifyTool extends MagnifyTool {
|
|
|
2970
2970
|
* @returns {void}
|
|
2971
2971
|
*/
|
|
2972
2972
|
handleKeyDown(event) {
|
|
2973
|
-
if (event.key === '
|
|
2973
|
+
if (event.key === 'M' || event.key === 'm') {
|
|
2974
2974
|
// Toggle the visibility of borders
|
|
2975
2975
|
this.configuration.showBorders = !this.configuration.showBorders;
|
|
2976
2976
|
|
|
@@ -81303,6 +81303,7 @@ const interaction_1 = __webpack_require__(1534);
|
|
|
81303
81303
|
const imageStore_1 = __importStar(__webpack_require__(5278));
|
|
81304
81304
|
const imageColormaps_1 = __webpack_require__(4540);
|
|
81305
81305
|
const imageUtils_1 = __webpack_require__(8345);
|
|
81306
|
+
const default_1 = __webpack_require__(6694);
|
|
81306
81307
|
/*
|
|
81307
81308
|
* This module provides the following functions to be exported:
|
|
81308
81309
|
* clearImageCache(seriesId)
|
|
@@ -81722,6 +81723,7 @@ const renderImage = function (seriesStack, elementId, defaultProps) {
|
|
|
81722
81723
|
}
|
|
81723
81724
|
(0, exports.storeViewportData)(image, element.id, storedViewport, data);
|
|
81724
81725
|
(0, imageStore_1.set)(["ready", element.id, true]);
|
|
81726
|
+
(0, imageStore_1.set)(["seriesUID", element.id, data.seriesUID]);
|
|
81725
81727
|
const t1 = performance.now();
|
|
81726
81728
|
console.log(`Call to renderImage took ${t1 - t0} milliseconds.`);
|
|
81727
81729
|
const uri = cornerstone_wado_image_loader_1.default.wadouri.parseImageId(data.imageId).url;
|
|
@@ -81891,53 +81893,57 @@ const updateViewportData = function (elementId, viewportData, activeTool) {
|
|
|
81891
81893
|
console.error("invalid html element: " + elementId);
|
|
81892
81894
|
return;
|
|
81893
81895
|
}
|
|
81894
|
-
|
|
81895
|
-
|
|
81896
|
-
|
|
81897
|
-
|
|
81898
|
-
|
|
81899
|
-
(
|
|
81900
|
-
|
|
81901
|
-
|
|
81902
|
-
|
|
81903
|
-
|
|
81904
|
-
|
|
81905
|
-
|
|
81906
|
-
|
|
81907
|
-
|
|
81908
|
-
|
|
81909
|
-
(
|
|
81910
|
-
|
|
81911
|
-
|
|
81912
|
-
|
|
81913
|
-
|
|
81914
|
-
|
|
81915
|
-
|
|
81916
|
-
|
|
81917
|
-
|
|
81918
|
-
|
|
81919
|
-
|
|
81920
|
-
|
|
81921
|
-
|
|
81922
|
-
|
|
81923
|
-
|
|
81924
|
-
|
|
81925
|
-
|
|
81926
|
-
|
|
81927
|
-
|
|
81928
|
-
|
|
81929
|
-
|
|
81930
|
-
|
|
81931
|
-
|
|
81932
|
-
|
|
81933
|
-
|
|
81934
|
-
|
|
81935
|
-
|
|
81936
|
-
|
|
81937
|
-
|
|
81938
|
-
|
|
81939
|
-
|
|
81940
|
-
|
|
81896
|
+
const toolsNames = Object.keys(default_1.DEFAULT_TOOLS);
|
|
81897
|
+
const isValidTool = toolsNames.includes(activeTool);
|
|
81898
|
+
if (isValidTool === true) {
|
|
81899
|
+
switch (activeTool) {
|
|
81900
|
+
case "WwwcRegion":
|
|
81901
|
+
if (viewportData.voi) {
|
|
81902
|
+
(0, imageStore_1.set)([
|
|
81903
|
+
"contrast",
|
|
81904
|
+
elementId,
|
|
81905
|
+
viewportData.voi.windowWidth,
|
|
81906
|
+
viewportData.voi.windowCenter
|
|
81907
|
+
]);
|
|
81908
|
+
}
|
|
81909
|
+
break;
|
|
81910
|
+
case "Pan":
|
|
81911
|
+
if (viewportData.translation) {
|
|
81912
|
+
(0, imageStore_1.set)([
|
|
81913
|
+
"translation",
|
|
81914
|
+
elementId,
|
|
81915
|
+
viewportData.translation.x,
|
|
81916
|
+
viewportData.translation.y
|
|
81917
|
+
]);
|
|
81918
|
+
}
|
|
81919
|
+
break;
|
|
81920
|
+
case "Zoom":
|
|
81921
|
+
if (viewportData.scale) {
|
|
81922
|
+
(0, imageStore_1.set)(["scale", elementId, viewportData.scale]);
|
|
81923
|
+
}
|
|
81924
|
+
break;
|
|
81925
|
+
case "Rotate":
|
|
81926
|
+
if (viewportData.rotation) {
|
|
81927
|
+
(0, imageStore_1.set)(["rotation", elementId, viewportData.rotation]);
|
|
81928
|
+
}
|
|
81929
|
+
break;
|
|
81930
|
+
case "CustomMouseWheelScroll":
|
|
81931
|
+
const viewport = imageStore_1.default.get(["viewports", elementId]);
|
|
81932
|
+
const isTimeserie = viewport.isTimeserie;
|
|
81933
|
+
if (isTimeserie) {
|
|
81934
|
+
const index = viewportData.newImageIdIndex;
|
|
81935
|
+
const timeId = viewport.timeIds[index];
|
|
81936
|
+
const timestamp = viewport.timestamps[index];
|
|
81937
|
+
(0, imageStore_1.set)(["timeId", elementId, timeId]);
|
|
81938
|
+
(0, imageStore_1.set)(["timestamp", elementId, timestamp]);
|
|
81939
|
+
}
|
|
81940
|
+
break;
|
|
81941
|
+
default:
|
|
81942
|
+
break;
|
|
81943
|
+
}
|
|
81944
|
+
}
|
|
81945
|
+
else {
|
|
81946
|
+
console.warn("unknown tool: " + activeTool);
|
|
81941
81947
|
}
|
|
81942
81948
|
};
|
|
81943
81949
|
exports.updateViewportData = updateViewportData;
|
|
@@ -81970,6 +81976,11 @@ const storeViewportData = function (image, elementId, viewport, data) {
|
|
|
81970
81976
|
(0, imageStore_1.set)(["maxSliceId", elementId, data.numberOfSlices - 1]);
|
|
81971
81977
|
}
|
|
81972
81978
|
if (data.isTimeserie) {
|
|
81979
|
+
(0, imageStore_1.set)([
|
|
81980
|
+
"numberOfTemporalPositions",
|
|
81981
|
+
elementId,
|
|
81982
|
+
data.numberOfTemporalPositions
|
|
81983
|
+
]);
|
|
81973
81984
|
(0, imageStore_1.set)(["minTimeId", elementId, 0]);
|
|
81974
81985
|
(0, imageStore_1.set)(["timeId", elementId, data.timeIndex || 0]);
|
|
81975
81986
|
if (data.numberOfSlices && data.numberOfTemporalPositions) {
|
|
@@ -82016,6 +82027,9 @@ const storeViewportData = function (image, elementId, viewport, data) {
|
|
|
82016
82027
|
]);
|
|
82017
82028
|
(0, imageStore_1.set)(["isColor", elementId, data.isColor]);
|
|
82018
82029
|
(0, imageStore_1.set)(["isMultiframe", elementId, data.isMultiframe]);
|
|
82030
|
+
if (data.isMultiframe) {
|
|
82031
|
+
(0, imageStore_1.set)(["numberOfFrames", elementId, data.numberOfFrames]);
|
|
82032
|
+
}
|
|
82019
82033
|
(0, imageStore_1.set)(["isTimeserie", elementId, data.isTimeserie]);
|
|
82020
82034
|
(0, imageStore_1.set)(["isPDF", elementId, false]);
|
|
82021
82035
|
(0, imageStore_1.set)(["waveform", elementId, data.waveform]);
|
|
@@ -82142,12 +82156,14 @@ exports.rotateImageRight = rotateImageRight;
|
|
|
82142
82156
|
*/
|
|
82143
82157
|
const getSeriesData = function (series, defaultProps) {
|
|
82144
82158
|
const data = {};
|
|
82159
|
+
data.seriesUID = series.larvitarSeriesInstanceUID || series.seriesUID; //case of resliced series
|
|
82145
82160
|
if (series.isMultiframe) {
|
|
82146
82161
|
data.isMultiframe = true;
|
|
82147
82162
|
data.numberOfSlices = series.imageIds.length;
|
|
82148
82163
|
data.imageIndex = 0;
|
|
82149
82164
|
data.imageId = series.imageIds[data.imageIndex];
|
|
82150
82165
|
data.isTimeserie = false;
|
|
82166
|
+
data.numberOfFrames = series.numberOfFrames;
|
|
82151
82167
|
}
|
|
82152
82168
|
else if (series.is4D) {
|
|
82153
82169
|
data.isMultiframe = false;
|
|
@@ -82420,6 +82436,13 @@ const setValue = (store, data) => {
|
|
|
82420
82436
|
store.series[k][field] = v[0];
|
|
82421
82437
|
triggerSeriesListener(k);
|
|
82422
82438
|
break;
|
|
82439
|
+
case "seriesUID":
|
|
82440
|
+
if (!viewport) {
|
|
82441
|
+
return;
|
|
82442
|
+
}
|
|
82443
|
+
viewport[field] = v[0];
|
|
82444
|
+
triggerViewportListener(k);
|
|
82445
|
+
break;
|
|
82423
82446
|
case "isColor":
|
|
82424
82447
|
case "isMultiframe":
|
|
82425
82448
|
case "isPDF":
|
|
@@ -82443,6 +82466,8 @@ const setValue = (store, data) => {
|
|
|
82443
82466
|
case "pendingSliceId":
|
|
82444
82467
|
case "timeId":
|
|
82445
82468
|
case "timestamp":
|
|
82469
|
+
case "numberOfFrames":
|
|
82470
|
+
case "numberOfTemporalPositions":
|
|
82446
82471
|
if (!viewport) {
|
|
82447
82472
|
return;
|
|
82448
82473
|
}
|
|
@@ -85817,6 +85842,243 @@ function parseECG(seriesId, dataSet, tag, nSampling = 2) {
|
|
|
85817
85842
|
exports.parseECG = parseECG;
|
|
85818
85843
|
|
|
85819
85844
|
|
|
85845
|
+
/***/ }),
|
|
85846
|
+
|
|
85847
|
+
/***/ 4585:
|
|
85848
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
85849
|
+
|
|
85850
|
+
"use strict";
|
|
85851
|
+
|
|
85852
|
+
/** @module tools/custom/customMouseWheelScrollTool
|
|
85853
|
+
* @desc This file provides functionalities for
|
|
85854
|
+
* custom DICOM Loader
|
|
85855
|
+
*/
|
|
85856
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
85857
|
+
if (k2 === undefined) k2 = k;
|
|
85858
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
85859
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
85860
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
85861
|
+
}
|
|
85862
|
+
Object.defineProperty(o, k2, desc);
|
|
85863
|
+
}) : (function(o, m, k, k2) {
|
|
85864
|
+
if (k2 === undefined) k2 = k;
|
|
85865
|
+
o[k2] = m[k];
|
|
85866
|
+
}));
|
|
85867
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
85868
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
85869
|
+
}) : function(o, v) {
|
|
85870
|
+
o["default"] = v;
|
|
85871
|
+
});
|
|
85872
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
85873
|
+
if (mod && mod.__esModule) return mod;
|
|
85874
|
+
var result = {};
|
|
85875
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
85876
|
+
__setModuleDefault(result, mod);
|
|
85877
|
+
return result;
|
|
85878
|
+
};
|
|
85879
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
85880
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
85881
|
+
};
|
|
85882
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
85883
|
+
const cornerstone_tools_1 = __importDefault(__webpack_require__(4030));
|
|
85884
|
+
const BaseTool = cornerstone_tools_1.default.importInternal("base/BaseTool");
|
|
85885
|
+
const scrollToIndex = cornerstone_tools_1.default.importInternal("util/scrollToIndex");
|
|
85886
|
+
const getToolState = cornerstone_tools_1.default.getToolState;
|
|
85887
|
+
// internal libraries
|
|
85888
|
+
const imageStore_1 = __importStar(__webpack_require__(5278));
|
|
85889
|
+
const default_1 = __webpack_require__(6694);
|
|
85890
|
+
/*
|
|
85891
|
+
* @class CustomMouseWheelScrollTool
|
|
85892
|
+
* @extends BaseTool
|
|
85893
|
+
* @memberof Tools
|
|
85894
|
+
*
|
|
85895
|
+
* @classdesc Tool for scrolling through images using the mouse wheel
|
|
85896
|
+
* @private
|
|
85897
|
+
*/
|
|
85898
|
+
class CustomMouseWheelScrollTool extends BaseTool {
|
|
85899
|
+
/*
|
|
85900
|
+
* @constructs CustomMouseWheelScrollTool
|
|
85901
|
+
* @param {object} props - Any properties passed to the component
|
|
85902
|
+
*/
|
|
85903
|
+
constructor(props = {}) {
|
|
85904
|
+
const defaultProps = {
|
|
85905
|
+
name: "CustomMouseWheelScroll",
|
|
85906
|
+
supportedInteractionTypes: ["MouseWheel"],
|
|
85907
|
+
configuration: {
|
|
85908
|
+
loop: false,
|
|
85909
|
+
allowSkipping: true,
|
|
85910
|
+
invert: false,
|
|
85911
|
+
fixedFrame: 1,
|
|
85912
|
+
fixedSlice: 0,
|
|
85913
|
+
currentMode: "stack",
|
|
85914
|
+
framesNumber: 1
|
|
85915
|
+
}
|
|
85916
|
+
};
|
|
85917
|
+
super(props, defaultProps);
|
|
85918
|
+
this.currentMode = "stack";
|
|
85919
|
+
this.framesNumber = this.configuration.framesNumber;
|
|
85920
|
+
this.slicesnumber = 0;
|
|
85921
|
+
this.is4D = false;
|
|
85922
|
+
this.isMultiframe = false;
|
|
85923
|
+
this.animation = false;
|
|
85924
|
+
this.animationId = null;
|
|
85925
|
+
}
|
|
85926
|
+
/*
|
|
85927
|
+
* @verify4D
|
|
85928
|
+
* @desc Verify if the image is 4D or not
|
|
85929
|
+
*/
|
|
85930
|
+
verify4D() {
|
|
85931
|
+
const viewport = imageStore_1.default.get(["viewports", this.element.id]);
|
|
85932
|
+
// check is4D and multiframe
|
|
85933
|
+
this.is4D = viewport.isTimeserie;
|
|
85934
|
+
this.isMultiframe = viewport.isMultiframe;
|
|
85935
|
+
// extract frames number
|
|
85936
|
+
if (this.is4D === true) {
|
|
85937
|
+
this.configuration.framesNumber = viewport.numberOfTemporalPositions;
|
|
85938
|
+
}
|
|
85939
|
+
else if (this.isMultiframe === true) {
|
|
85940
|
+
this.configuration.framesNumber = viewport.numberOfFrames;
|
|
85941
|
+
this.currentMode = "slice";
|
|
85942
|
+
this.configuration.currentMode = "slice";
|
|
85943
|
+
}
|
|
85944
|
+
else {
|
|
85945
|
+
this.configuration.framesNumber = 1;
|
|
85946
|
+
}
|
|
85947
|
+
this.framesNumber = this.configuration.framesNumber;
|
|
85948
|
+
}
|
|
85949
|
+
handleToggle(newcurrentMode) {
|
|
85950
|
+
// Toggle mode between 'stack' and 'slice' on Tab key press or other events
|
|
85951
|
+
this.verify4D();
|
|
85952
|
+
if (this.is4D === false) {
|
|
85953
|
+
this.currentMode = this.isMultiframe ? "slice" : "stack";
|
|
85954
|
+
this.configuration.currentMode = this.isMultiframe ? "slice" : "stack";
|
|
85955
|
+
}
|
|
85956
|
+
else if (this.is4D === true) {
|
|
85957
|
+
if (this.currentMode != newcurrentMode) {
|
|
85958
|
+
this.toggleScrollMode(this.element);
|
|
85959
|
+
}
|
|
85960
|
+
}
|
|
85961
|
+
}
|
|
85962
|
+
/*
|
|
85963
|
+
* @method toggleScrollMode
|
|
85964
|
+
* @param {element} HTMLElement
|
|
85965
|
+
* @desc Handle the toggle between 'stack' and 'slice' modes
|
|
85966
|
+
* we enter in this function only if this.is4d===true so this.framesNumber!=0
|
|
85967
|
+
*/
|
|
85968
|
+
toggleScrollMode(element) {
|
|
85969
|
+
if (!element) {
|
|
85970
|
+
console.error("Element is undefined");
|
|
85971
|
+
return;
|
|
85972
|
+
}
|
|
85973
|
+
const toolData = getToolState(element, "stack");
|
|
85974
|
+
if (!toolData || !toolData.data || !toolData.data.length) {
|
|
85975
|
+
console.error("No Tool Data");
|
|
85976
|
+
return;
|
|
85977
|
+
}
|
|
85978
|
+
const stackData = toolData.data[0];
|
|
85979
|
+
const currentIndex = stackData.currentImageIdIndex;
|
|
85980
|
+
switch (this.currentMode) {
|
|
85981
|
+
case "stack":
|
|
85982
|
+
// Switching from 'stack' to 'slice'
|
|
85983
|
+
this.configuration.fixedSlice = Math.floor((currentIndex + 1) / this.framesNumber); // slice = 0,1,2,3 and so on
|
|
85984
|
+
this.configuration.currentMode = "slice";
|
|
85985
|
+
this.currentMode = "slice";
|
|
85986
|
+
break;
|
|
85987
|
+
case "slice":
|
|
85988
|
+
// Switching from 'slice' to 'stack'
|
|
85989
|
+
this.configuration.fixedFrame =
|
|
85990
|
+
currentIndex + 1 - this.configuration.fixedSlice * this.framesNumber; // frame is related to the current slice
|
|
85991
|
+
this.configuration.currentMode = "stack";
|
|
85992
|
+
this.currentMode = "stack";
|
|
85993
|
+
break;
|
|
85994
|
+
default:
|
|
85995
|
+
break;
|
|
85996
|
+
}
|
|
85997
|
+
}
|
|
85998
|
+
mouseWheelCallback(evt) {
|
|
85999
|
+
const { direction: invert, element } = evt.detail;
|
|
86000
|
+
this.handleToggle(default_1.DEFAULT_TOOLS["CustomMouseWheelScroll"].currentMode);
|
|
86001
|
+
// configure scroll direction
|
|
86002
|
+
const direction = invert *
|
|
86003
|
+
(this.configuration.currentMode === "stack"
|
|
86004
|
+
? this.configuration.framesNumber
|
|
86005
|
+
: 1);
|
|
86006
|
+
const toolData = getToolState(element, "stack");
|
|
86007
|
+
if (!toolData || !toolData.data || !toolData.data.length) {
|
|
86008
|
+
return;
|
|
86009
|
+
}
|
|
86010
|
+
const stackData = toolData.data[0];
|
|
86011
|
+
if (this.configuration.currentMode === "stack") {
|
|
86012
|
+
// Handle 'stack' mode
|
|
86013
|
+
// Calculate validIndex for 'stack' mode (no looping) between 0 and (N-1)*framesnumber where N=numberofslices=numberofimageids/numberofframes
|
|
86014
|
+
let lastIndex = imageStore_1.default.get(["viewports", element.id, "sliceId"]);
|
|
86015
|
+
let nextIndex = lastIndex + direction;
|
|
86016
|
+
if (lastIndex === -1) {
|
|
86017
|
+
nextIndex = 0 + direction;
|
|
86018
|
+
lastIndex = 0;
|
|
86019
|
+
}
|
|
86020
|
+
this.slicesnumber =
|
|
86021
|
+
Math.ceil(stackData.imageIds.length / this.framesNumber) - 1;
|
|
86022
|
+
// Ensure nextIndex is between 0 and upperBound
|
|
86023
|
+
const validIndex = nextIndex >= 0 &&
|
|
86024
|
+
nextIndex < stackData.imageIds.length - 1 &&
|
|
86025
|
+
this.slicesnumber > 0
|
|
86026
|
+
? nextIndex
|
|
86027
|
+
: lastIndex;
|
|
86028
|
+
// Scroll to the calculated index
|
|
86029
|
+
scrollToIndex(element, validIndex);
|
|
86030
|
+
}
|
|
86031
|
+
else {
|
|
86032
|
+
// Handle 'slice' mode
|
|
86033
|
+
let lastIndex = this.isMultiframe === true || this.is4D === true
|
|
86034
|
+
? imageStore_1.default.get(["viewports", element.id, "sliceId"])
|
|
86035
|
+
: stackData.currentImageIdIndex;
|
|
86036
|
+
this.slicesnumber =
|
|
86037
|
+
Math.ceil(stackData.imageIds.length / this.framesNumber) - 1;
|
|
86038
|
+
const startFrame = this.configuration.fixedSlice * this.configuration.framesNumber;
|
|
86039
|
+
const endFrame = (this.configuration.fixedSlice + 1) * this.configuration.framesNumber -
|
|
86040
|
+
1;
|
|
86041
|
+
// Calculate the potential new index without considering looping
|
|
86042
|
+
let nextIndex = lastIndex + direction;
|
|
86043
|
+
// Check if the new index is within the valid range for the current slice
|
|
86044
|
+
if (nextIndex < startFrame ||
|
|
86045
|
+
nextIndex > endFrame ||
|
|
86046
|
+
nextIndex >= stackData.imageIds.length) {
|
|
86047
|
+
nextIndex = startFrame;
|
|
86048
|
+
}
|
|
86049
|
+
// Scroll to the calculated index
|
|
86050
|
+
scrollToIndex(element, nextIndex);
|
|
86051
|
+
if (this.is4D) {
|
|
86052
|
+
const viewport = imageStore_1.default.get(["viewports", element.id]);
|
|
86053
|
+
const timeId = viewport.timeIds[nextIndex];
|
|
86054
|
+
const timestamp = viewport.timestamps[nextIndex];
|
|
86055
|
+
(0, imageStore_1.set)(["timeId", element.id, timeId]);
|
|
86056
|
+
(0, imageStore_1.set)(["timestamp", element.id, timestamp]);
|
|
86057
|
+
}
|
|
86058
|
+
}
|
|
86059
|
+
}
|
|
86060
|
+
/*
|
|
86061
|
+
* @method scrollWithoutSkipping
|
|
86062
|
+
* @param {stackData} stackData
|
|
86063
|
+
* @param {pendingEvent} pendingEvent
|
|
86064
|
+
* @param {element} element
|
|
86065
|
+
* @desc Handles the event of the mouse wheel
|
|
86066
|
+
*/
|
|
86067
|
+
scrollWithoutSkipping(stackData, pendingEvent, element) {
|
|
86068
|
+
const newImageHandler = (event) => {
|
|
86069
|
+
const index = stackData.imageIds.indexOf(event.detail.image.imageId);
|
|
86070
|
+
if (index === pendingEvent.index) {
|
|
86071
|
+
stackData.pending = [];
|
|
86072
|
+
element.removeEventListener("cornerstoneimagerendered", newImageHandler);
|
|
86073
|
+
}
|
|
86074
|
+
};
|
|
86075
|
+
element.addEventListener("cornerstoneimagerendered", newImageHandler);
|
|
86076
|
+
scrollToIndex(element, pendingEvent.index);
|
|
86077
|
+
}
|
|
86078
|
+
}
|
|
86079
|
+
exports["default"] = CustomMouseWheelScrollTool;
|
|
86080
|
+
|
|
86081
|
+
|
|
85820
86082
|
/***/ }),
|
|
85821
86083
|
|
|
85822
86084
|
/***/ 8737:
|
|
@@ -86060,6 +86322,7 @@ const polylineScissorsTool_1 = __importDefault(__webpack_require__(8990));
|
|
|
86060
86322
|
const rectangleRoiOverlayTool_1 = __importDefault(__webpack_require__(1828));
|
|
86061
86323
|
const ellipticalRoiOverlayTool_1 = __importDefault(__webpack_require__(3211));
|
|
86062
86324
|
const BorderMagnifyTool_1 = __importDefault(__webpack_require__(7819));
|
|
86325
|
+
const customMouseWheelScrollTool_1 = __importDefault(__webpack_require__(4585));
|
|
86063
86326
|
/**
|
|
86064
86327
|
* These tools are added with `addDefaultTools()`
|
|
86065
86328
|
*/
|
|
@@ -86127,48 +86390,28 @@ const DEFAULT_TOOLS = {
|
|
|
86127
86390
|
shortcut: "ctrl-m",
|
|
86128
86391
|
type: "utils"
|
|
86129
86392
|
},
|
|
86130
|
-
|
|
86131
|
-
name: "
|
|
86393
|
+
CustomMouseWheelScroll: {
|
|
86394
|
+
name: "CustomMouseWheelScroll",
|
|
86132
86395
|
viewports: "all",
|
|
86133
86396
|
configuration: {
|
|
86134
86397
|
loop: false,
|
|
86135
|
-
allowSkipping: true
|
|
86398
|
+
allowSkipping: true,
|
|
86399
|
+
invert: false,
|
|
86400
|
+
fixedFrame: 1,
|
|
86401
|
+
fixedSlice: 0,
|
|
86402
|
+
currentMode: "stack",
|
|
86403
|
+
framesNumber: 1
|
|
86136
86404
|
},
|
|
86137
86405
|
options: {
|
|
86138
|
-
mouseButtonMask:
|
|
86139
|
-
deltaY: 0 // default 0
|
|
86406
|
+
mouseButtonMask: 0
|
|
86140
86407
|
},
|
|
86141
86408
|
cleanable: false,
|
|
86142
|
-
defaultActive: false,
|
|
86143
|
-
class: "StackScrollTool"
|
|
86144
|
-
},
|
|
86145
|
-
StackScrollMouseWheel: {
|
|
86146
|
-
name: "StackScrollMouseWheel",
|
|
86147
|
-
viewports: "all",
|
|
86148
|
-
configuration: {
|
|
86149
|
-
loop: false,
|
|
86150
|
-
allowSkipping: true,
|
|
86151
|
-
invert: false
|
|
86152
|
-
},
|
|
86153
|
-
options: {},
|
|
86154
|
-
cleanable: false,
|
|
86155
86409
|
defaultActive: true,
|
|
86156
|
-
class: "
|
|
86410
|
+
class: "CustomMouseWheelScrollTool",
|
|
86411
|
+
description: "scroll images/frames",
|
|
86412
|
+
shortcut: "mouse wheel",
|
|
86413
|
+
type: "utils"
|
|
86157
86414
|
},
|
|
86158
|
-
// Slice4DScrollMouseWheel: {
|
|
86159
|
-
// name: "Slice4DScrollMouseWheel",
|
|
86160
|
-
// viewports: "all",
|
|
86161
|
-
// configuration: {
|
|
86162
|
-
// loop: false, // default false
|
|
86163
|
-
// allowSkipping: false, // default true
|
|
86164
|
-
// invert: false,
|
|
86165
|
-
// framesNumber: 1
|
|
86166
|
-
// },
|
|
86167
|
-
// options: {},
|
|
86168
|
-
// cleanable: false,
|
|
86169
|
-
// defaultActive: true,
|
|
86170
|
-
// class: "Slice4DScrollMouseWheelTool"
|
|
86171
|
-
// },
|
|
86172
86415
|
Pan: {
|
|
86173
86416
|
name: "Pan",
|
|
86174
86417
|
viewports: "all",
|
|
@@ -86178,6 +86421,7 @@ const DEFAULT_TOOLS = {
|
|
|
86178
86421
|
supportedInteractionTypes: ["Mouse", "Touch"]
|
|
86179
86422
|
},
|
|
86180
86423
|
cleanable: false,
|
|
86424
|
+
defaultActive: false,
|
|
86181
86425
|
class: "PanTool",
|
|
86182
86426
|
description: "Move image xy",
|
|
86183
86427
|
shortcut: "ctrl-p",
|
|
@@ -86193,13 +86437,13 @@ const DEFAULT_TOOLS = {
|
|
|
86193
86437
|
maxScale: 25.0
|
|
86194
86438
|
},
|
|
86195
86439
|
options: {
|
|
86196
|
-
mouseButtonMask:
|
|
86440
|
+
mouseButtonMask: 2,
|
|
86197
86441
|
supportedInteractionTypes: ["Mouse", "Touch"],
|
|
86198
86442
|
defaultStrategy: "default" // can be 'default', 'translate' or 'zoomToCenter'
|
|
86199
86443
|
},
|
|
86200
86444
|
cleanable: false,
|
|
86201
86445
|
class: "ZoomTool",
|
|
86202
|
-
defaultActive:
|
|
86446
|
+
defaultActive: true,
|
|
86203
86447
|
description: "Zoom image at mouse position",
|
|
86204
86448
|
shortcut: "ctrl-z",
|
|
86205
86449
|
type: "utils"
|
|
@@ -86381,7 +86625,7 @@ const DEFAULT_TOOLS = {
|
|
|
86381
86625
|
},
|
|
86382
86626
|
cleanable: false,
|
|
86383
86627
|
class: "ZoomTouchPinchTool",
|
|
86384
|
-
defaultActive:
|
|
86628
|
+
defaultActive: false
|
|
86385
86629
|
},
|
|
86386
86630
|
PanMultiTouch: {
|
|
86387
86631
|
name: "PanMultiTouch",
|
|
@@ -86395,7 +86639,7 @@ const DEFAULT_TOOLS = {
|
|
|
86395
86639
|
},
|
|
86396
86640
|
cleanable: false,
|
|
86397
86641
|
class: "PanMultiTouchTool",
|
|
86398
|
-
defaultActive:
|
|
86642
|
+
defaultActive: false
|
|
86399
86643
|
},
|
|
86400
86644
|
Brush: {
|
|
86401
86645
|
name: "Brush",
|
|
@@ -86485,7 +86729,8 @@ const dvTools = {
|
|
|
86485
86729
|
// Slice4DScrollMouseWheelTool: Slice4DScrollMouseWheelTool,
|
|
86486
86730
|
RectangleRoiOverlayTool: rectangleRoiOverlayTool_1.default,
|
|
86487
86731
|
EllipticalRoiOverlayTool: ellipticalRoiOverlayTool_1.default,
|
|
86488
|
-
BorderMagnifyTool: BorderMagnifyTool_1.default
|
|
86732
|
+
BorderMagnifyTool: BorderMagnifyTool_1.default,
|
|
86733
|
+
CustomMouseWheelScrollTool: customMouseWheelScrollTool_1.default
|
|
86489
86734
|
};
|
|
86490
86735
|
exports.dvTools = dvTools;
|
|
86491
86736
|
/**
|
|
@@ -86801,7 +87046,7 @@ const toggleMouseToolsListeners = function (elementId, disable) {
|
|
|
86801
87046
|
// TODO-ts fix type (should be a cornerstoneTools event type)
|
|
86802
87047
|
// @mronzoni does cornerstoneTools have a type for this event?
|
|
86803
87048
|
(0, imageStore_1.set)(["sliceId", evt.target.id, evt.detail.newImageIdIndex]);
|
|
86804
|
-
(0, imageRendering_1.updateViewportData)(evt.srcElement.id, evt.detail, "
|
|
87049
|
+
(0, imageRendering_1.updateViewportData)(evt.srcElement.id, evt.detail, "CustomMouseWheelScroll");
|
|
86805
87050
|
}
|
|
86806
87051
|
if (disable) {
|
|
86807
87052
|
element.removeEventListener("cornerstonetoolsmousedrag", mouseMoveHandler);
|
|
@@ -87229,7 +87474,7 @@ function tryUpdateImage(element) {
|
|
|
87229
87474
|
* @param {Boolean} doNotSetInStore - Flag to avoid setting in store (useful on tools initialization eg in addDefaultTools). NOTE: This is just a hack, we must rework tools/ui sync.
|
|
87230
87475
|
*/
|
|
87231
87476
|
const setToolActive = function (toolName, options, viewports, doNotSetInStore) {
|
|
87232
|
-
var _a;
|
|
87477
|
+
var _a, _b;
|
|
87233
87478
|
let defaultOpt = Object.assign({}, (_a = default_1.DEFAULT_TOOLS[toolName]) === null || _a === void 0 ? void 0 : _a.options); // deep copy obj because otherwise cornerstone tools will modify it
|
|
87234
87479
|
(0, lodash_1.extend)(defaultOpt, options);
|
|
87235
87480
|
if (viewports && viewports.length > 0) {
|
|
@@ -87254,6 +87499,9 @@ const setToolActive = function (toolName, options, viewports, doNotSetInStore) {
|
|
|
87254
87499
|
// mouseButtonMask is now an array, thanks to cs tools "setToolActiveForElement",
|
|
87255
87500
|
// but only if it has a rendered image in the viewport (!)
|
|
87256
87501
|
// so we must check the type anyway for type coherence
|
|
87502
|
+
if (((_b = default_1.DEFAULT_TOOLS[toolName]) === null || _b === void 0 ? void 0 : _b.defaultActive) === true) {
|
|
87503
|
+
doNotSetInStore = false;
|
|
87504
|
+
}
|
|
87257
87505
|
if (!doNotSetInStore && defaultOpt.mouseButtonMask) {
|
|
87258
87506
|
if (typeof defaultOpt.mouseButtonMask == "number") {
|
|
87259
87507
|
defaultOpt.mouseButtonMask = [defaultOpt.mouseButtonMask];
|
|
@@ -88981,7 +89229,7 @@ module.exports = JSON.parse('{"x00000000":{"tag":"x00000000","vr":"UL","vm":"1",
|
|
|
88981
89229
|
/***/ ((module) => {
|
|
88982
89230
|
|
|
88983
89231
|
"use strict";
|
|
88984
|
-
module.exports = JSON.parse('{"name":"larvitar","keywords":["DICOM","imaging","medical","cornerstone"],"version":"2.0
|
|
89232
|
+
module.exports = JSON.parse('{"name":"larvitar","keywords":["DICOM","imaging","medical","cornerstone"],"version":"2.1.0","description":"typescript library for parsing, loading, rendering and interacting with DICOM images","repository":{"url":"https://github.com/dvisionlab/Larvitar.git","type":"git"},"main":"dist/larvitar.js","types":"dist/index.d.ts","files":["dist","imaging/**/*.d.ts"],"scripts":{"coverage":"typescript-coverage-report","generate-docs":"node_modules/.bin/jsdoc -c jsdoc.json","build":"webpack --config ./bundler/webpack.prod.js && cp ./dist/larvitar.js ./docs/examples/larvitar.js","dev":"webpack --progress --config ./bundler/webpack.dev.js && cp ./dist/larvitar.js ./docs/examples/larvitar.js","dev-wip":"webpack serve --config ./bundler/webpack.dev-wip.js"},"author":"Simone Manini <simone.manini@dvisionlab.com> (https://www.dvisionlab.com)","contributors":["Mattia Ronzoni <mattia.ronzoni@dvisionlab.com> (https://www.dvisionlab.com)","Sara Zanchi <sara.zanchi@dvisionlab.com> (https://www.dvisionlab.com)","Ale Re <ale.re@dvisionlab.com> (https://www.dvisionlab.com)","Laura Borghesi Re <laura.borghesi@dvisionlab.com> (https://www.dvisionlab.com)"],"license":"MIT","dependencies":{"@rollup/plugin-commonjs":"^17.1.0","cornerstone-core":"^2.6.1","cornerstone-file-image-loader":"^0.3.0","cornerstone-tools":"^6.0.7","cornerstone-wado-image-loader":"^4.13.2","cornerstone-web-image-loader":"^2.1.1","crypto-js":"^4.1.1","dicom-character-set":"^1.0.3","dicom-parser":"^1.8.13","docdash":"^1.2.0","hammerjs":"^2.0.8","jpeg-lossless-decoder-js":"^2.0.7","keycode-js":"^3.1.0","lodash":"^4.17.15","pako":"^1.0.10","papaparse":"^5.3.0","plotly.js-dist-min":"^2.27.1","uuid":"^8.3.2"},"devDependencies":{"@babel/core":"^7.21.8","@types/cornerstone-core":"^2.3.0","@types/crypto-js":"^4.1.1","@types/hammerjs":"^2.0.41","@types/lodash":"^4.14.192","@types/papaparse":"^5.3.7","@types/plotly.js":"^2.12.30","@types/plotly.js-dist-min":"^2.3.4","@types/uuid":"^9.0.1","babel-loader":"^9.1.2","clean-webpack-plugin":"^4.0.0","copy-webpack-plugin":"^11.0.0","fs":"^0.0.1-security","html-loader":"^4.2.0","html-webpack-plugin":"^5.5.0","ip":"^1.1.8","jsdoc":"^3.6.4","portfinder-sync":"^0.0.2","ts-loader":"^9.4.2","typescript":"^5.0.2","typescript-coverage-report":"^0.7.0","webpack":"^5.76.3","webpack-bundle-analyzer":"^4.8.0","webpack-cli":"^5.0.1","webpack-dev-server":"^4.13.1"}}');
|
|
88985
89233
|
|
|
88986
89234
|
/***/ })
|
|
88987
89235
|
|