效果图如下
代码解释
<svg
@click="handleSvgClick"
@mousemove="handleMouseMove"
:width="svgWidth"
:height="svgHeight"
style="position: absolute; top: 0; left: 770px;"
>建立SVG区域,并且设立点击事件click(引出线),鼠标移动事件mousemove(拉线)
<rect
v-for="(area, index) in fixedAreas"
:key="index"
:x="area.x"
:y="area.y"
:width="area.width"
:height="area.height"
:fill="area.fill"
:fill-opacity="0.3"
:stroke="area.stroke"
:stroke-width="2"
/>设置方向框,用于连线
<!-- 动态线 -->
<line
v-if="startPoint && isDrawing && currentPoint"
:x1="startPoint.x"
:y1="startPoint.y"
:x2="currentPoint.x"
:y2="currentPoint.y"
:stroke="startPoint.color"
stroke-width="2"
/>实现拉线的效果
<line x1="540" y1="130" x2="180" y2="130" stroke="black" stroke-width="2" />
<line x1="760" y1="130" x2="1005" y2="130" stroke="black" stroke-width="2" />
<line x1="1200" y1="640" x2="1200" y2="140" stroke="black" stroke-width="2" />固定线,自主添加固定的线
<!-- 终点和固定线 -->
<g v-for="line in lines" :key="line.id" v-if="showLines">
<circle :cx="line.end.x" :cy="line.end.y" r="5" :fill="line.end.color" />
<line
:x1="line.start.x"
:y1="line.start.y"
:x2="line.end.x"
:y2="line.end.y"
:stroke="line.start.color"
stroke-width="2"
/>
</g>设置终点,并且将线固定
<svg@click="handleSvgClick"@mousemove="handleMouseMove":width="svgWidth":height="svgHeight"style="position: absolute; top: 0; left: 770px;"><rectv-for="(area, index) in fixedAreas":key="index":x="area.x":y="area.y":width="area.width":height="area.height":fill="area.fill":fill-opacity="0.3":stroke="area.stroke":stroke-width="2"/><!-- 动态线 --><linev-if="startPoint && isDrawing && currentPoint":x1="startPoint.x":y1="startPoint.y":x2="currentPoint.x":y2="currentPoint.y":stroke="startPoint.color"stroke-width="2"/><line x1="540" y1="130" x2="180" y2="130" stroke="black" stroke-width="2" /><line x1="760" y1="130" x2="1005" y2="130" stroke="black" stroke-width="2" /><line x1="1200" y1="640" x2="1200" y2="140" stroke="black" stroke-width="2" /><!-- 终点和固定线 --><g v-for="line in lines" :key="line.id" v-if="showLines"><circle :cx="line.end.x" :cy="line.end.y" r="5" :fill="line.end.color" /><line:x1="line.start.x":y1="line.start.y":x2="line.end.x":y2="line.end.y":stroke="line.start.color"stroke-width="2"/></g></svg>
代码解释
//svg区域大小的设置 const svgWidth = ref<number>(1280) const svgHeight = ref<number>(900)
//设置SVG里要显示的字 const spanAreas = ref([{x: 1520, y: 90,color:'red',text:"低噪放输出"},{x: 1710, y: 90,color:'red',text:"矩阵输入"},{x: 2000, y: 165,color:'red',text:"矩阵输出"},{x: 2000, y: 584,color:'red',text:"接收机输入"},{x: 1690, y: 395,color:'red',text:"检测点"}, ])
//svg区域
const svgWidth = ref<number>(1280)
const svgHeight = ref<number>(900)
const showLines = ref<boolean>(true)
//字体区域
const spanAreas = ref([{x: 100, y: 50,color:'red',text:"低噪放输出"},{x: 360, y: 415,color:'red',text:"矩阵输入"},{x: 40, y: 660,color:'red',text:"矩阵输出"},{x: 40, y: 660,color:'red',text:"接收机输入"},
])const startPoint = ref<any | null>(null);
const currentPoint = ref<any | null>(null);
const isDrawing = ref<boolean>(false);
const lines = ref<any[]>([]);const fixedAreas = ref([{ x: 135, y: 80, width: 30, height: 30, fill: 'red', stroke: 'red', id: 'area1' },{ x: 180, y: 80, width: 30, height: 30, fill: 'black', stroke: 'black', id: 'area2' },{ x: 320, y: 400, width: 30, height: 30, fill: 'red', stroke: 'red', id: 'area3' },{ x: 320, y: 440, width: 30, height: 30, fill: 'black', stroke: 'black', id: 'area4' },{ x: 130, y: 700, width: 30, height: 30, fill: 'red', stroke: 'red', id: 'area5' },{ x: 175, y: 700, width: 30, height: 30, fill: 'black', stroke: 'black', id: 'area6' },{ x: 765, y: 0, width: 30, height: 30, fill: 'red', stroke: 'red', id: 'area7' },{ x: 835, y: 0, width: 30, height: 30, fill: 'black', stroke: 'black', id: 'area8' }
]);
//让每次线在中心点绘制
const getCenter = (area: any) => {return {x: area.x + area.width / 2,y: area.y + area.height / 2};
};
const handleSvgClick = (event: MouseEvent) => {const x = event.offsetX;const y = event.offsetY;// 判断点击了哪个区域const clickedArea = fixedAreas.value.find(area =>x >= area.x && x <= area.x + area.width && y >= area.y && y <= area.y + area.height);if (clickedArea) {const center = getCenter(clickedArea);// 如果点击的是 area7 或 area8,开始绘制红线if (clickedArea.id === 'area7' || clickedArea.id === 'area8') {if(clickedArea.id === 'area7'){// 清除之前的所有红线lines.value = lines.value.filter(line => line.end.color !== 'red');// 开始绘制新的红线startPoint.value = { x: center.x, y: center.y, color: 'red' }; // 保存新的起点信息}else if(clickedArea.id === 'area8'){// 清除之前的所有红线lines.value = lines.value.filter(line => line.end.color !== 'black');// 开始绘制新的红线startPoint.value = { x: center.x, y: center.y, color: 'black' }; // 保存新的起点信息}isDrawing.value = true;}else if (startPoint.value && isDrawing.value) {// 检查目标区域的颜色是否与起点颜色一致if (startPoint.value.color === clickedArea.stroke) {// 如果颜色一致,连接新的红线lines.value.push({id:clickedArea.id,start: startPoint.value,end: { x: center.x, y: center.y, color: clickedArea.stroke },});// 完成绘制,清除起点startPoint.value = null;currentPoint.value = null;isDrawing.value = false;}else {// 如果颜色不一致,取消当前的绘制startPoint.value = null;currentPoint.value = null;isDrawing.value = false;}}if(lines.value[0]!=null && lines.value[1]!=null){if((lines.value[0].id=="area3" && lines.value[1].id=="area4") || (lines.value[0].id=="area4" && lines.value[1].id=="area3")){}else{}}}
};const handleMouseMove = (event: MouseEvent) => {if (isDrawing.value && startPoint.value) {// 更新实时坐标currentPoint.value = { x: event.offsetX, y: event.offsetY };}
};