leader-line划线,z-index较高的问题?调用position()后,失去圆角的问题?

作者站长头像
站长
· 阅读数 41

页面采用flex上下布局, 上面高度固定,下面通过 flex: 1; 自动撑开, 然后 overflow-y: auto; 超出显示滚动条;

需要通过 leader-line 划线的内容主要在下面部分, 所以滚动后需要通过 position() 来更新线条位置,现在遇到如下问题:

  1. 滚动到最下面,划线会覆盖在上面的内容;
  2. 滚动页面后,折线grid的圆角就失效了,该如何处理呢?

问题一:leader-line划线,z-index较高的问题?调用position()后,失去圆角的问题?

问题二:leader-line划线,z-index较高的问题?调用position()后,失去圆角的问题?

demo 地址: https://codepen.io/qingyun1029/pen/JjwxrmE

链接打不开,直接复制如下内容,保持为 html 文件即可:

<!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>
        html, body{
            height: 100%;
            overflow: hidden;
            margin: 0;
            border: 0;
            padding: 0;
        }
        .wrapper{
            height: 100%;
            overflow-y: hidden;
            display: flex;
            flex-direction: column;
        }
        .top{
            height: 200px;
            background: #e3e3e3;
        }
        .content{
            height: 0;
            flex: 1;
            overflow-y: auto;
            padding: 0 50px;
        }
        .node-warpper{
            background: rgba(255, 0, 0, 0.172);
            margin: 20px;
        }

        .node{
            border: 1px solid blue;
            height: 30px;
            line-height: 30px;
            margin: 10px;
        }
    </style>
