赞
踩
可视化编辑器已成为前端发展趋势,相关产品层出不穷,但是用户较难根据自身需求去完整实现一个功能较为全面的可视化编辑器,我将采用乐吾乐开源的meta2d.js可视化库来实现一个简单的流程图编辑器,通过这个案例来介绍meta2d的相关功能,并向读者展示如何用meta2d从零出发搭建一个较为完整的项目,让我们在实际项目中来体验meta2d的强大之处吧。
meta2d是乐吾乐开源的2D图元组成的可视化引擎,集实时数据展示、动态交互、数据管理等一体的全功能2D可视化引擎。能够快速实现数字孪生、大屏可视化、Web组态、SCADA等解决方案。具有实时监控、多样、变化、动态交互、高效、可扩展、支持自动算法、跨平台等特点,最大程度减少研发和运维的成本,并致力于普通业务人员 0 代码开发实现物联网、工业互联网、电力能源、水利工程、智慧农业、智慧医疗、智慧城市等可视化解决方案。
乐吾乐已将其meta2d核心库完全免费开源,本系列教程就是基于meta2d从零实现web端可视化流程图编辑器。
乐吾乐 meta2d开源项目地址:https://github.com/le5le-com/meta2d.js
乐吾乐 meta2d官方文档:https://doc.le5le.com/document/119359590
此可视化流程图编辑器项目地址:github.com/Grnetsky/me…
在线体验地址: http://editor.xroot.top/
contextxMenu用于右键菜单选项,可以为用户定制快捷功能。
本章我们来实现meta2d的contextMenu的功能,本项目的contextMenu主要是提供一些层级改变的功能和一些个人定制的扩展功能比如复制粘贴等。
对于图元层级的管理,meta2d提供了一系列的图层改变的API:
对于复制粘贴功能,meta2d提供了copy方法用于复制指定图元到缓存列表,paste方法用于粘贴复制的图元,我们可以使用ctrl+C和ctrl+V的快捷键方式来调用meta2d封装的复制粘贴功能。
接下来让我们看看contextMenu怎么实现吧
先给出总的代码:
<script setup> import {computed, onMounted, reactive, ref} from "vue"; import {useEventbus} from "../hooks/useEventbus.js"; let isPens = ref(false) let ctxMenu = ref() let activePens = [] // 设置contextmenu的初始坐标 let menuPos = reactive({ top:-9999, left:-9999, visible:false }) // contextmenu计算属性,用于将menupos数据加工后传入contextmenu的css样式 const calcMenuPos = computed(()=>{ return { top:menuPos.top+"px", left:menuPos.left+"px", visible:menuPos.visible?"visible":"hidden" } }) // 全局事件总线 const eventBus = useEventbus() // 监听meta2d的load事件,等待meta2d初始化完成 eventBus.customOn('load',()=>{ // 阻止系统默认菜单栏,并聚焦到我们的contextmenu组件 window.addEventListener('contextmenu',(e)=>{ e.preventDefault() ctxMenu.value.focus() }) // 监听meta2d的contextmenu事件,弹出contextmenu组件 meta2d.on('contextmenu',({e})=>{ menuPos.top = e.clientY menuPos.left = e.clientX menuPos.visible = true ctxMenu.value.focus() }) // 赋值activepens meta2d.on("active",(pens)=>{ console.log("active",pens) if(pens.length>0){ activePens = reactive(pens) console.log("activePEns",activePens) isPens.value = true }else { isPens.value = false activePens = [] } }) meta2d.on('inactive',()=>{ isPens.value = false }) }) // 调用meta2d相关API function changeCoverage(pos){ switch (pos){ case "top": meta2d.top(activePens) break case "bottom": meta2d.bottom(activePens) break case "up": meta2d.up(activePens) break case "down": meta2d.down(activePens) break } ctxMenu.value.blur() } function lock() { meta2d.lock(2) meta2d.emit('lock') ctxMenu.value.blur() } function paste() { meta2d.paste() ctxMenu.value.blur() } function copy() { meta2d.copy(activePens) ctxMenu.value.blur() } function ctxMenuClose() { menuPos.visible = false } </script> <template> <div class="contextmenu" ref="ctxMenu" tabindex="-1" @blur="ctxMenuClose"> <div class="ctx_item" v-show="isPens" @click="changeCoverage('top')">置顶</div> <div class="ctx_item" v-show="isPens" @click="changeCoverage('bottom')">置底</div> <div class="ctx_item" v-show="isPens" @click="changeCoverage('up')">上一图层</div> <div class="ctx_item" v-show="isPens" @click="changeCoverage('down')">下一图层</div> <div class="ctx_item" @click="lock">锁定</div> <div class="ctx_item" v-show="isPens" @click="copy">复制</div> <div class="ctx_item" @click="paste">粘贴</div> </div> </template> <style scoped> .contextmenu { padding: 6px; position: absolute; top: v-bind("calcMenuPos.top"); left:v-bind("calcMenuPos.left"); visibility: v-bind("calcMenuPos.visible"); background-color: #fff; max-height: 5000px; width: 180px; z-index: 999; border-radius: 10px; } .ctx_item{ width: 100%; padding: 10px; cursor: pointer; transition: background-color .5s ease; } .ctx_item:hover{ background-color: #eeeeee; } </style>
vue3支持通过v-bind在css中绑定变量了,我们利用这一点就很好实现我们想要的功能了。首先我们的contextMenu肯定要通过一个事件触发出来,meta2d提供了一个“contextmenu”的事件,用于监听在meta2d上触发单击鼠标右键的行为,另外,为了防止系统的contextMenu的弹出影响用户使用,我们需要先在系统的contextmenu事件中将其禁止掉,然后在其中调用我们自己的contextMenu组件出来,像下面这样:
window.addEventListener('contextmenu',(e)=>{
e.preventDefault() // 阻止系统菜单栏
ctxMenu.value.focus() // 聚焦我们的菜单栏,防止聚焦到了meta2d自身上而导致弹出失败
})
// meta2d的contextmen
meta2d.on('contextmenu',({e})=>{
// 设定
menuPos.top = e.clientY
menuPos.left = e.clientX
menuPos.visible = true
ctxMenu.value.focus()
})
需要注意的是,原生div的focus和blur事件并不生效,我们需要在其身上加入tabindex属性,其作用读者自行查看文档,我们需要给它加上tabindex属性,像这样:
<div class="contextmenu" ref="ctxMenu" tabindex="-1" @blur="ctxMenuClose">
...
</div>
然后通过active事件,拿到作用的图元对象,并在点击事件中执行相关API就好了,其他细枝末节相信读者都能很好看懂,直接来看最后效果吧。
功能实现成功,读者也可以去在线链接中体验。
本章我们较为简单的介绍了meta2d图层相关的API,然后介绍了contextMenu组件的实现,在此基础上定制了
我们自己的右击菜单的功能。读者可根据自己实际需求进行定制化设计,到此我们整个项目的主要功能就已经讲完了。
通过这么多章节的学习,我相信各位读者对meta2d有了基本的认识,由于全文篇幅有限,没办法将meta2d所有的功能一一介绍,更多奇妙的探索还需读者自行实践,虽然文章内容不多,但是足够支撑读者进行简单的定制化自己的可视化编辑器了,接下来让我们回顾下这个系列我们学到了些什么吧:
以上就是我们整个系列学习的全部内容了,如果你对meta2d的更多功能感兴趣,可自行前往官网阅读相关文档。如果你在开发中遇到了一些困难发现了一些bug欢迎与我交流,也可以在meta2d github上提出issue会有专业的人员解答,国产开源需要大家的支持。
感谢大家对本系列的关注与认可,我们未来再见。
有问题欢迎在评论区反馈,欢迎持续关注。
给大家推荐一下 Meta2d.js是一个实时数据响应和交互的2d引擎,可用于Web组态,物联网,数字孪生等场景。
Github:github.com/le5le-com/m…
Gitee: gitee.com/le5le/meta2…
如果本篇文章帮助到了你,欢迎为meta2d项目star点星。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。