VUE怎么使用canvas绘制管线管廊 您所在的位置:网站首页 canvas中绘制图片的方法 VUE怎么使用canvas绘制管线管廊

VUE怎么使用canvas绘制管线管廊

2023-05-06 07:52| 来源: 网络整理| 查看: 265

VUE怎么使用canvas绘制管线管廊 发布时间:2023-04-27 14:27:50 来源:亿速云 阅读:53 作者:iii 栏目:开发技术

这篇文章主要介绍了VUE怎么使用canvas绘制管线管廊的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇VUE怎么使用canvas绘制管线管廊文章都会有所收获,下面我们一起来看看吧。

首先,我在JS中定义了一下常量,其作用如下:

let canvas = {}, ctx = {}; const image = new Image(); // 定义管线默认宽度 const PIPELINE_NUMBER = 15; // 定义图标默认缩放比例 const ICON_SCALE_RATIO = 25; // 所有绘制元素 let allElementCollection = []; // 初始化管线水类型: 0为冷水 1为热水 let pipeline_water_type = 0; // 当前绘制设备的对象 let equipment_select = {}; // 是否显示设备绘制的范围 let equipment_area_show = false // 初始化绘制类型:0为管线 1为设备,2为文字框 默认为管线 let draw_element_type = 0; // 管线流动速度初始值 let pipeline_offset = 0; // 定义当前选中的已绘制元素 let current_select_element_index = {};

接下来是处理鼠标左键在按下后,在上节的代码中,针对于鼠标左键按下后,需要判断当前点击的区域是否已经存在绘制的内容,如果有,执行绘制内容移动,如果没有,则开始新建绘制内容,代码如下:

if (shape) {     moveAllElement(e, clickX, clickY, rect, shape);     canvas.style.cursor= "move"; } else {     if (e.buttons === 1) {         draw_element_type === 0 ? drawRealTimePipeline(e, clickX, clickY, rect) : (draw_element_type === 1 ? drawRealTimeEquipment(e, clickX, clickY, rect) : drawRealTimeText(e, clickX, clickY, rect))     } }

我们一个一个的来,如果绘制内容不存在,则执行新建绘制内容,这里我使用三目运算来判断当前需要绘制的类型drawRealTimePipeline、drawRealTimeEquipment、drawRealTimeText。

drawRealTimePipeline:绘制实时管线// 绘制实时管线 const drawRealTimePipeline = (e, clickX, clickY, rect) => {     const shape = new ElementFactory(clickX, clickY);     shape.endX = clickX;     shape.endY = clickY;     // 绘制管线时,删除通过 new 的对象的 textInfo 和 equipmentInfo,这两个对于管线来说没有用处     delete shape.textInfo;     delete shape.equipmentInfo;     let shapeWidth = 0, shapeHeight = 0;     // 为了方便处理元素删除,动态添加一个随机的 ID,并且在当前位置拿到,方便在绘制线段过短时来精确删除     let current_uid = setuid(shape);     allElementCollection.push(shape);     window.onmousemove = (evt) => {         ctx.clearRect(0, 0, canvas.width, canvas.height);         shapeWidth = (evt.clientX - rect.left) - clickX;         shapeHeight = (evt.clientY - rect.top) - clickY;         // 判断绘制为 竖线 还是 横线         let shapeDirection = Math.abs(shapeWidth) >= Math.abs(shapeHeight);         if (shapeDirection) {             // 如果是横线,则 endY 为固定值             shape.endX = evt.clientX - rect.left;             shape.endY = clickY + PIPELINE_NUMBER;         } else {             // 如果是竖线,则 endX 为固定值             shape.endX = clickX + PIPELINE_NUMBER;             shape.endY = evt.clientY - rect.top;         }         shape.pipelineInfo.direction = shapeDirection;         shape.pipelineInfo.waterType = pipeline_water_type;         draw();     };     // 画线时,鼠标抬起判断如果线段绘制过短,则不推入 allElementCollection     window.onmouseup = () => {         if(parseInt(draw_element_type) === 0 && shape.endX) {             if (Math.abs(shape.startX - shape.endX)  {     // 生成唯一ID     let uid = Math.round( Math.random() * 100000000000);     shape.uid = uid;     return uid }drawRealTimeEquipment:绘制实时设备:

绘制设备时,由于绘制的图片,所以对于构造函数中的endX、endY需要自己计算

VUE怎么使用canvas绘制管线管廊

