效果图:
本来想用svg画线的,最后发现这玩意兼容性不太好。 经过了解需求,左右边的盒子都是固定个数的,所以直接使用定位+ rotate 来实现。
废话不说,上代码。
1.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>
<link rel="stylesheet" href="./index.css">
</head>
<body>
<div class="box">
<div class="left">
<div class="row">
<div class="xian"></div>
<div class="xian"></div>
<div class="xian"></div>
<div class="xian"></div>
<div class="xian"></div>
</div>
<div class="row">
<div class="xian"></div>
<div class="xian"></div>
<div class="xian"></div>
<div class="xian"></div>
<div class="xian"></div>
</div>
<div class="row">
<div class="xian"></div>
<div class="xian"></div>
<div class="xian"></div>
<div class="xian"></div>
<div class="xian"></div>
</div>
</div>
<div class="right">
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
<div class="row"></div>
</div>
</div>
</body>
<script>
const leftDoms = document.querySelectorAll('.left .row')
const rightDoms = document.querySelectorAll('.right .row')
// 左边选中的索引
let leftInd = 0
leftDoms.forEach((v, i) => {
v.addEventListener('click', () => {
leftDoms.forEach(p => {
p.classList.remove('active')
})
leftInd = i
leftDoms[i].classList.add('active')
const xianDoms = document.querySelectorAll('.left .active .xian')
// 清空右边的选中状态和线
xianDoms.forEach((v3, i3) => {
v3.classList.remove(`xian${leftInd+1}-${i3+1}`)
})
rightDoms.forEach((v2, i2) => {
v2.classList.remove('active')
})
})
})
rightDoms.forEach((v, i) => {
v.addEventListener('click', () => {
// 拿到左边选中的元素的线
const leftAcDoms = document.querySelectorAll('.left .active .xian')
// 应该添加和删除的类
const leftXianClass = `xian${leftInd+1}-${i+1}`
const leftXianClassName = leftAcDoms[i].className
if (leftXianClassName.includes(leftXianClass)) {
leftAcDoms[i].classList.remove(leftXianClass)
} else {
leftAcDoms[i].classList.add(leftXianClass)
}
const className = rightDoms[i].className
if (className.includes('active')) {
rightDoms[i].classList.remove('active')
} else {
rightDoms[i].classList.add('active')
}
})
})
</script>
</html>
2.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.box {
width: 800px;
margin: 100px auto;
display: flex;
}
.box .row {
cursor: pointer;
position: relative;
width: 100px;
height: 40px;
border-radius: 20px;
border: 1px solid red;
margin-bottom: 20px;
}
.box .row .xian {
position: absolute;
top: 19px;
height: 2px;
background-color: green;
transform-origin: top left;
left: 100px;
width: 0px;
transition: all 0.2s;
}
.box .active {
background-color: red;
}
.box .active .xian1-1 {
transform: rotate(-31deg);
width: 120px;
}
.box .active .xian1-2 {
width: 100px;
}
.box .active .xian1-3 {
transform: rotate(31deg);
width: 120px;
}
.box .active .xian1-4 {
transform: rotate(49deg);
width: 158px;
}
.box .active .xian1-5 {
transform: rotate(60deg);
width: 206px;
}
.box .active .xian2-1 {
transform: rotate(-49deg);
width: 156px;
}
.box .active .xian2-2 {
transform: rotate(-31deg);
width: 120px;
}
.box .active .xian2-3 {
width: 100px;
}
.box .active .xian2-4 {
transform: rotate(31deg);
width: 120px;
}
.box .active .xian2-5 {
transform: rotate(49deg);
width: 158px;
}
.box .active .xian3-1 {
transform: rotate(-60deg);
width: 205px;
}
.box .active .xian3-2 {
transform: rotate(-49deg);
width: 156px;
}
.box .active .xian3-3 {
transform: rotate(-31deg);
width: 120px;
}
.box .active .xian3-4 {
width: 100px;
}
.box .active .xian3-5 {
transform: rotate(31deg);
width: 120px;
}
.box .left {
margin-right: 100px;
margin-top: 60px;
}