阅片工具更改

main
caiyiling 2026-08-07 16:02:57 +08:00
parent f3610b685a
commit 8bdac9bd6e
3 changed files with 107 additions and 23 deletions

View File

@ -160,6 +160,17 @@
<svg-icon v-if="forceFitToWindow" icon-class="fitToWindow" class="svg-icon" />
<svg-icon v-else icon-class="fitToImage" class="svg-icon" />
</div>
<!-- 同步切图 -->
<div v-if="!isFusion && !isMPR && cells.length > 1"
:class="['tool-item', isScrollSync ? 'tool-item-active' : '']"
:title="$t('trials:reading:button:imageIndexSync')" @click.prevent="setImageIndexSync">
<i v-if="isScrollSync" class="el-icon-lock svg-icon" />
<i v-else class="el-icon-unlock svg-icon" />
</div>
<!-- 截图 -->
<div class="tool-item" :title="$t('trials:reading:button:screenShot')" @click.prevent="saveImage">
<svg-icon icon-class="image" class="svg-icon" />
</div>
<!-- MPR -->
<div class="tool-item" :title="`${$t('trials:reading:button:mpr')}`" @click.prevent="openMPRViewport()"
v-if="((criterionType === 0 && readingTool === 0) || this.readingTool === 3) && !isMPR">
@ -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}`)" />
<Viewport :ref="`viewport-${index}`" :data-viewport-uid="`viewport-${index}`"
:rendering-engine-id="renderingEngineId" :viewport-id="`viewport-${index}`" :viewport-index="index"
:is-scroll-sync="isScrollSync" @scrollSync="handleViewportScrollSync"
@activeViewport="activeViewport" @toggleTaskByViewport="toggleTaskByViewport" @previewCD="previewCD"
@renderAnnotations="renderAnnotations" @contentMouseup="contentMouseup" v-else />
</div>
@ -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

View File

@ -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
}

View File

@ -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
}