这周后端与核心对组件的框架进行了初步讨论。
后端与核心的大致连接流程
从组建个体与组件层级讨论了一些共用方法
组件个体方面
public:
createElement();//创建组件
deleteElement();//删除组件
moveElement();//移动组件
moveCorePoint();//移动组件的单个关键点
deleteCorePoint();//删除关键点
addCorePoint();//增加关键点。
scaleElement();//改变组件大小
getCorePoint();//获取关键点
changeElementAttributes();//改变组价的某些属性
组件层级方面
public:
domOrderToFirst();//将组件dom顺序置为第一个
domOrderToLast();//组件dom顺序变为最后一个
groupElements();//将组件合并
unGroupElements();//拆分合并的组件
具体的初步实现思想
以树存储结构 root深度为0
叶子节点是单个正常组件,非叶子节点是合并以后产生的轮廓组件,父子关系是包含的
只有叶子节点具有正常的组件属性,其余均是只有轮廓的矩阵,没有属性,不能被点击,只有内部的叶子节点可以被点击
点击一次是叶子节点最外层分组,两次则选中叶子节点。即只有深度为1的分组,或者叶子节点的组件可以被选中和操作
后端所有变化均只考虑叶子节点的变化,分组的边框可以由叶子节点计算而来。
所有组件呈现树形。root是svg,其余是<g>
f[]父节点,child[]子节点,dep[]节点深度。
图中只显示深度为1的分组,和叶子节点。其余分组并不显示。
在删除、创建过程中保证叶子节点是组件而不是分组,非叶子节点至少有两个子节点,即分组合法。
root不在判断范围。
public:
createElement(int shapeId){
shapeId:组件类型
将新组件掺入树中
f[newElement]=root;
child[root].push_back(newElement);
dep[newElement]=1;
}
;//创建组件
deleteElement(elementId){
删除elementId为根的子树中所有节点。
child[f[elementId]].remove(elementId);
dfs(elementId);//删除所有子节点
dfs(int x){
for(son:child[x]){
dfs(son);
}
delete(x);
}
1.
elementId被删除后。
若elementId的父节点的子节点数是1,则找到该子节点son,
将son上移至节点Y的子节点,Y加上son至少有两个子节点,中间节点均删除。
while(child[f[son]].size()<2){
fs=f[son];
child[f[fs]].remove(fs);
chils[f[fs]].push_back(son);
f[son]=f[fs];
son=fs;
f[fs]=null;
}
dep[son]=dep[Y]+1;
}
;//删除组件
moveElement(elementId,dx,dy){
祖先节点矩阵边框也要变大或减小(前端传递)
for(elementId为根的子树中所有节点son){
for(组件son的所有关键点p){
p.x+=x;
p.y+=y;
}
for(son的外围矩阵的点p){
p.x+=x;
p.y+=y;
}
}
}
;//移动组件
关键点变化可能会涉及到分组矩阵的变化,均从前端获取。
moveCorePoint(elementId,coreId,dx,dy){
p为coreId对应的点
p.x+=dx;
p.y+=dy;
};//移动组件的单个关键点
deleteCorePoint(elementId,coreId){
从elementId的关键点组删去即可
同时关键点数目coreSize-1;方便前端获取
};//删除关键点
addCorePoint(elementId,coreX,coreY,P){
在P点之后加上关键点Q(coreX,coreY)
Q.next=P.nxet;
p.next=Q;
coreSize+1;
};//增加关键点。
scaleElement(elementId){
祖先节点矩阵边框也要变大或减小(前端传递)
将elementId子树内所有叶子节点都做出同样的变化。
for(elementId子树内所有叶子节点son){
sonx,sony按照比例得到
计算son与elementId最近边的距离以及哪条边{
}
son与elementId的最近边距离不变
然后产生其余各点
}
};//改变组件大小
getCorePoint();//获取关键点
changeElementAttributes(){
只有叶子节点有属性
}
;//改变组件的某些属性
组件层级方面的实现
public:
domOrderToFirst(elementId){
后端的组件顺序与dom顺序一致
将elementId变为所有组件的第一个
};//将组件dom顺序置为第一个
domOrderToLast(elementId){
后端的组件顺序与dom顺序一致
将elementId变为所有组件的最后一个
};//组件dom顺序变为最后一个
groupElements(ele[]){
组件合并以后产生一个新的矩阵组件F,内部组件为其子组件。
后端并记录父子关系,很容易知道被选中的都是深度为1的分组或组件。
f[F]=root;
dep[F]=1;
child[f[F]].push_back(F);
for(val:ele){
child[f[val]].remove(val);
f[val] = F;
dep[val]=2;
child[F].push_back(val);
}
F边框矩阵数据从前端获取
子组件的属性并无变化。
dom顺序是否变化未定,drawio变化顺序有些奇怪,不变好像也可以
};//将组件合并
unGroupElements(){
根据选中的组件x,将x的子组件分离,并销毁x,子组件向上升一级
获取x子节点中分组的矩阵数据。
for(x的所有子节点son){
f[son]=f[x];
child[f[x]].push_back(son);
dep[son]=1;
}
child[f[x]].remove(x);
delete(x);
若有分组深度变为1,则从前端获取分组矩阵数据
}//拆分合并的组件