连接两个 div ,其实是在每个 div 中选取一个点,将所选取的两个点进行连接。
结合上面斜线的样式实现方案,我们可以将连接两个 div 的问题进一步分解为:
(1)从两个 div 中分别选取一个点作为连接点,并计算出两个连接点的
坐标
;
(2)通过两个点的坐标,计算出斜线样式所需的
width
、
top
、
left
、
transform: rotate
的数值,也就是连接线的
长度
、
位置
与
旋转弧度
;
(3)动态创建连接线 DOM ,设置其样式,添加到页面中。
2.3 连接点的坐标计算
从 div 中选取连接点,通常可以选取 div
元素块的中心点
、或
某一条边框的中心点
、或
某一个顶点
,根据自身的审美选择即可。
通过 div 元素在浏览器可见区域的 top 、 left 值,以及其自身宽高,可以计算出两个点在浏览器可见区域中的坐标,如计算元素块的中心点坐标:
var obj = document.getElementById('divID')
var x = obj.getBoundingClientRect().left + obj.clientWidth / 2
var y = obj.getBoundingClientRect().top + obj.clientHeight / 2
2.4 连接线的长度计算
有了两个连接点的坐标后,我们可以通过勾股定理,计算出连接线的长度:
var length = Math.sqrt((x2 -x1) * (x2 -x1) + (y2 -y1) * (y2 -y1))
注:图中的坐标系并非数学意义上严格的直角坐标系,而是按照网页样式布局的习惯所画的示意图,其 y 轴负方向(向下方向)为正值。
2.5 连接线的旋转弧度计算
Math.atan2(y, x)
方法可以计算二维坐标系中任意一个点 (x, y) 和 原点 (0, 0) 的连线与 x 轴正半轴的夹角大小(弧度值)。
将连接线平移,使其原 (x1, y1) 点与远点 (0, 0) 重合,则原 (x2, y2) 点移动至 (x2 -x1, y2 -y1) ,套用 Math.atan2(y, x)
即可计算出连接线的旋转弧度:
var rad = Math.atan2((y2 -y1), (x2 -x1))
2.6 连接线的位置计算
连接线的位置,指的是连接线在未做旋转前(旋转是按照元素的中心点进行旋转),其左上顶点的坐标,计算如下:
var top = (y1 + y2) / 2
var left = (x1 + x2) / 2 - length / 2
2.7 创建连接线 DOM
斜线样式所需的所有属性值都计算完毕,最后创建 DOM ,为其设置行内样式,再将 DOM 添加到页面中即可:
var line = document.createElement('div')
var style = 'position: absolute; background-color: #333333; height: 1px; top:' + top +
'px; left:' + left + 'px; width: ' + length + 'px; transform: rotate(' + rad + 'rad);'
line.setAttribute('style', style)
document.body.appendChild(line)
3 完整代码样例
最后给出完整的样例代码,连接了 5 个圆形的中心点绘制出一个五角星:
<!DOCTYPE html>
<html lang="">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
</head>
<div id="e1" class="element element_1"></div>
<div id="e2" class="element element_2"></div>
<div id="e3" class="element element_3"></div>
<div id="e4" class="element element_4"></div>
<div id="e5" class="element element_5"></div>
</body>
</html>
<style type="text/css">
.element { position: absolute; width: 50px; height: 50px; border-radius: 25px; background-color: yellow; }
.element_1 { top: 100px; left: 175px; }
.element_2 { top: 175px; left: 75px; }
.element_3 { top: 175px; left: 275px; }
.element_4 { top: 300px; left: 100px; }
.element_5 { top: 300px; left: 250px; }
</style>
<script type="text/javascript">
function drawLine (obj1, obj2) {
var x1 = obj1.getBoundingClientRect().left + obj1.clientWidth / 2
var y1 = obj1.getBoundingClientRect().top + obj1.clientHeight / 2
var x2 = obj2.getBoundingClientRect().left + obj2.clientWidth / 2
var y2 = obj2.getBoundingClientRect().top + obj2.clientHeight / 2
var length = Math.sqrt((x2 -x1) * (x2 -x1) + (y2 -y1) * (y2 -y1))
var rad = Math.atan2((y2 -y1), (x2 -x1))
var top = (y1 + y2) / 2
var left = (x1 + x2) / 2 - length / 2
var line = document.createElement('div')
var style = 'position: absolute; background-color: red; height: 1px; top:' +
top + 'px; left:' + left + 'px; width: ' + length + 'px; transform: rotate(' + rad + 'rad);'
line.setAttribute('style', style)
document.body.appendChild(line)
drawLine(document.getElementById('e1'), document.getElementById('e4'))
drawLine(document.getElementById('e1'), document.getElementById('e5'))
drawLine(document.getElementById('e2'), document.getElementById('e3'))
drawLine(document.getElementById('e2'), document.getElementById('e5'))
drawLine(document.getElementById('e3'), document.getElementById('e4'))
</script>
Java 全栈小工
粉丝