用svg做一个简单的画板编辑器,实现图形自动创建,拖动,多选,单选,画框,连线,数据绑定,保存,修改等功能,如图:
主要讲下几个关键的点;
1、关于左侧菜单栏拖动图形到画板上自动生成相应的图形主要是这个组件“Ext.dd.DropTarget”,如:
Ext.create('Ext.dd.DropTarget', body, {
ddGroup: 'model-to-canvas',
notifyEnter: function (ddSource, e, data) {
//Add some flare to invite drop.
},
notifyDrop: function (ddSource, e, data) {
//dosomething
}
});
2、画板图形的分类:
主要有三类有效图形,无效图形及工具图形,以id为key通过对象方式进行存储,方便后续的拖动,连线,删除等操作
//有效图形
me.validGraphs = {};
//无效图形
me.invalidGraphs = {};
//工具图形
me.tools = {};
//选择框内图形
me.selectGraphs = {};
3、如何框中选中的图形:
根据中心点原理,手动画出的边框,计算四个角的坐标,然后遍历有效图形,在有效图形中若中心点再边框内,则认为选中,效果如图
4、图形连线
双击图形,获取鼠标点击的当前图形,自动生成一根箭头,此时如果再点击空白画板,则默认该点击点为直线的折点,点击下一个图形时自动连接完成如图:
至于如何判断从哪个角度进行连接,我是通过向量的方式,因为画板坐标是知道的,以其中一个图形中心为坐标原点,根据向量基本定理计算,代码如下:
getPoint: function (x1, y1, x2, y2, w1, h1) {
var point = {};
var sMinX = (x1 - w1 / 2);
var sMinY = (y1 - h1 / 2);
var sMaxX = (x1 + w1 / 2);
var sMaxY = (y1 + h1 / 2);
if (x2 <= x1 && y2 < y1) {//第一向限
var sX = calculation_getX(sMinY);
if (sX >= sMinX) {
point = {pointX: sX, pointY: sMinY};
} else {
point = {pointX: sMinX, pointY: calculation_getY(sMinX)};
}
} else if (x2 > x1 && y2 <= y1) {//第二向限
var sX = calculation_getX(sMinY);
if (sX <= sMaxX) {
point = {pointX: sX, pointY: sMinY};
} else {
point = {pointX: sMaxX, pointY: calculation_getY(sMaxX)};
}
} else if (x2 < x1 && y2 >= y1) {//第三向限
var sX = calculation_getX(sMaxY);
if (sX >= sMinX) {
point = {pointX: sX, pointY: sMaxY};
} else {
point = {pointX: sMinX, pointY: calculation_getY(sMinX)};
}
} else if (x2 >= x1 && y2 > y1) {//第四向限
var sX = calculation_getX(sMaxY);
if (sX <= sMaxX) {
point = {pointX: sX, pointY: sMaxY};
} else {
point = {pointX: sMaxX, pointY: calculation_getY(sMaxX)};
}
}
function calculation_getX(y) {
if (y2 != y1) {
return (y - y1) * (x2 - x1) / (y2 - y1) + x1;
} else {
return x2;
}
}
function calculation_getY(x) {
if (x2 != x1) {
return (x - x1) * (y2 - y1) / (x2 - x1) + y1;
} else {
return y2;
}
}
return point;
},
ps:这是初期做法,可以再进一步优化;
大概就讲这些吧
欢迎加群611981770