JointJS是以SVG为基础,依赖Backbone、jQuery和Lodash开发的一款实现流程图绘制的开源前端框架,属于比较冷门的技术,网上文档甚少,基本上只能靠英文官网学习,以下是某大神汇总的部分知识点值得推荐:JointJS官方API的个人整理,望大家学习路上不要太辛苦。
我在项目开发时部分功能是参照官网的这个demo去做,demo是依赖Rappid开发的,Rappid是JointJS的一个付费版本,提供了更强大的功能,也很实用,但是付费,所以项目上没法使用,为了实现出与demo相近的功能下了一番苦功终于有些成果,在此分享两个功能的具体实现。
一、画布拖拽及缩放
1.画布拖拽
画布拖拽其实更多的是依赖jQuery对DOM的基础操作,这也是我在研究demo实现拖拽时发现的。先看下我的HTML标签结构:
<!-- 展现窗口 -->
<div id="wrap">
<!-- 画板 -->
<div>
<!-- 画布 -->
<div id="paper"></div>
</div>
</div>
来看一张图片
上图中的灰色区域是画板区域,也可以被去掉,只不过有这么一块区域存在后当画布拖动到边缘时会使画布和窗口之间存在距离而不是紧贴在一起,这样的视觉感受会更好一些。当鼠标在画布上点击不放开始进行拖拽时,其实就是鼠标在窗口中移动,通过mousemove事件的来修改窗口的scrollLeft和scrollTop在视觉上让人感觉是拖着画布在移动,但其实代码主要去控制的是窗口而非画布或者画板,明白了这个原理之后再来看下代码。
const [$WRAP, $PAPER] = [$(WRAP_DIV), $('#paper')];
const JOINT_GRAPH = new joint.dia.Graph();
const JOINT_PAPER = new joint.dia.Paper({
el: $PAPER.get(0),
model: JOINT_GRAPH,
width: 3000,
height: 3000,
gridSize: 10, //栅格点间距,元素拖动会捕捉栅格点
drawGrid: {
name: 'doubleMesh',
args: [
{
color: '#dedede', //栅格点颜色
scaleFactor: 1,
thickness: 1 //栅格点大小
},
{
color: '#dedede', //栅格点颜色
scaleFactor: 10,
thickness: 2 //栅格点大小
}
]
},
background: {
color: '#fff'
},
snapLinks: true,
restrictTranslate: true //设定元素不能拖出画布
});
以上是初始化一个绘制区域的代码,比较基础了,官网上都有,不明白的去官网或者前面推荐的博文里看,这里就不普及基础知识了,直接看以下部分:
let [_x, _y] = [0, 0];
//这里的on方法是JointJS中绑定事件的方法
JOINT_PAPER.on('blank:pointerdown', (evt, x, y) => {
[_x, _y] = [evt.offsetX, evt.offsetY];
$PAPER.css('cursor', 'grabbing');
//这里的on方法是jQuery中绑定事件的方法
$WRAP.on