156 lines
4.1 KiB
Vue
156 lines
4.1 KiB
Vue
<template>
|
||
<div>
|
||
<!-- 左侧菜单 -->
|
||
<div
|
||
style="
|
||
position: fixed;
|
||
left: 0;
|
||
top: 0;
|
||
width: 200px;
|
||
height: 100vh;
|
||
background-color: #f0f0f0;
|
||
"
|
||
>
|
||
左侧菜单
|
||
</div>
|
||
|
||
<!-- 背景区域 -->
|
||
<div
|
||
ref="background"
|
||
style="margin-left: 200px; height: 100vh; position: relative; background-color: #fff"
|
||
>
|
||
<!-- 其他定位元素(如图片) -->
|
||
<img
|
||
src="https://sys.znkjfw.com/imgs/process/%E8%AF%B7%E5%81%87.png"
|
||
style="position: absolute; top: 100px; left: 300px; width: 150px; height: 150px"
|
||
alt="示例图片"
|
||
/>
|
||
|
||
<!-- 显示测量结果 -->
|
||
<div v-if="distance !== null" style="position: absolute; top: 20px; left: 220px">
|
||
距离:{{ distance.toFixed(2) }} 像素
|
||
</div>
|
||
|
||
<!-- 绘制点和连线 -->
|
||
<template v-if="points.length > 0">
|
||
<div
|
||
v-for="(point, index) in points"
|
||
:key="index"
|
||
:style="{
|
||
position: 'absolute',
|
||
left: `${point.x}px`,
|
||
top: `${point.y}px`,
|
||
width: '10px',
|
||
height: '10px',
|
||
backgroundColor: 'red',
|
||
borderRadius: '50%'
|
||
}"
|
||
></div>
|
||
<div
|
||
v-if="points.length === 2"
|
||
:style="{
|
||
position: 'absolute',
|
||
left: `${points[0].x}px`,
|
||
top: `${points[0].y}px`,
|
||
width: `${lineWidth}px`,
|
||
height: '2px',
|
||
backgroundColor: 'blue',
|
||
transform: `rotate(${lineAngle}deg)`,
|
||
transformOrigin: '0 0'
|
||
}"
|
||
></div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
||
|
||
export default {
|
||
setup() {
|
||
const background = ref(null) // 背景区域的 DOM 元素
|
||
const points = ref([]) // 存储点击的点位
|
||
const distance = ref(null) // 存储两点之间的距离
|
||
|
||
// 计算两点之间的距离
|
||
const calculateDistance = (point1, point2) => {
|
||
const dx = point2.x - point1.x
|
||
const dy = point2.y - point1.y
|
||
return Math.sqrt(dx * dx + dy * dy)
|
||
}
|
||
|
||
// 计算连线的角度
|
||
const lineAngle = computed(() => {
|
||
if (points.value.length === 2) {
|
||
const dx = points.value[1].x - points.value[0].x
|
||
const dy = points.value[1].y - points.value[0].y
|
||
return Math.atan2(dy, dx) * (180 / Math.PI)
|
||
}
|
||
return 0
|
||
})
|
||
|
||
// 计算连线的长度
|
||
const lineWidth = computed(() => {
|
||
if (points.value.length === 2) {
|
||
return calculateDistance(points.value[0], points.value[1])
|
||
}
|
||
return 0
|
||
})
|
||
|
||
// 处理点击事件
|
||
const handleClick = (event) => {
|
||
// 获取点击点相对于整个页面的坐标
|
||
const x = event.clientX
|
||
const y = event.clientY
|
||
|
||
// 检查点击是否发生在背景区域内
|
||
const backgroundRect = background.value.getBoundingClientRect()
|
||
if (
|
||
x >= backgroundRect.left &&
|
||
x <= backgroundRect.right &&
|
||
y >= backgroundRect.top &&
|
||
y <= backgroundRect.bottom
|
||
) {
|
||
if (points.value.length === 2) {
|
||
// 如果已经有两个点,清空信息
|
||
points.value = []
|
||
distance.value = null
|
||
} else {
|
||
// 记录点击的点位(相对于背景区域的坐标)
|
||
const offsetX = x - backgroundRect.left
|
||
const offsetY = y - backgroundRect.top
|
||
points.value.push({ x: offsetX, y: offsetY })
|
||
if (points.value.length === 2) {
|
||
// 计算两点之间的距离
|
||
distance.value = calculateDistance(points.value[0], points.value[1])
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 监听全局点击事件
|
||
onMounted(() => {
|
||
window.addEventListener('click', handleClick)
|
||
})
|
||
|
||
// 移除全局点击事件监听
|
||
onUnmounted(() => {
|
||
window.removeEventListener('click', handleClick)
|
||
})
|
||
|
||
return {
|
||
background,
|
||
points,
|
||
distance,
|
||
lineAngle,
|
||
lineWidth
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 样式可以根据需要调整 */
|
||
</style>
|