This commit is contained in:
lxd 2024-12-27 17:25:57 +08:00
commit b1988882cb
3 changed files with 142 additions and 87 deletions

View File

@ -146,7 +146,7 @@
</el-button> </el-button>
<span style="font-size: 15px; margin-bottom: 10px">测量</span> <span style="font-size: 15px; margin-bottom: 10px">测量</span>
<!-- <el-button <el-button
style="width: 30px; height: 30px; margin-bottom: 10px" style="width: 30px; height: 30px; margin-bottom: 10px"
type="primary" type="primary"
plain plain
@ -154,7 +154,7 @@
> >
<el-icon><ZoomIn /></el-icon> <el-icon><ZoomIn /></el-icon>
</el-button> </el-button>
<span style="font-size: 15px; margin-bottom: 10px">放大</span> --> <span style="font-size: 15px; margin-bottom: 10px">放大</span>
<el-button <el-button
style="width: 30px; height: 30px; margin-bottom: 10px" style="width: 30px; height: 30px; margin-bottom: 10px"
@ -582,6 +582,7 @@ import ECGCopmareDialog from '@/views/ECG/ECGCompare.vue'
import ECGApplyforRepair from '@/views/ECG/ECGModify/ECGApplyforRepair.vue' import ECGApplyforRepair from '@/views/ECG/ECGModify/ECGApplyforRepair.vue'
import useClipboard from "vue-clipboard3";// import useClipboard from "vue-clipboard3";//
const { toClipboard } = useClipboard(); const { toClipboard } = useClipboard();
import ECGSB from '@/views/ECG/ECGSB.vue'
/** 提交表单 */ /** 提交表单 */
const emit = defineEmits(['success']) // success const emit = defineEmits(['success']) // success
const message = useMessage() // const message = useMessage() //

View File

