Vue3+TypeScript对于SVG的使用

news/2024/11/18 12:49:50/

 效果图如下

 

代码解释 

        <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 };}
};

 


http://www.ppmy.cn/news/1547985.html

相关文章

Java基础——多线程

1. 线程 是一个程序内部的一条执行流程程序中如果只有一条执行流程&#xff0c;那这个程序就是单线程的程序 2. 多线程 指从软硬件上实现的多条执行流程的技术&#xff08;多条线程由CPU负责调度执行&#xff09; 2.1. 如何创建多条线程 Java通过java.lang.Thread类的对象…

报错 No available slot found for the embedding model

报错内容 Server error: 503 - [address0.0.0.0:12781, pid304366] No available slot found for the embedding model. We recommend to launch the embedding model first, and then launch the LLM models. 目前GPU占用情况如下 解决办法: 关闭大模型, 先把 embedding mode…

Node.js 版本管理的最终答案 Volta

文章目录 特点安装Unix系统安装Windows系统安装 常用命令volta fetchvolta installvolta uninstallvolta pinvolta listvolta completionsvolta whichvolta setupvolta runvolta help 建议 目前对于前端项目的node 版本&#xff0c;我们一般会在项目 package.json 的 engines 字…

React--》如何高效管理前端环境变量:开发与生产环境配置详解

在前端开发中&#xff0c;如何让项目在不同环境下表现得更为灵活与高效&#xff0c;是每个开发者必须面对的挑战&#xff0c;从开发阶段的调试到生产环境的优化&#xff0c;环境变量配置无疑是其中的关键。 env配置文件&#xff1a;通常用于管理项目的环境变量&#xff0c;环境…

高级 SQL 技巧讲解

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; SQL&#xff08;结构化查询语言&#xff09;是管理和操作数据库的核心工具。从基本的查询语句到复杂的数据处理&#xff0c;掌握高级 SQL 技巧不仅能显著提高数据分析的效率&#xff0c;还能解决业务中的复…

基于Java Springboot二手家电管理平台

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

React Native 全栈开发实战班 -原生功能集成之相机与图片

在移动应用中&#xff0c;相机功能 和 图片选择 是非常常见的需求&#xff0c;用户可以通过相机拍照或从相册中选择图片。React Native 提供了多种方式来实现相机和图片选择功能&#xff0c;包括使用第三方库&#xff08;如 react-native-image-picker&#xff09;和调用原生模…

STM32设计学生宿舍监测控制系统

目录 前言 一、本设计主要实现哪些很“开门”功能&#xff1f; 二、电路设计原理图 电路图采用Altium Designer进行设计&#xff1a; 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 随着科技的飞速发展和智能化时代的到来&#xff0c;学生宿舍的安全、舒适…