一、先看图
二、代码实现
1.三个圆环,设置三个dom
<div>
<div class="ul1Box">
<ul>
<li v-for="(item,index) in hotTransform3" :key="index" :style="{transform: item.posi}">
<div class="liBox">
<div class="pointLabel">{{item.label}}</div>
<div class="point" :style="{background:item.bg}"></div>
</div>
</li>
</ul>
</div>
<div class="ul2Box">
<ul>
<li v-for="(item,index) in hotTransform2" :key="index" :style="{transform: item.posi}">
<div class="liBox">
<div class="pointLabel">{{item.label}}</div>
<div class="point" :style="{background:item.bg}"></div>
</div>
</li>
</ul>
</div>
<div class="ul3Box">
<ul>
<li v-for="(item,index) in hotTransform" :key="index" :style="{transform: item.posi}">
<div class="liBox">
<div class="pointLabel">{{item.label}}</div>
<div class="point" :style="{background:item.bg}"></div>
</div>
</li>
</ul>
</div>
</div>
2.样式
ul,li {
margin: 0;
list-style-type: none;
padding: 0;
}
.ul1Box ul {
width: 17.5rem;
height:17.5rem;
background-color: #fff;
border-radius: 50%;
position: relative;
border: 1px solid rgba(146, 182, 255, 0.39);
z-index:8;
/* top: 50%;
left: 50%;
transform: translate(-50%,-50%); */
}
.newWordsBox li {
width: 2.1875rem;
height: 2.1875rem;
position: absolute;
/* background-color: rgb(97, 153, 74); */
color: #000;
font-size: .6875rem;
border-radius: 50%;
text-align: center;
margin-left: -0.125rem;
/* left: 50%; */
margin-left: -1.25rem;
margin-top: -1.25rem;
transform-origin: 0px 0px;
}
.liBox{
width: 100%;
height: 100%;
position: relative;
cursor: pointer;
}
.activeLiBox{
color: #005AFF;
}
.ul1Box{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
.ul2Box{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
.ul2Box ul {
width: 12.5rem;
height:12.5rem;
background-color: #fff;
border-radius: 50%;
position: relative;
border: 1px solid rgba(146, 182, 255, 0.39);
z-index:8;
/* top: 50%;
left: 50%;
transform: translate(-50%,-50%); */
}
.ul3Box{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
.ul3Box ul {
width: 7.5rem;
height:7.5rem;
background-color: #fff;
border-radius: 50%;
position: relative;
border: 1px solid rgba(146, 182, 255, 0.39);
z-index:8;
/* top: 50%;
left: 50%;
transform: translate(-50%,-50%); */
}
.pointLabel{
position: absolute;
top: -0.3125rem;
width: 3.75rem;
left: 50%;
transform: translate(-50%);
}
.point{
width: .375rem;
height: .375rem;
border-radius: 50%;
background: rgba(124, 198, 35, 1);
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
3.js
【渲染三个圆环上的label数据,实际根据使用场景自行替换arr.push的字段】
hotTransforms(){
if (!this.hotWorldList) {
return
}
let num = 0
// let angleList = [80,105,124,235,250,270,290]
let angleList = [10,80,144,235,290] //设置每个label在圆环上的角度
let arr = []
if (this.hotWorldList.length<=5) {
num = this.hotWorldList.length
} else if (this.hotWorldList.length>5) {
num = 5
}
if (this.wordFlag == 1) {
for (let i = 0; i < num; i++) {
arr.push({label:this.hotWorldList[i].word,num:this.hotWorldList[i].num,analyze:this.hotWorldList[i].analyze,angle:angleList[i],posi:'',bg:this.hotWorldColor(i)}) //bg用于设置点的颜色
}
} else {
for (let i = 0; i < num; i++) {
let a = this.hotWorldList[i].rate
arr.push({label:this.hotWorldList[i].word,num:a.substring(0,a.indexOf('%')),analyze:this.hotWorldList[i].analyze,angle:angleList[i],posi:'',bg:this.hotWorldColor(i)})
}
}
arr.forEach(e => {
e.posi = this.getAxis(e.angle,60)
})
// return arr
this.hotTransform = arr
},
hotTransforms2(){
if (this.hotWorldList.length<=5) {
return
}
let num = 0
// let angleList = [60,100,130,210,235,260,290]
let angleList = [75,95,130,220,275]
let arr = []
if (this.hotWorldList.length<=10) {
num = this.hotWorldList.length - 5
} else if (this.hotWorldList.length>14) {
num = 5
}
if (this.wordFlag == 1) {
for (let i = 0; i < num; i++) {
arr.push({label:this.hotWorldList[i+5].word,num:this.hotWorldList[i+5].num,analyze:this.hotWorldList[i+5].analyze,angle:angleList[i],posi:'',bg:this.hotWorldColor(i+5)})
}
} else {
for (let i = 0; i < num; i++) {
let a = this.hotWorldList[i+5].rate
arr.push({label:this.hotWorldList[i+5].word,num:a.substring(0,a.indexOf('%')),analyze:this.hotWorldList[i+5].analyze,angle:angleList[i],posi:'',bg:this.hotWorldColor(i+5)})
}
}
arr.forEach(e => {
e.posi = this.getAxis(e.angle,100)
})
// return arr
this.hotTransform2 = arr
},
hotTransforms3(){
if (this.hotWorldList.length<=10) {
return
}
let num = 0
// let angleList = [20,80,134,180,245,325]
let angleList = [65,85,100,115,128,235,250,265,280,295]
let arr = []
if (this.hotWorldList.length<=20) {
num = this.hotWorldList.length - 10
}
if (this.wordFlag == 1) {
for (let i = 0; i < num; i++) {
arr.push({label:this.hotWorldList[i+10].word,num:this.hotWorldList[i+10].num,analyze:this.hotWorldList[i+10].analyze,angle:angleList[i],posi:'',bg:this.hotWorldColor(i+10)})
}
} else {
for (let i = 0; i < num; i++) {
let a = this.hotWorldList[i+10].rate
arr.push({label:this.hotWorldList[i+10].word,num:a.substring(0,a.indexOf('%')),analyze:this.hotWorldList[i+10].analyze,angle:angleList[i],posi:'',bg:this.hotWorldColor(i+10)})
}
}
arr.forEach(e => {
e.posi = this.getAxis(e.angle,140)
})
// return arr
this.hotTransform3 = arr
},
getAxis(angle,r) { //设置环绕元素位置偏移量,全文用的rem适配,所以这里点位用的rem,需根据实际使用选择单位
// 公式,r-半径,angle-角度
// x: r+r*Math.sin(angle*Math.PI/180)
// y: r-r*Math.cos(angle*Math.PI/180)
return `translate(${(r*Math.sin(angle*Math.PI/180)+r)/16}rem, ${(r-
r*Math.cos(angle*Math.PI/180))/16}rem)`
}