</head>
<body>
    <div class="wrapper">
        <div class="top">
            top 区域
        </div>
        <div class="content" id="content">
            <div class="node-warpper" style="width: 200px;height: 100px;">
                <div class="node" id="node-1">
                    <div>node-1</div>
                </div>
            </div>
            <div class="node-warpper" style="width: 200px;height: 400px;">
                <div class="node" id="node-2">
                    <div>node-2</div>
                </div>
            </div>
            <div class="node-warpper" style="width: 200px;height: 200px;">
                <div class="node" id="node-3">
                    <div>node-3</div>
                </div>
            </div>
            <div class="node-warpper" style="width: 200px;height: 300px;">
                <div class="node" id="node-4">
                    <div>node-4</div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://files.cnblogs.com/files/mggahui/leader-line.min.js"></script>
    <script>
        let node1 = document.getElementById('node-1')
        let node2 = document.getElementById('node-2')
        let node3 = document.getElementById('node-3')
        let node4 = document.getElementById('node-4')

        let line1 = new LeaderLine({ start: node1, end: node2, path: 'grid', startSocket: 'right', endSocket: 'right', color: 'blue', size: 5  })
        let line2 = new LeaderLine({ start: node2, end: node3, path: 'grid', startSocket: 'left', endSocket: 'left', color: 'blue', size: 5  })
        let line3 = new LeaderLine({ start: node3, end: node4, path: 'grid', startSocket: 'right', endSocket: 'right', color: 'blue', size: 5  })

        let showEffectName = 'draw'
            // 动画参数
        let animOptions = {
            duration: 1000, //持续时长
            timing: 'ease-in' // 动画函数
        }
        line1.show(showEffectName, animOptions)
        line2.show(showEffectName, animOptions)
        line3.show(showEffectName, animOptions)

        let scrollView = document.getElementById('content')
        scrollView.addEventListener('scroll',function(){
            //滚动div,更新线条位置
            line1.position()
            line2.position()
            line3.position()

            //将折线替换成圆角
            let elmsPath1 = document.getElementById(`leader-line-${idx + 1}-line-path`);
            elmsPath1.setAttribute('d', addArc(elmsPath1.getAttribute('d'), 10));
            let elmsPath2 = document.getElementById(`leader-line-${idx + 1}-line-path`);
            elmsPath2.setAttribute('d', addArc(elmsPath2.getAttribute('d'), 10));
            let elmsPath3 = document.getElementById(`leader-line-${idx + 1}-line-path`);
            elmsPath3.setAttribute('d', addArc(elmsPath3.getAttribute('d'), 10));
        }, false);
        
        //将折线替换成圆角
        var elmsPath = document.getElementById('leader-line-1-line-path');
        elmsPath.setAttribute('d', addArc(elmsPath.getAttribute('d'), 10));
        var elmsPath2 = document.getElementById('leader-line-2-line-path');
        elmsPath2.setAttribute('d', addArc(elmsPath2.getAttribute('d'), 10));
        var elmsPath3 = document.getElementById('leader-line-3-line-path');
        elmsPath3.setAttribute('d', addArc(elmsPath3.getAttribute('d'), 10));

        //替换成圆角方法
        function addArc(pathData, radius) {
            var reL = /^L ?([\d.\-+]+) ([\d.\-+]+) ?/,
                newPathData, curXY, curDir, newXY, newDir,
                sweepFlag, arcXY, arcStartXY;

            function getDir(xy1, xy2) {
                if (xy1.x === xy2.x) {
                return xy1.y < xy2.y ? 'd' : 'u';
                } else if (xy1.y === xy2.y) {
                return xy1.x < xy2.x ? 'r' : 'l';
                }
                throw new Error('Invalid data');
            }

            function captureXY(s, x, y) {
                newXY = {x: +x, y: +y};
                return '';
            }

            function offsetXY(xy, dir, offsetLen, toBack) {
                return {
                x: xy.x + (dir === 'l' ? -offsetLen : dir === 'r' ? offsetLen : 0) * (toBack ? -1 : 1),
                y: xy.y + (dir === 'u' ? -offsetLen : dir === 'd' ? offsetLen : 0) * (toBack ? -1 : 1)
                };
            }

            pathData = pathData.trim().replace(/,/g, ' ').replace(/\s+/g, ' ')
                .replace(/^M ?([\d.\-+]+) ([\d.\-+]+) ?/, function(s, x, y) {
                curXY = {x: +x, y: +y};
                return '';
                });
            if (!curXY) { throw new Error('Invalid data'); }
            newPathData = 'M' + curXY.x + ' ' + curXY.y;

            while (pathData) {
                newXY = null;
                pathData = pathData.replace(reL, captureXY);
                if (!newXY) { throw new Error('Invalid data'); }

                newDir = getDir(curXY, newXY);
                if (curDir) {
                arcStartXY = offsetXY(curXY, curDir, radius, true);
                arcXY = offsetXY(curXY, newDir, radius);
                sweepFlag =
                    curDir === 'l' && newDir === 'u' ? '1' :
                    curDir === 'l' && newDir === 'd' ? '0' :
                    curDir === 'r' && newDir === 'u' ? '0' :
                    curDir === 'r' && newDir === 'd' ? '1' :
                    curDir === 'u' && newDir === 'l' ? '0' :
                    curDir === 'u' && newDir === 'r' ? '1' :
                    curDir === 'd' && newDir === 'l' ? '1' :
                    curDir === 'd' && newDir === 'r' ? '0' :
                    null;
                if (!sweepFlag) { throw new Error('Invalid data'); }
                newPathData += 'L' + arcStartXY.x + ' ' + arcStartXY.y +
                    'A ' + radius + ' ' + radius + ' 0 0 ' + sweepFlag + ' ' + arcXY.x + ' ' + arcXY.y;
                }

                curXY = newXY;
                curDir = newDir;
            }
            newPathData += 'L' + curXY.x + ' ' + curXY.y;
            debugger
            return newPathData;
        }
    </script>
</body>
</html>
回复
1个回答
avatar
test
2024-06-26

1、你的svg都使用了absolute定位,且在wrapper元素下面,所以默认是覆盖整个wrapper的,你想让top在svg上面,需要给top一个更高的z-indexposition: relative;z-index: 1;

2、你在scroll里面执行了将折线替换成圆角的操作,但是里面的元素获取都是通过leader-line-${idx + 1}-line-path获取的,我看你的idx并没有定义,所以这步是失败的。另外你的elmsPath1、elmsPath2、elmsPath3都是通过这个选择器获取的,最终获取的都是同一个。你scroll外面有同样的代码块,可以封装成一个公共函数,在scroll里面执行这个公共函数就行。

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容