前言
每次寫點東西都扯兩句-0-,這幾天一半精力放在移動端,一半維護之前的項目。書也少看了,不過還好依舊保持一顆學習的心。對於css3我是之前有專門整理過的,因此對於原理之前也算了解。今天是項目中遇到一個效果,來整理一下。
正文
首先我們可以找到微信的語音播放效果。這里自行打開手機微信進行查看。之前后台提起用gif動畫,但是對於gif動畫有兩個難點:1.誰來畫?(抱歉這種東西沒有設計師來搞前端是不做的。)2.移動端你跟我提用gif?
很顯然,必須用css3來搞。不過之前寫js寫的多了,發現css3有點生疏。但是基本的搜索能力還是有的。找到Loader.css看下基本布局,然后找mdn文檔翻翻。基本思路就確定下來了。
先來看代碼:
<div class="cricleplay" v-on:click="audio" status="stop" no="1">
<div class="small"></div>
<div class="middle stopanimate"></div>
<div class="large stopanimate"></div>
</div>
用一個cricleplay來包含,然后你看一下語法可能就明白我已經升級vue版本到1.0.8了。因為移動端不想再包含其他的庫,於是寫原生的js操作dom也花了蠻多時間去熟悉。。。后來發現zepto.min.js其實挺小。然后就替換了一部分。
剛開始考慮的是直接用Border來畫,然后四分之一圓這樣來。
然而對比一下你可以看見: 
這兩者非常的不像。。。
於是應該考慮如何畫一個弧形,然而在google和百度上找不到。
於是直接去codepen搜索arc。
找一個類似弧形。
之后就能畫出類似這種:

直接來貼成品代碼:
.small{
width: 20px;
height: 20px;
border-style: solid;
border-top-color: transparent;
border-left-color: transparent;
border-bottom-color: transparent;
border-radius: 50%;
box-sizing: border-box;
vertical-align: middle;
display: inline-block;
color:#A2A2A2;
}
.middle{
width: 30px;
height: 30px;
border-style: solid;
border-top-color: transparent;
border-left-color: transparent;
border-bottom-color: transparent;
border-radius: 50%;
box-sizing: border-box;
vertical-align: middle;
display: inline-block;
margin-left: -22px;
animation: show2 3s ease-in-out infinite;
opacity: 1;
color:#A2A2A2;
}
@keyframes show2 {
0% { opacity: 0;}
30% { opacity: 1;}
100% { opacity: 0;}
}
.cricleplay{
width: 100%;
}
.large{
width: 40px;
height: 40px;
border-style: solid;
border-top-color: transparent 大專欄 純css3配合vue實現微信語音播放效果;
border-left-color: transparent;
border-bottom-color: transparent;
border-radius: 50%;
box-sizing: border-box;
vertical-align: middle;
display: inline-block;
margin-left: -32px;
animation: show3 3s ease-in-out infinite;
opacity: 1;
color:#A2A2A2;
}
@keyframes show3 {
0% { opacity: 0;}
60% { opacity: 1;}
100% { opacity: 0;}
}
當然你也可以戳這里看更加直觀的效果。
對於這些css3是沒什么好講的,看下代碼就能直接理解思路。比較需要時間調試的是動畫補間。
然后我們就獲取到一個能夠不斷播放的語音效果。但是我們是需要能夠在點擊之后才播放。點擊其它或者再次點擊動畫應該消失。因此我們可以把整個效果配上動作處理寫成一個vue組件。不過我這里直接從項目中提取部分。
來看代碼:
// 添加、移除、檢測 className
function hasClass(element, className) {
var reg = new RegExp('(\s|^)'+className+'(\s|$)');
return element.className.match(reg);
}
function addClass(element, className) {
if (!hasClass(element, className))
{
element.className += " "+className;
}
}
function removeClass(element, className) {
if (hasClass(element, className)) {
var reg = new RegExp('(\s|^)'+className+'(\s|$)');
element.className = element.className.replace(reg,' ');
}
}
上面這些是我之前打算純js處理dom的操作class的方法。
對於讓infinite動畫能夠中途停止,尤其是在移動端。我一開始思路是添加一個class設置animation-iteration-count為0.在chrome調試的時候是可行的。然而在移動端它是不能夠停止的。
因此google了一下方案。
最終采用的方案是:
.stopanimate{
-moz-animation-name: none;
-webkit-animation-name: none;
-ms-animation-name: none;
animation-name: none;
}
將動畫名稱給清除了。
然后很簡單就是對應的動畫添加樣式或者刪除樣式
addClass(that.currentparent.children[1],"stopanimate");
addClass(that.currentparent.children[2],"stopanimate");
addClass(event.children[1],"stopanimate");
addClass(event.children[2],"stopanimate");
因為我用的是vue,在methods中處理時能獲取到event,然后event中找到需要操作的類。當然你可以自己用其它方式獲取。
然后就能看到如下效果:

結尾
這篇文章沒多大技術含量,主要就是我自己記錄下思路。
