diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue
index 96a8f1e8..9240870a 100644
--- a/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue
+++ b/src/views/trials/trials-panel/reading/dicoms3D/components/ReadPage.vue
@@ -160,6 +160,17 @@
+
+
+
+
+
+
+
+
+
@@ -381,13 +392,16 @@
:rendering-engine-id="renderingEngineId" :viewport-id="`viewport-${index}`" :viewport-index="index"
:histogramVisible="histogramVisible" :actionConfiguration="actionConfiguration"
:SegmentConfig="SegmentConfig" :segmentationId.sync="segId" :segmentIndex.sync="segIndex"
- :curSegSeries.sync="curSegSeries" @activeViewport="activeViewport"
+ :curSegSeries.sync="curSegSeries" :is-scroll-sync="isScrollSync"
+ @activeViewport="activeViewport"
@toggleTaskByViewport="toggleTaskByViewport" @previewCD="previewCD"
@renderAnnotations="renderAnnotations" @contentMouseup="contentMouseup"
- @resetViewport="resetViewport" @resetHistogram="resetHistogram" v-if="readingTool === 3"
+ @resetViewport="resetViewport" @resetHistogram="resetHistogram"
+ @scrollSync="handleViewportScrollSync" v-if="readingTool === 3"
v-resize="(e) => handleSizeChange(e, `viewport-${index}`)" />
@@ -799,6 +813,7 @@ export default {
activeViewportWC: null,
clipPlaying: false,
fps: 15,
+ isScrollSync: false,
manualsDialog: { visible: false, isFullscreen: false, justKeyDoc: false },
hotKeyList: [],
forceFitToWindow: false,
@@ -3415,8 +3430,34 @@ export default {
scrollPage(type) {
// if (this.histogramVisible) return false
this.clipPlaying = false
+ if (this.isScrollSync && !this.isFusion && !this.isMPR && this.cells.length > 1) {
+ for (let i = 0; i < this.cells.length; i++) {
+ const viewportRef = this.$refs[`${this.viewportKey}-${i}`]
+ if (viewportRef && viewportRef[0] && typeof viewportRef[0].scrollPage === 'function') {
+ viewportRef[0].scrollPage(type)
+ }
+ }
+ return
+ }
this.$refs[`${this.viewportKey}-${this.activeViewportIndex}`][0].scrollPage(type)
},
+ setImageIndexSync() {
+ this.isScrollSync = !this.isScrollSync
+ },
+ handleViewportScrollSync({ viewportIndex, type, direction }) {
+ if (!this.isScrollSync || this.isFusion || this.isMPR || this.cells.length <= 1) return
+ const syncType = type ?? direction
+ if (viewportIndex !== this.activeViewportIndex || ![-1, 1, 0, 99999].includes(syncType)) return
+
+ this.clipPlaying = false
+ for (let i = 0; i < this.cells.length; i++) {
+ if (i === viewportIndex) continue
+ const viewportRef = this.$refs[`${this.viewportKey}-${i}`]
+ if (viewportRef && viewportRef[0] && typeof viewportRef[0].scrollPage === 'function') {
+ viewportRef[0].scrollPage(syncType)
+ }
+ }
+ },
// 播放
toggleClipPlay(isPlay) {
// if (this.histogramVisible) return false
diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/Viewport.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/Viewport.vue
index 06805756..14764a7a 100644
--- a/src/views/trials/trials-panel/reading/dicoms3D/components/Viewport.vue
+++ b/src/views/trials/trials-panel/reading/dicoms3D/components/Viewport.vue
@@ -117,6 +117,10 @@ export default {
viewportIndex: {
type: Number,
required: true
+ },
+ isScrollSync: {
+ type: Boolean,
+ default: false
}
},
data() {
@@ -191,6 +195,7 @@ export default {
this.element.oncontextmenu = (e) => e.preventDefault()
this.resizeObserver.observe(this.element)
this.element.addEventListener('CORNERSTONE_STACK_NEW_IMAGE', this.stackNewImage)
+ this.element.addEventListener('wheel', this.handleWheelSync)
// this.element.addEventListener('CORNERSTONE_VOI_MODIFIED', this.voiModified)
// this.element.addEventListener('CORNERSTONE_CAMERA_MODIFIED', this.cameraModified)
@@ -374,6 +379,32 @@ export default {
toolGroup.setToolEnabled('ScaleOverlay')
}
},
+ handleWheelSync(e) {
+ if (!this.isScrollSync) return
+
+ const deltaY = typeof e.deltaY === 'number' ? e.deltaY : -e.wheelDeltaY
+ if (!deltaY) return
+
+ const renderingEngine = getRenderingEngine(this.renderingEngineId)
+ const viewport = renderingEngine && renderingEngine.getViewport(this.viewportId)
+ if (!viewport) return
+
+ const currentImageIdIndex = viewport.getCurrentImageIdIndex()
+ const numImages = viewport.getImageIds().length
+ if (numImages <= 1) return
+ const direction = deltaY > 0 ? 1 : -1
+ let type = direction
+
+ if (direction === 1 && currentImageIdIndex >= numImages - 1) {
+ type = 0
+ csUtils.jumpToSlice(viewport.element, { imageIndex: 0 })
+ } else if (direction === -1 && currentImageIdIndex <= 0) {
+ type = 99999
+ csUtils.jumpToSlice(viewport.element, { imageIndex: numImages - 1 })
+ }
+
+ this.$emit('scrollSync', { viewportIndex: this.viewportIndex, type })
+ },
scrollPage(type) {
const renderingEngine = getRenderingEngine(this.renderingEngineId)
const viewport = renderingEngine.getViewport(this.viewportId)
@@ -383,9 +414,9 @@ export default {
if (type === 0) {
newImageIdIndex = 0
} else if (type === -1) {
- newImageIdIndex = currentImageIdIndex === 0 ? currentImageIdIndex : currentImageIdIndex - 1
+ newImageIdIndex = currentImageIdIndex === 0 ? numImages - 1 : currentImageIdIndex - 1
} else if (type === 1) {
- newImageIdIndex = currentImageIdIndex === numImages - 1 ? currentImageIdIndex : currentImageIdIndex + 1
+ newImageIdIndex = currentImageIdIndex === numImages - 1 ? 0 : currentImageIdIndex + 1
} else if (type === 99999) {
newImageIdIndex = numImages - 1
}
diff --git a/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue b/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue
index da5619f2..5bf1bfb8 100644
--- a/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue
+++ b/src/views/trials/trials-panel/reading/dicoms3D/components/VolumeViewport.vue
@@ -130,6 +130,10 @@ export default {
type: Number,
required: true
},
+ isScrollSync: {
+ type: Boolean,
+ default: false
+ },
histogramVisible: {
type: Boolean,
default: false
@@ -304,23 +308,7 @@ export default {
this.element.addEventListener("CORNERSTONE_VOLUME_NEW_IMAGE", this.stackNewImage)
this.element.addEventListener('CORNERSTONE_VOI_MODIFIED', this.voiModified)
this.element.addEventListener('CORNERSTONE_IMAGE_RENDERED', this.imageRendered)
- this.element.addEventListener('wheel', (e) => {
- // if (this.histogramVisible) return false
- console.log('CORNERSTONE_STACK_VIEWPORT_SCROLL')
- const renderingEngine = getRenderingEngine(this.renderingEngineId)
- const viewport = renderingEngine.getViewport(this.viewportId)
- const currentImageIdIndex = viewport.getCurrentImageIdIndex()
- const totalImages = this.imageInfo.total;
-
- // 手动实现循环逻辑
- if (currentImageIdIndex >= totalImages - 1 && e.wheelDeltaY < 0) {
- // 滚动到最后一张时跳回第一张
- csUtils.jumpToSlice(viewport.element, { imageIndex: 0 });
- } else if (currentImageIdIndex <= 0 && e.wheelDeltaY > 0) {
- // 滚动到第一张时跳回最后一张
- csUtils.jumpToSlice(viewport.element, { imageIndex: totalImages - 1 });
- }
- });
+ this.element.addEventListener('wheel', this.handleWheelSync)
this.element.addEventListener('CORNERSTONE_TOOLS_MOUSE_MOVE', this.cornerstoneToolsMouseMove)
// this.element.addEventListener(cornerstoneTools.Enums.Events.MOUSE_WHEEL, this.handletoolsMouseWheel)
this.element.addEventListener('mouseleave', () => {
@@ -390,6 +378,30 @@ export default {
setFilp(f = false) {
this.isFlip = f
},
+ handleWheelSync(e) {
+ const deltaY = typeof e.deltaY === 'number' ? e.deltaY : -e.wheelDeltaY
+ if (!deltaY) return
+
+ const renderingEngine = getRenderingEngine(this.renderingEngineId)
+ const viewport = renderingEngine.getViewport(this.viewportId)
+ const currentImageIdIndex = viewport.getCurrentImageIdIndex()
+ const totalImages = this.imageInfo.total
+ if (totalImages <= 1) return
+ const direction = deltaY > 0 ? 1 : -1
+ let type = direction
+
+ if (currentImageIdIndex >= totalImages - 1 && direction === 1) {
+ type = 0
+ csUtils.jumpToSlice(viewport.element, { imageIndex: 0 })
+ } else if (currentImageIdIndex <= 0 && direction === -1) {
+ type = 99999
+ csUtils.jumpToSlice(viewport.element, { imageIndex: totalImages - 1 })
+ }
+
+ if (this.isScrollSync) {
+ this.$emit('scrollSync', { viewportIndex: this.viewportIndex, type })
+ }
+ },
stackNewImage(e) {
if (this.isFlip) return this.isFlip = false
const { detail } = e
@@ -573,9 +585,9 @@ export default {
if (type === 0) {
newImageIdIndex = 0
} else if (type === -1) {
- newImageIdIndex = currentImageIdIndex === 0 ? currentImageIdIndex : currentImageIdIndex - 1
+ newImageIdIndex = currentImageIdIndex === 0 ? numImages - 1 : currentImageIdIndex - 1
} else if (type === 1) {
- newImageIdIndex = currentImageIdIndex === numImages - 1 ? currentImageIdIndex : currentImageIdIndex + 1
+ newImageIdIndex = currentImageIdIndex === numImages - 1 ? 0 : currentImageIdIndex + 1
} else if (type === 99999) {
newImageIdIndex = numImages - 1
}