严重拖延症,一方面这项目模块纯属个人娱乐。另一方面,流程图这块涉及的东西还是蛮多的,这次也只是介绍一些简单的部分。拖了这么久,现在终于要开始硬着头皮写一篇基于vue+svg的流程图"伪教程"文章了。初次献丑,还请轻喷。
模块简介
出于学习vue而非兼容的目的,本项目仅考虑现代浏览器( 谷歌 ),部分兼容问题还请见谅。
本模块的开发源于对流程图的简单需求( 纯UI实现,暂不存在业务逻辑 ),这里不赘诉vue-cli生成的目录结构(可以参考这篇或自行谷歌)。
项目实际用到的技术栈:SVG + vue + vuex
功能介绍:
- 画布缩放
- 节点( 开始,基础,判断等 )添加,删除
- 节点间连线( 直线/折线 )
- 文本添加
- 外部导入SVG图形
- 撤销与重做
画布缩放
考虑到画布缩放后布局需保持一致,这里通过修改transform: scale(); transform-origin: ;
来实现,节点则相对父层定位。
TODO: SVG最优缩放解决方案?
节点相关
下面我简单说一下思路:
由于不存在业务逻辑,我把流程图简化为 开始
基础
判断
3个基础组件( 基于SVG )。
如:
<template>
<!-- 开始 -->
<ellipse v-bind="style"></ellipse>
<!-- 基础 -->
<rect v-bind="style"></rect>
<!-- 判断 -->
<path v-bind="style"></path>
</template>复制代码
这里说一下判断这个组件( 后期可能出现复杂形状均以path实现 ),一般由AI软件直接导出相关形状。
左边工具栏跟画布中的相同图形源于同个组件,故设有两个样式,即 defaultStyle
和 drawStyle
。之前有考虑过,如果流程图的图形复杂多变的话,那这种模式岂不是每一个组件都得人为定义。同样,采用导入SVG也有类似问题。因为如果图形大小都不确定的话,除了支持图形修改大小,否者将导致画布出现大小不一的图形。( 非常遗憾这方面没有做出突破,不过这将成为未来改进的方向。)
最开始采用的解决方案是以scale的方式,也就是统一让工具栏中的图形跟拖入画布中的图形成等比缩放关系。不过该方式会造成stroke也同比缩放,并非我们想要的。
所以目前暂时采用写死的方式。
注意: 在svg中 ellipse
定位相对于中心点,而rect定位是相对于左上角。
TODO是否有办法将各组件定位源点设置为组件中心点。
节点渲染
节点渲染方面,由于之前是将图形作为组件,于是采用 component + is
的方式来渲染图形。同时也是以数据驱动的方式来渲染,即数据决定视图。
<component v-for=