共计 3303 个字符,预计需要花费 9 分钟才能阅读完成。
有时候须要在页面里绘画线条, 简单点的能够应用 canvas 去画, 简略点的能够间接应用 css 搞定, 通过:before 和:after 伪类实现。
成果如图:
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {background-color: black;}
.tree {display: flex;}
.line {
background-color: white;
position: relative;
}
.content {background-color: aqua;}
.content .box {text-align: center;}
</style>
</head>
<body>
<div class="tree">
<div class="line" id="tree-line">
</div>
<div class="content" id="tree-content">
</div>
</div>
<script>
// 元素信息
let elementInfo = {
total: 12,// 元素总量
perHeight: 30,// 每个元素高度
perWidth: 120,// 每个元素宽度
maxLevel: 5,// 最大层级
}
// 连接线信息
let lineInfo = {
perLevelWidth: 30,// 每一层宽度
size: 2,// 线宽 or 高
color: "black",// 线色彩
styleSheet: "",// 款式, 依据 drawLine 动态变化
}
let lineElement = document.getElementById("tree-line");// 线区
let contentElement = document.getElementById("tree-content");// 内容区
lineElement.style.width = `${elementInfo.maxLevel * lineInfo.perLevelWidth}px`;// 依据层级确定线条区域的宽度
// 初始化内容区数据
function drawData() {for (let i = 1; i <= elementInfo.total; i++) {let divEle = document.createElement("div");
divEle.className = "box";
divEle.innerText = `test-${i}`;
divEle.style.height = `${elementInfo.perHeight}px`;
divEle.style.lineHeight = `${elementInfo.perHeight}px`;
divEle.style.width = `${elementInfo.perWidth}px`;
contentElement.appendChild(divEle);
}
}
// 依据给定参数绘出连接线
function drawLine(rowStart, rowEnd, level) {if (rowStart < 1) return;
if (rowEnd > elementInfo.total) return;
if(level < 1 || level > elementInfo.maxLevel) return;
let lineVerticalEle = document.createElement("div");
let lineHorizontalEle = document.createElement("div");
let lineVerticalClassName = `line${rowStart}-${rowEnd}-vertical`;
let lineHorizontalClassName = `line${rowStart}-${rowEnd}-horizontal`;
lineVerticalEle.className = lineVerticalClassName;
lineHorizontalEle.className = lineHorizontalClassName;
let tempStyle = `
.${lineVerticalClassName}::after {
display: block;
content: "";
position: absolute;
background-color: ${lineInfo.color};
width: ${lineInfo.size}px;
height: ${(rowEnd - rowStart) * elementInfo.perHeight}px;
top: ${(rowStart - 1) * elementInfo.perHeight + elementInfo.perHeight / 2}px;
left: ${(level - 1) * lineInfo.perLevelWidth + lineInfo.perLevelWidth / 2}px;
}
.${lineHorizontalClassName}::before {
display: block;
content: "";
position: absolute;
background-color:${lineInfo.color};
height: ${lineInfo.size}px;
width: ${(elementInfo.maxLevel - level) * lineInfo.perLevelWidth + lineInfo.perLevelWidth / 2}px;
top: ${(rowStart - 1) * elementInfo.perHeight + elementInfo.perHeight / 2}px;
left: ${(level - 1) * lineInfo.perLevelWidth + lineInfo.perLevelWidth / 2}px;
}
.${lineHorizontalClassName}::after {
display: block;
content: "";
position: absolute;
background-color: ${lineInfo.color};
height:${lineInfo.size}px;
width: ${(elementInfo.maxLevel - level) * lineInfo.perLevelWidth + lineInfo.perLevelWidth / 2}px;
top: ${(rowEnd - 1) * elementInfo.perHeight + elementInfo.perHeight / 2}px;
left:${(level - 1) * lineInfo.perLevelWidth + lineInfo.perLevelWidth / 2}px;
}
`
lineInfo.styleSheet += tempStyle + "\n";
lineElement.appendChild(lineVerticalEle);
lineElement.appendChild(lineHorizontalEle);
}
drawData();
drawLine(1, 12, 1);
drawLine(6, 9, 2);
drawLine(10, 11, 2);
let head = document.head || document.getElementsByTagName('head')[0];
let lineStyle = document.createElement('style');
lineStyle.type = 'text/css';
lineStyle.innerHTML = lineInfo.styleSheet;
head.appendChild(lineStyle);// 增加线条款式
</script>
</body>
</html>
正文完