本文目录
本篇主要记录流程图的实现过程中的难点和核心技术点,先上效果图:
节点可以任意拖拽,曲线跟随变化
正在连接的线
1、节点实现
流程图是基于SVG绘制的,节点主要利用 g
和 foreignObject
的特性来实现:
<g class=\"pane-node\">
<foreignObject width=\"180\" height=\"50\">
<body xmlns=\"http://www.w3.org/1999/xhtml\">
<div class=\"pane-node-content\">
<span class=\"iconfont icon-datas\"></span>
<span class=\"name\" :title=\"item.name\">{{item.name}}</span>
<!-- 节点进 -->
<div class=\"pane-port-list in\">
......
</div>
<!-- 节点出 -->
<div class=\"pane-port-list out\">
......
</div>
</div>
</body>
</foreignObject>
</g>
- g元素:特性是可以包裹元素,并进行位置变化,这样拖拽的时候获取对应的坐标改变
transform
的值就可以整体移动了; - foreignObject标签:借助
<foreignObject>
标签,可以直接在SVG内部嵌入XHTML元素,尤其一些需要css进行控制的样式类,但是这个兼容性较差,主要是IE浏览器。
2、曲线的绘制
核心代码:
<g class=\"pane-link\">
<path class=\"connector-wrap\" :d=\"`M ${pos.startS} Q ${pos.curveS} T ${pos.endS}`\"></path>
<path
class=\"target-marker\"
d=\"M 5 0 L 0 3.6327126400268037 L 5 7.265425280053607 Z\"
:transform=\"`translate(${item.endPosX - 4},${item.endPosY + 4}) scale(1,1) rotate(-90)`\"
></path>
</g>
这里使用的是svg
中的path
中的M Q T
:
M
:moveto
这里是初始节点的底部连接点Q
:quadratic Bézier curve
二次贝塞尔曲线
【截图源于网络】T
:smooth quadratic Bézier curveto
二次贝塞尔曲线平滑延伸
【截图源于网络】
这里的
T
指的是通过一个控制点推断出一个新的控制点,T前面必须是一个Q命令或者是另一个T命令
由此可见,只要确认三个点(起点,控制点,终点),就可以绘制出平滑好看的曲线啦~
/**
* startPosX 起节点的左上角x
* endPosX 终节点的左上角x
* sizeX 节点的一半宽度 sizeY 是节点的高度
/
// 起始点
let startS = `${startPosX + sizeX} ${startPosY + sizeY}`;
// 二次贝尔曲线
let curveS = `${startPosX + sizeX} ${startPosY + sizeY + 40} ${
this.endNode
? (startPosX + endPosX+ 2 * sizeX) / 2
: (startPosX + endPosX+ sizeX) / 2
} ${(startPosY + endPosY + 20) / 2}`;
// 终点
let endS = `${this.endNode ? endPosX + sizeX : endPosX} ${endPosY}`;
至于节点的拖拽就比较简单了,点击移动的时候获取位置信息更transform
的translate
属性即可。