用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