// 绘制实时设备 const drawRealTimeEquipment = (e, clickX, clickY, rect) => {     const shape = new ElementFactory(clickX, clickY)     // 绘制设备时,删除通过 new 的对象的 textInfo 和 pipelineInfo,这两个对于图形来说没有用处     delete shape.textInfo;     delete shape.pipelineInfo;     // 设备绘制在鼠标点击的那一刻就需要开始创建,     setEquipment(e);     setuid(shape);     allElementCollection.push(shape);     window.onmousemove = (evt) => setEquipment(evt);     function setEquipment(evt) {         ctx.clearRect(0, 0, canvas.width, canvas.height);         shape.startX = evt.clientX - rect.left;         shape.startY = evt.clientY - rect.top;         // 计算当前绘制的endX endY         image.src = require(`../assets/images/${equipment_select.iconPath}`);         let icon_width = Math.ceil(image.width / ICON_SCALE_RATIO),             icon_height = Math.ceil(image.height / ICON_SCALE_RATIO);         shape.endX = evt.clientX - rect.left + icon_width;         shape.endY = evt.clientY - rect.top + icon_height;         draw();     }     draw(); };drawRealTimeText:绘制实时文本:// 绘制实时文字 const drawRealTimeText = (e, clickX, clickY, rect) => {     const shape = new ElementFactory(clickX, clickY);     setuid(shape);     // 绘制文字时,删除通过 new 的对象的 equipmentInfo 和 pipelineInfo,这两个对于图形来说没有用处     delete shape.equipmentInfo;     delete shape.pipelineInfo;     ctx.font = `normal normal normal ${shape.textInfo.fontSize + 'px' || '16px'} Microsoft YaHei`;     const defaultText = '默认文字,请右键修改';     const measureText = ctx.measureText(defaultText);     const textW = measureText.width,         textH = measureText.actualBoundingBoxAscent + measureText.actualBoundingBoxDescent;     shape.textInfo.text = defaultText;     allElementCollection.push(shape);     setText(e)     window.onmousemove = (evt) => setText(evt)     function setText(evt) {         ctx.clearRect(0, 0, canvas.width, canvas.height)         shape.startX = evt.clientX - rect.left;         shape.startY = evt.clientY - rect.top;         shape.endX = evt.clientX - rect.left + textW;         shape.endY = evt.clientY - rect.top - textH;         draw();     }     draw(); };

接下来是鼠标点的位置,已经存在了绘制的内容,那么这个时候就有两种情况了,一个是 鼠标左键 点击的,一个是 鼠标右键 点击的。

鼠标左键点击只能执行移动,鼠标右键则是弹出操作框,如图:

VUE怎么使用canvas绘制管线管廊

这里有一点需要注意,管线的操作框中没有 编辑 按钮,且弹出框的位置需要根据鼠标点击的位置变化而变化。

moveAllElement:元素移动事件:// 元素移动 const moveAllElement = (e, clickX, clickY, rect, shape) => {     const { startX, startY, endX, endY } = shape;     let tipX = 0, tipY = 0;     // 鼠标左键:拖动位置     if (e.buttons === 1) {         window.onmousemove = (evt) => {             removeEditTip();             ctx.clearRect(0, 0, canvas.width, canvas.height);             const distanceX = evt.clientX - rect.left - clickX;             const distanceY = evt.clientY - rect.top - clickY;             shape.startX = startX + distanceX;             shape.startY = startY + distanceY;             shape.endX = endX + distanceX;             shape.endY = endY + distanceY;             draw();         }     }     // 鼠标右键:执行信息编辑     if (e.buttons === 2) {         if (shape.type === 0) {             // 管线             tipX = e.clientX;             tipY = e.clientY + 10;         } else if (shape.type === 1) {             // 如果点击的是图标,弹出提示出现在图标下方             tipX = (shape.endX - shape.startX) / 2 + shape.startX + rect.left             tipY = shape.endY + rect.top         } else if (shape.type === 2) {             // 文字             tipX = shape.startX + rect.left + ctx.measureText(`${shape.textInfo.text}`).width / 2;             tipY = shape.startY + rect.top;         }         createEditTip(tipX, tipY, shape);         return false     } };

createEditTip为动态创建的DOM结构,即操作提示框。

createEditTip、removeEditTip:动态创建及移除DOM操作提示框:// 创建管线点击事件弹窗 const createEditTip = (x, y, shape) => {     let width = shape.type ? 180 : 120, marginLeft = shape.type ? 95 : 65, display = shape.type ? 'inline-block' : 'none'     removeEditTip()     let tipText = document.createElement('div')     tipText.classList.add('tip-text-content')     tipText.innerHTML = `                             

                                删除                                 编辑                                 取消                             

                         `     document.body.appendChild(tipText)     document.getElementById('equipmentDelete').onclick = () => {         allElementCollection.splice(current_select_element_index, 1)         ctx.clearRect(0, 0, canvas.width, canvas.height)         draw()         removeEditTip()     };     // 判断点击的是 图片 的编辑按钮,还是 文字 的编辑按钮     let modifyButton = document.getElementById('equipmentModify') ? 'equipmentModify' : 'textModify';     document.getElementById(modifyButton).onclick = () => {         removeEditTip()     };     document.getElementById('buttonCancel').onclick = () => {         removeEditTip()     }; }; // 移除管线事件弹窗 const removeEditTip = () => {     const popup = document.querySelector('.tip-text-content')     if (popup) document.body.removeChild(popup) }

关于“VUE怎么使用canvas绘制管线管廊”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“VUE怎么使用canvas绘制管线管廊”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。

推荐阅读: vue跳转页面使用的标签是什么 如何使用vue实现双向绑定

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:[email protected]进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

vue canvas 上一篇新闻:elmentUI组件中el-date-picker怎么限制时间范围精确到小时 下一篇新闻:python中threading模块怎么使用 猜你喜欢 vue如何实现密码显示隐藏功能 nodejs环境怎么快速操作mysql数据库 Nginx如何开启gzip配置 Java中如何使用Jackson python中np.multiply()、np.dot()和星号(*)三种乘法运算的区别有哪些 NumPy如何实现矩阵乘法 python如何使用Scrapy爬取网易新闻 Opencv图像处理中如何使用mask node中如何使用shell脚本 使用JSON.stringify时遇到的循环引用问题怎么解决


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有