具体代码参见:https://github.com/yyccmmkk/js-reference-line
【需求】
对一个元素进行拖拽时,生成这个组件和其它组件对齐的参考线,实现各组件间四条边及水平中心线及垂直中心线对齐。
【解决思路】
1 MAP记录所有需要对齐组件的视窗坐标点(左上,右上,左下,右下)
2 P为当前拖拽对象实时的坐标点(左上,左下,右上,右下,中心点)
3 拿当前对象的坐标点P去匹配座标记录MAP
4 发现某一边对齐时,在canvas中画线,清除画布的操作应该在拖动时进行处理,
问题的关键在于如何快速的去计算当前组件的6条线(四边+中心线)和其它所有组件6条线在一条线上,看似麻烦其实可以简化逻辑为,只要判断三个点,左上角、右下角、中心点,在记录中有没有存在
- 如何判断两个组件垂直对齐?答:坐标x一样
- 如何判断两个组件水平对齐?答:坐标Y一样
- 如何记录坐标点便于查询
- 根据坐标画线
【答:3】
创建一个数组 tempArry 存放所有的坐标对象(包含座标信息),像下边这样
let tempArray=[
{let:1,right:100,top:10,bottom:400},
{let:2,right:200,top:20,bottom:600},
{let:1,right:300,top:30,bottom:400}
];
创建两个对象mapX 、mapY。对tempArray 进行遍历,mapX mapY 分别以x ,y 为key。 值为数组(ps:因为有可能多个组件 坐标是相同的),数组保存了坐标对象在tempArray中的索引。
mapX 记录所有组件的坐标x,每个组件三个x坐标(ps:左、中、右),结果如下
let mapX={
1:[0,2],
2:[1],
50.5:[0],
101:[1],
150.5:[2],
100:[0],
200:[1],
300:[2]
};
mapY 记录所有组件的坐标y,每个组件有三个坐标y(ps:上、中、下),结果如下
let mapY={
10:[0],
205:[0],
310:[1],
215:[2],
20:[1],
30:[2],
400:[0,2],
600:[1],
}
假设有一组件视窗坐标为(left:1,right:600,top:20,bottom:300);
通过判断左上角坐标点(p1) 就可以检测组件左边与上边的对齐,通过右下角坐标点(p2),就可以检测组件 右边与下边的对齐,对过中心坐标(p3)就可以找到水平与垂直线的对齐。
p1 x:1,y:20
p2 x:600,y:300
p3 x:300.5,y:160
mapX 中存在以x 为值的key 就证明有垂直对齐的线,
mapY 中存在以 y为值 的key 就证明有水平对齐的线
通过map 中的值索引可以快速拿到对应的对齐组件信息,把当前组件的坐标点信息扔进去,取最大最小值就可以拿到对齐线的坐标信息,详见源码,大概思路是这样,其中还涉及一些细节,比如排自身的坐标信息等。