190 lines
4.9 KiB
Vue
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>
|