最近公司專案有個需求是在網頁上操作虛擬機器,emmm...操作就操作吧,誰讓是領導提的,我們也不知道,我們也不敢問啊....咋辦?搞吧,爬了n多個坑才終於把虛擬機器功能給引入到專案中,看著熟悉的Linux操作視窗,都別攔我,讓我裝一會*
領導看了十分滿意,然後說...我看電腦上都有那個懸浮球,我們這也得有吧
???啥玩意???去他電腦上看了一下才發現是安全軟體的那個展示電腦使用情況的懸浮球,WTF!!你見過哪個Linux有這懸浮球的?你咋不讓我再給你整一隻瑞星小獅子在旁邊給你跳舞呢??算了還是別說了,說了真讓我做怎麼搞....
需求
需求說起來很簡單--》小球、懸浮在頁面最上層、內部有波浪能動、波浪高度跟虛擬機器使用情況有關、滑鼠放上去展示詳細資訊,大概就是醬嬸的
開搞
環境
專案使用的是vue框架,所以demo都是在vue環境下,不過程式碼其實沒什麼環境需求的。
設計思路
看到這個需求的第一想法就是用canvas畫一個懸浮球,這個倒也不難,網上挺多案例的,後面想能不能用css動畫試試?效能還能更好一下,畢竟在有虛擬機器的頁面已經是有點卡了,任何效能的提升都是有必要的。
主要實現原理就是使用一個不停運動的a遮在b塊上面,然後讓a的顏色與背景顏色相同,從而造成b的邊緣在不停波動的效果。
1.畫個大圓套小圓
<div class="container">
<div class="wave"></div>
</div>
<style>
.container {
width: 100px;
height: 100px;
border-radius: 50%;
border: 3px solid #67c23a;
background: #ffffff;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 5px;
}
.wave {
position: relative;
width: 100px;
height: 100px;
background-image: linear-gradient(-180deg, #aaff80 13%, #67c23a 91%);
border-radius: 50%;
}
</style>
複製程式碼
然後我們得到了這個
2.畫遮蓋層並讓它扭起來
<div class="container">
<div class="wave"></div>
<div class="wave-mask"></div>
</div>
<style>
.wave-mask {
position: absolute;
width: 200px;
height: 200px;
top: 0;
left: 50%;
border-radius: 40%;
background-color: rgba(212, 24, 24, 0.9);
transform: translate(-50%, -70%) rotate(0);
animation: toRotate 10s linear -5s infinite;
z-index: 20;
}
@keyframes toRotate {
50% {
transform: translate(-50%, -70%) rotate(180deg);
}
100% {
transform: translate(-50%, -70%) rotate(360deg);
}
}
</style>
複製程式碼
然後就變成了這樣(為了看的效果更好,原諒我使用的大紅色)
3.裁剪
.container {
overflow: hidden;
}
.wave-mask {
background-color: rgba(255, 255, 255, 0.9);
}
複製程式碼
成品就醬嬸的了
4.完善
波浪的高度完全是受wave-mask的top屬性影響的,所以要動態變更懸浮球狀態只需要計算然後相應的改變top的值就可以了,然後稍微完善一下程式碼
<template>
<div class="home">
<div class="container" :class="{ warning: parseInt(usingRate) > 60, danger: parseInt(usingRate) > 80 }">
<div class="wave"></div>
<div class="wave-mask" :style="`top: ${40 - parseInt(usingRate)}px`"></div>
</div>
<div class="using-slider">
<span>使用率:{{usingRate}} %</span>
<el-slider v-model="usingRate"></el-slider>
</div>
</div>
</template>
<script>
export default {
data () {
return {
usingRate: 0
}
}
}
</script>
<style lang="scss" scoped>
.container {
width: 100px;
height: 100px;
border-radius: 50%;
border: 3px solid #67c23a;
background: #ffffff;
overflow: hidden;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 5px;
.wave {
position: relative;
width: 100px;
height: 100px;
background-image: linear-gradient(-180deg, #aaff80 13%, #67c23a 91%);
border-radius: 50%;
}
.wave-mask {
position: absolute;
width: 200px;
height: 200px;
top: 0;
left: 50%;
border-radius: 40%;
background-color: rgba(255, 255, 255, 0.9);
transform: translate(-50%, -70%) rotate(0);
animation: toRotate 10s linear -5s infinite;
z-index: 20;
}
&.warning {
border: 3px solid #e6a23c;
.wave {
background-image: linear-gradient(-180deg, #f0c78a 13%, #e6a23c 91%);
}
&.danger {
border: 3px solid #f56c6c;
.wave {
background-image: linear-gradient(-180deg, #f78989 13%, #f56c6c 91%);
}
}
}
}
.using-slider {
width: 400px;
margin: 0 auto;
}
@keyframes toRotate {
50% {
transform: translate(-50%, -70%) rotate(180deg);
}
100% {
transform: translate(-50%, -70%) rotate(360deg);
}
}
</style>
複製程式碼
看效果
大概就醬嬸了,第一次寫文,文筆不好多多見諒,別說我爛尾了,因為...我要下班了