@ -1,121 +1,174 @@
<template> <template>
<div class="magnifier" v-show="isShow"> <div class="magnifier" v-show="isShow">
<!-- 只保留放大的内容 -->
<div <div
v-if="isZoomed" v-if="isZoomed"
class="magnifier-glass" class="magnifier-glass"
:style="{ :style="{
left: zoomedPosition.x + 'px', left: zoomedPosition.x + 'px',
top: zoomedPosition.y + 'px', top: zoomedPosition.y + 'px',
backgroundImage: screenshotUrl ? `url(${screenshotUrl})` : 'none', transform: `translate(-50%, -50%) scale(1)`,
backgroundPosition: 'center', width: '300px',
backgroundSize: 'cover', height: '200px',
width: '250px', backgroundColor: 'white'
height: '250px'
}" }"
></div> >
<canvas ref="magnifierCanvas" width="300" height="200"></canvas>
</div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, reactive } from 'vue' import { ref, reactive } from 'vue'
import html2canvas from 'html2canvas'
import ECGForm from './ECGForm.vue'
const isShow = ref(true) const isShow = ref(true)
const isZoomed = ref(false) const isZoomed = ref(false)
const screenshotUrl = ref('') const magnifierCanvas = ref(null)
const zoomLevel = 1.8
const zoomedPosition = reactive({ const zoomedPosition = reactive({
x: 0, x: 0,
y: 0 y: 0
}) })
// //
async function captureArea(x, y) { function drawMagnifiedArea(x, y, container) {
try { if (!magnifierCanvas.value) return
const container = document.querySelector('.el-tab-pane')
if (!container) return
const captureSize = 50
const rect = container.getBoundingClientRect()
const left = x - captureSize / 2
const top = y - captureSize / 2
const canvas = await html2canvas(document.body, { const ctx = magnifierCanvas.value.getContext('2d', { willReadFrequently: true })
useCORS: true, const container1 = document.querySelector('#canvas-container')
allowTaint: true, const container2 = document.querySelector('#canvas-container1')
scale: 3, // const rect1 = container1.getBoundingClientRect()
x: left - rect.left, // const rect2 = container2.getBoundingClientRect()
y: top - rect.top, //
width: captureSize,
height: captureSize,
backgroundColor: null
})
screenshotUrl.value = canvas.toDataURL('image/jpeg', 0.5) //
isZoomed.value = true const transitionZone = 20 //
zoomedPosition.x = x const isInTransition = Math.abs(x - rect2.left) < transitionZone
zoomedPosition.y = y
} catch (error) { ctx.clearRect(0, 0, 300, 200)
console.error('截图失败:', error) ctx.imageSmoothingEnabled = true
ctx.imageSmoothingQuality = 'high'
if (isInTransition) {
//
const weight2 = (x - (rect2.left - transitionZone)) / (transitionZone * 2)
const weight1 = 1 - weight2
//
drawContainerContent(ctx, container1, x, y, rect1, weight1)
//
drawContainerContent(ctx, container2, x, y, rect2, weight2)
} else {
//
const currentContainer = x < rect2.left ? container1 : container2
const currentRect = x < rect2.left ? rect1 : rect2
drawContainerContent(ctx, currentContainer, x, y, currentRect, 1)
} }
} }
//
function drawContainerContent(ctx, container, x, y, rect, alpha) {
if (alpha === 0) return
ctx.globalAlpha = alpha
const layers = [
container.querySelector('#bottomCanvas, #bottomCanvas1'),
container.querySelector('#leftCanvas, #rightCanvas'),
container.querySelector('#topCanvas, #topCanvas1')
].filter(canvas => canvas)
layers.forEach(canvas => {
const canvasRect = canvas.getBoundingClientRect()
const canvasX = x - canvasRect.left
const canvasY = y - canvasRect.top
ctx.drawImage(
canvas,
canvasX - 75,
canvasY - 50,
150,
100,
0,
0,
300,
200
)
})
ctx.globalAlpha = 1
}
//
function handleMouseMove(e) {
if (!isZoomed.value) return
const container1 = document.querySelector('#canvas-container')
const container2 = document.querySelector('#canvas-container1')
const rect1 = container1.getBoundingClientRect()
const rect2 = container2.getBoundingClientRect()
//
const isInContainer1 = e.clientX >= rect1.left && e.clientX <= rect1.right &&
e.clientY >= rect1.top && e.clientY <= rect1.bottom
const isInContainer2 = e.clientX >= rect2.left && e.clientX <= rect2.right &&
e.clientY >= rect2.top && e.clientY <= rect2.bottom
if (!isInContainer1 && !isInContainer2) {
isZoomed.value = false
document.removeEventListener('mousemove', handleMouseMove)
return
}
zoomedPosition.x = e.clientX
zoomedPosition.y = e.clientY
// 使
const currentContainer = e.clientX < rect2.left ? container1 : container2
drawMagnifiedArea(e.clientX, e.clientY, currentContainer)
}
// //
function handleMouseDown(e) { function handleMouseDown(e) {
if (e.button === 0) { const container = e.target.closest('#canvas-container, #canvas-container1')
// if (!container || e.button !== 0) return
if (isZoomed.value) {
// const rect = container.getBoundingClientRect()
isZoomed.value = false const isInContainer = e.clientX >= rect.left && e.clientX <= rect.right &&
screenshotUrl.value = '' e.clientY >= rect.top && e.clientY <= rect.bottom
} else {
// if (!isInContainer) return
captureArea(e.clientX, e.clientY)
} if (isZoomed.value) {
isZoomed.value = false
document.removeEventListener('mousemove', handleMouseMove)
} else {
isZoomed.value = true
zoomedPosition.x = e.clientX
zoomedPosition.y = e.clientY
drawMagnifiedArea(e.clientX, e.clientY, container)
document.addEventListener('mousemove', handleMouseMove)
} }
} }
// function handleKeyPress(e) {
// if (e.key === 'Escape') {
// isShow.value = !isShow.value
// isZoomed.value = false
// screenshotUrl.value = ''
// if (isShow.value) {
// document.addEventListener('mousedown', handleMouseDown)
// } else {
// document.removeEventListener('mousedown', handleMouseDown)
// }
// }
// }
onMounted(() => {
// document.addEventListener('keydown', handleKeyPress)
})
onUnmounted(() => {
//document.removeEventListener('keydown', handleKeyPress)
// document.removeEventListener('mousedown', handleMouseDown)
})
nextTick(() => {
});
const infoParams = defineProps({ const infoParams = defineProps({
Isfd: Boolean Isfd: Boolean
}) })
// watch props.isFD
watch([() => infoParams.Isfd], ([newfd], [oldds]) => { watch([() => infoParams.Isfd], ([newfd], [oldds]) => {
if (newfd !== oldds) { if (newfd !== oldds) {
console.log(newfd)
if (newfd) { if (newfd) {
document.addEventListener('mousedown', handleMouseDown) document.addEventListener('mousedown', handleMouseDown)
} else { } else {
document.removeEventListener('mousedown', handleMouseDown) document.removeEventListener('mousedown', handleMouseDown)
document.removeEventListener('mousemove', handleMouseMove)
isZoomed.value = false
} }
} }
}) })
onUnmounted(() => {
document.removeEventListener('mousedown', handleMouseDown)
document.removeEventListener('mousemove', handleMouseMove)
})
</script> </script>
<style scoped> <style scoped>
@ -131,12 +184,14 @@ watch([() => infoParams.Isfd], ([newfd], [oldds]) => {
.magnifier-glass { .magnifier-glass {
position: fixed; position: fixed;
border: 2px solid rgba(255, 0, 0, 0.5); border: 1px solid rgba(255, 0, 0, 0.5);
border-radius: 50%;
transform: translate(-50%, -50%);
background-repeat: no-repeat;
pointer-events: none; pointer-events: none;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
transition: all 0.2s ease-out; overflow: hidden;
}
canvas {
transform: scale(1.8);
transform-origin: center center;
} }
</style> </style>

View File

@ -126,7 +126,6 @@ function handleMouseDown(event, type) {
const y = event.clientY - rect.top const y = event.clientY - rect.top
if (lastPoint.value) { if (lastPoint.value) {
// 使线
drawLineAndDistance(lastPoint.value, { x, y }) drawLineAndDistance(lastPoint.value, { x, y })
lastPoint.value = null // lastPoint.value = null //
} else { } else {
@ -451,7 +450,7 @@ const lead_name = ['I', 'II', 'III', 'aVR', 'aVL', 'aVF']
const rlead_name = ['V1', 'V2', 'V3', 'V4', 'V5', 'V6'] const rlead_name = ['V1', 'V2', 'V3', 'V4', 'V5', 'V6']
// //<EFBFBD><EFBFBD><EFBFBD>
function handleFileChange() { function handleFileChange() {
const json = JSON.parse(text.value) const json = JSON.parse(text.value)