乐趣区

关于html:Html使用纯css画线

有时候须要在页面里绘画线条, 简单点的能够应用 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>
退出移动版