前言
最近在开发一个低代码平台,目的是希望通过拖拽布局的方式,快速生成那些简单的信息展示类、营销类页面。其中组件的拖拽和缩放使用的是 react-rnd,但是它没有提供辅助线功能,于是乎自己封装了一下。
效果如下图:
思路
1: 辅助线放在哪?
刚开始的想法是渲染到当前拖拽元素内部,相对于当前元素进行定位。但后来发现,各个组件的层级不一定相同的,这会造成层级高的会把辅助线遮住了。于是最后使用 createPortal()
把辅助线渲染到body上面,这就解决了层级问题
2:辅助线有几条?
如图,辅助线最多同时存在6条。
3:辅助线长度怎么计算?
以左边的辅助线为例,大概会出现图下几种情况,简单来说就是重叠和不重叠的情况,观察这几种情况,可以得出计算方法就是,拿到所有x坐标相同的元素的左上角和左下角坐标,然后拿最大的y坐标减去最小y坐标。
简单来说就是:长度 = 最大的y – 最小的y。
4:辅助线坐标如何计算?
如图,无论当前拖拽的是元素A,或元素B,或元素C,显示的辅助线坐标,长度都会是一致的,也就是图里蓝色的那条。
所以这里有两个方法:
方法1:获取所有x坐标和当前拖拽元素x相同的元素,找到y最小的那个坐标,得到(x1,y1).
方法2:以当前拖拽的元素坐上角为起点,计算向上的偏移量,如拖拽B时,以(x2,y2)为起点,然后向上偏移y2-y1的距离,也同样得到辅助线坐标为(x1,y1)。
不过这里要注意,辅助线是以相对于body定位的,所以上面计算元素的坐标也是要相对于body的坐标。
5:什么时候显示辅助线,以及如何吸附?
这两个的逻辑相似,就是在拖拽时不停地计算当前拖拽元素的坐标和其他元素的坐标,当小于某个阀值的时候,显示辅助线,吸附的话就是改变当前元素的坐标就可以.
代码
代码虽然不多,但加起来也有几百行,就不贴出来了,有兴趣的可以去 github 看下,顺便求个star。?
总结
总的来说,比较麻烦的地方在于需要处理显示的情况和坐标计算的地方蛮多的。
目前这个组件我命名为 react-rnd-dragline 。已发布到 npm 和 github。这个组件是根据自己的业务需求封装的,所以可能没有封装得很通用,后续有需要,有时间再改进一下。
最后求个star。?