vue中使用css實現氣泡圖
阿新 • • 發佈:2021-08-17
html部分:
<div id="scatter"> <div class="bubble_min bubble10"></div> <div class="bubble_min bubble12"></div> <div class="bubble_min bubble8"></div> <div class="bubble_min bubble12"></div> <div class="bubble_min bubble8"></div> <ul> <li class="li" v-for="item,index in bubbleData" :key="index" :style="{top:item.top,left:item.left,background:item.background,width:item.width+'px',height:item.width+'px',animationDuration:item.time+'s'}"> <span :style="{width:item.width+'px'}">{{item.width>40?item.name:''}}</span> <span :style="{width:item.width+'px'}">{{item.width>40?item.value+'%':''}}</span> <div class="tip">{{item.name+':'+item.value+'%'}}</div> </li> </ul> </div>
js部分:
/** *獲取n等分圓周座標點 *半徑:r *圓心座標:(ox,oy) */ getPoint(r, ox, oy, n) { let point = []; var radians = (Math.PI / 180) * Math.round(360 / n); for (let i = 0; i < n; i++) { var x = ox + r * Math.sin(radians * i), y = oy + r * Math.cos(radians * i); point.unshift([Math.floor(x), Math.floor(y)]); } return point; }, // 初始化氣泡圖 initScatter() { this.bubbleData = [ {value:56,name:'類目一'}, {value:13,name:'類目二'}, {value:45,name:'類目三'}, {value:1,name:'類目四'}, {value:69,name:'類目四'} ] let offsets; let colors = ["#f1a137", "#8585f8", "#68ccf7", "#95da2f", "#f8a1ac"]; //氣泡位置,只有一個時顯示在中間,較多時圍成一個圓 if (this.bubbleData.length === 1) { offsets = [[100, 100]]; } else { offsets = this.getPoint(100, 100, 110, this.bubbleData.length); } this.bubbleData.forEach((v, i) => { v.top = offsets[i][0] + "px"; v.left = offsets[i][1] + "px"; //迴圈使用colors顏色列表 v.background = colors[i % 5]; //將類目的value作為氣泡的寬度,由於value為1-20時,氣泡太小不美觀,因此給每個氣泡增加20的寬度 v.width = v.value + Math.ceil(v.value / (v.value + 1)) * 20; //氣泡的動畫時長 v.time = v.value>50?(v.value%6)+10:(v.value%6)+6 }); },
css部分:
/* 氣泡圖 */ #scatter { width: 350px; height: 300px; position: relative; li { opacity: 0.7; border-radius: 50%; position: absolute; z-index: 1; display: flex; flex-direction: column; justify-content: center; align-items: center; animation-name: itemfloat; animation-timing-function: linear; animation-fill-mode: both; animation-iteration-count: infinite; .tip { width: 150px; height: 40px; line-height: 40px; text-align: center; color: #000; border: 1px solid #ccc; border-radius: 8px; background: #fff; display: none; position: absolute; top: -45px; z-index: 101; transition: display 2s; } span { color: #fff; font-size: 12px; text-align: center; padding: 0 5px; display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } } li:hover .tip { display: block; } li:nth-child(2n) { animation-duration: 8s; } li:nth-child(2n-1) { animation-duration: 12s; } li:hover { z-index: 100; opacity: 1; transition: opacity 2 s; } .bubble_min:nth-child(1) { width: 20px; height: 20px; top: 100px; left: 40px; } .bubble_min:nth-child(2) { width: 60px; height: 60px; top: 130px; left: 100px; } .bubble_min:nth-child(3) { width: 50px; height: 50px; top: 90px; left: 180px; } .bubble_min:nth-child(4) { width: 30px; height: 30px; top: 250px; left: 300px; } .bubble_min:nth-child(5) { width: 30px; height: 30px; top: 110px; left: 240px; } .bubble_min { background-image: url(../../../../assets/bubble.png); background-size:100% 100% ; border-radius: 50%; position: absolute; z-index: 1; opacity: 0.5; animation-name: minibubble; animation-timing-function: linear; animation-fill-mode: both; animation-iteration-count: infinite; } .bubble8 { animation-duration: 8s; } .bubble10 { animation-duration: 10s; } .bubble12 { animation-duration: 12s; } @keyframes itemfloat { 0% { transform: translateY(0); } 25% { transform: translateY(-15px); } 50% { transform: translateY(0); } 75% { transform: translateY(15px); } 100% { transform: translateY(0); } } @keyframes minibubble { 0% { transform: translateY(200px) rotate(0deg); } 100% { transform: translateY(-240px) rotate(1500deg); } } }
效果圖如下: