zn-admin-vue3-wcs/src/views/mapPage/realTimeMap/components-tool/editMapRoute.vue
2025-02-17 16:07:07 +08:00

190 lines
4.9 KiB
Vue

<template>
<div>
<!-- SVG 画布 -->
<svg
ref="svgRef"
width="500"
height="300"
@mousedown="handleMouseDown"
@mousemove="handleMouseMove"
@mouseup="handleMouseUp"
>
<!-- 绘制所有曲线 -->
<path
v-for="(curve, index) in curveList"
:key="index"
:d="getCurvePath(curve)"
stroke="#000"
fill="none"
stroke-width="2"
:class="{ selected: selectedCurve === curve }"
@click="svgClick(curve)"
/>
<!-- 绘制控制点和连线 -->
<line
v-if="selectedCurve"
:x1="selectedCurve.start.x"
:y1="selectedCurve.start.y"
:x2="selectedCurve.control1.x"
:y2="selectedCurve.control1.y"
stroke="gray"
stroke-dasharray="2"
/>
<line
v-if="selectedCurve"
:x1="selectedCurve.end.x"
:y1="selectedCurve.end.y"
:x2="selectedCurve.control2.x"
:y2="selectedCurve.control2.y"
stroke="gray"
stroke-dasharray="2"
/>
<!-- 绘制起点、终点和控制点 -->
<circle
v-for="(curve, index) in curveList"
:key="'start' + index"
:cx="curve.start.x"
:cy="curve.start.y"
r="5"
fill="red"
@mousedown="startDrag($event, curve, 'start')"
/>
<circle
v-for="(curve, index) in curveList"
:key="'end' + index"
:cx="curve.end.x"
:cy="curve.end.y"
r="5"
fill="red"
@mousedown="startDrag($event, curve, 'end')"
/>
<circle
v-if="selectedCurve"
:cx="selectedCurve.control1.x"
:cy="selectedCurve.control1.y"
r="5"
fill="green"
@mousedown="startDrag($event, selectedCurve, 'control1')"
/>
<circle
v-if="selectedCurve"
:cx="selectedCurve.control2.x"
:cy="selectedCurve.control2.y"
r="5"
fill="green"
@mousedown="startDrag($event, selectedCurve, 'control2')"
/>
</svg>
<!-- 显示控制点坐标 -->
<div class="points" v-if="selectedCurve">
<p>起点: ({{ selectedCurve.start.x }}, {{ selectedCurve.start.y }})</p>
<p>控制点 1: ({{ selectedCurve.control1.x }}, {{ selectedCurve.control1.y }})</p>
<p>控制点 2: ({{ selectedCurve.control2.x }}, {{ selectedCurve.control2.y }})</p>
<p>终点: ({{ selectedCurve.end.x }}, {{ selectedCurve.end.y }})</p>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
mapRouteList: {
type: Array,
default: () => []
}
})
const svgRef = ref(null) // SVG 元素的引用
const curveList = computed(() => props.mapRouteList) // 存储所有曲线
const selectedCurve = ref(null) // 当前选中的曲线
const isDragging = ref(false) // 是否正在拖拽
const dragTarget = ref(null) // 当前拖拽的目标(起点、终点、控制点)
// 获取鼠标位置
const getMousePos = (event) => {
const rect = svgRef.value.getBoundingClientRect()
return {
x: event.clientX - rect.left,
y: event.clientY - rect.top
}
}
// 开始拖拽
const startDrag = (event, curve, target) => {
event.preventDefault()
isDragging.value = true
selectedCurve.value = curve
dragTarget.value = target
}
// 鼠标按下事件
const handleMouseDown = (event) => {
const mousePos = getMousePos(event)
// 如果没有选中任何点,则创建一条新的直线
if (!isDragging.value && curveList.value.length === 0) {
const newCurve = {
start: mousePos,
end: mousePos,
control1: { x: mousePos.x + 50, y: mousePos.y - 50 },
control2: { x: mousePos.x + 100, y: mousePos.y - 50 }
}
curveList.value.push(newCurve)
selectedCurve.value = newCurve
dragTarget.value = 'end'
isDragging.value = true
}
}
// 鼠标移动事件
const handleMouseMove = (event) => {
if (!isDragging.value || !selectedCurve.value) return
const mousePos = getMousePos(event)
// 更新拖拽的目标点
if (dragTarget.value === 'start') {
selectedCurve.value.start = mousePos
} else if (dragTarget.value === 'end') {
selectedCurve.value.end = mousePos
} else if (dragTarget.value === 'control1') {
selectedCurve.value.control1 = mousePos
} else if (dragTarget.value === 'control2') {
selectedCurve.value.control2 = mousePos
}
}
// 鼠标松开事件
const handleMouseUp = () => {
isDragging.value = false
dragTarget.value = null
}
// 获取曲线的路径
const getCurvePath = (curve) => {
return `M ${curve.startPointX} ${curve.startPointY} C ${curve.beginControlX} ${curve.beginControlX}, ${curve.control2.x} ${curve.control2.y}, ${curve.endPointX} ${curve.endPointY}`
}
const svgClick = (item) => {
console.log(item)
}
</script>
<style scoped>
svg {
border: 1px solid #000;
cursor: crosshair;
}
path.selected {
stroke: blue;
}
.points {
margin-top: 10px;
font-size: 14px;
}
</style>