利用css transition屬性實(shí)現(xiàn)一個(gè)帶動(dòng)畫(huà)顯隱的微信小程序部件
像這樣的一個(gè)帶過(guò)渡效果的小部件在我們實(shí)際開(kāi)發(fā)中的應(yīng)用幾率還是比較大的,但是在開(kāi)發(fā)微信小程序的過(guò)程中可能有的小伙伴發(fā)現(xiàn)transition這個(gè)屬性它不好使(下面說(shuō)明)所以我們這個(gè)時(shí)候會(huì)考慮去使用微信官方提供的wx.createAnimation API來(lái)創(chuàng)建動(dòng)畫(huà)。
接下來(lái)我?guī)Ц魑恍』锇槿绾巫?transition 屬性在這種需求中好使起來(lái),下面上代碼
page({ data: { show:false//用于顯示或隱藏控件 }, chanMask:function(){ var isShow = this.data.show ? false : true;//如果顯示就隱藏,隱藏就顯示 this.setData({ show:isShow }) } })
/*index.wxss*/ /*顯示前*/ .mask-con{ transition: 1s; position: fixed; width: 100%; height: 300rpx; left: 0; bottom: -300rpx; text-align: center; line-height: 300rpx; box-shadow: 0 1px 10px #aaa; } /*顯示后*/ .mask-con-show{ bottom: 0; }
<!--index.wxml--> <view class="container"> <button bindtap="chanMask">點(diǎn)我</button> <view class="mask-con {{show ? 'mask-con-show' : ''}}"> <view class="close" bindtap="chanMask">X</view> 慢慢飛起 </view> </view>
在以上代碼中我們首先在data中定義了一個(gè)show變量用于mask-con控件的顯示狀態(tài),在chanMask函數(shù)中交替的改變這個(gè)變量,然后將chanMask函數(shù)綁定給button和close控件的點(diǎn)擊事件上,最后我們根據(jù)show來(lái)決定是否給mask-con(我們的動(dòng)畫(huà)控件)添加一個(gè)class: mask-con-show那么到這里我們已經(jīng)實(shí)現(xiàn)了一個(gè)帶過(guò)渡的顯隱小部件
現(xiàn)在很多的APP或小程序都是以這種方式來(lái)close彈窗控件,那個(gè)X用戶點(diǎn)的不過(guò)癮,看到這里聰明的小伙伴可能會(huì)想到再另外添加一個(gè)陰影控件在mask-con的下層并綁定上我們的chanMask函數(shù),這樣的話陰影控件和我們的mask-con就可能不是在一個(gè)整體上了,不夠直觀,又比如說(shuō)領(lǐng)導(dǎo)要讓這個(gè)陰影它有一個(gè)顯示顏色慢慢加深,隱藏慢慢減淡的效果,為了應(yīng)對(duì)這種情況,我們把代碼調(diào)整如下:
page({ data: { show:false//用于顯示或隱藏mask控件 }, chanMask:function(){ var isShow = this.data.show ? false : true;//如果顯示就隱藏,隱藏就顯示 this.setData({ show:isShow }) } })
/*index.wxss*/ .mask-shadow{ width: 100%; height: 100%; opacity: 0; transition: 1s; } .mask-shadow-on{ opacity: 0.3; } .mask-con{ position: absolute; width: 100%; height: 300rpx; left: 0; bottom: -300rpx; transition: 1s; text-align: center; line-height: 300rpx; box-shadow: 0 1px 10px #aaa; } .mask-con-show{ bottom: 0; }
<!--index.wxml--> <view class="container"> <button bindtap="chanMask">點(diǎn)我</button> <view class="mask {{show ? 'show' : 'hide'}}"> <view class="mask-shadow {{show ? 'mask-shadow-on' : ''}}"></view> <view class="mask-con {{show ? 'mask-con-show' : ''}}"> <view class="close" bindtap="chanMask">X</view> 慢慢飛起 </view> </view> </view>
在這里我們?cè)O(shè)置了兩個(gè)樣式類(lèi)名mask-shadow-on和mask-con-show來(lái)定義陰影以及主要控件mask-con動(dòng)畫(huà)后的效果(具體代碼根據(jù)自己的需求決定),看起來(lái)一切都OK,沒(méi)有任何問(wèn)題,那么先運(yùn)行一波,艾瑪,神馬情況?陰影和我們的mask-con直接懟了出來(lái)毫無(wú)過(guò)渡效果,那這是何原因影響我們程序的效果呢,經(jīng)過(guò)一番考量博主發(fā)現(xiàn)在display為none的情況之下我們的transition屬性可能會(huì)失效,那到這里有的小伙伴可能會(huì)問(wèn) “博主,那個(gè)不對(duì)啊,我們明明已經(jīng)將mask的display設(shè)置成block怎么還有這種問(wèn)題呢”
是這樣的,我們的mask控件它顯示需要那么一點(diǎn)時(shí)間才能完全顯示出來(lái),但是呢我們的變量show設(shè)置成true之后,我們的陰影控件和主要控件也會(huì)馬上添加上了動(dòng)畫(huà)后樣式類(lèi)名,這個(gè)時(shí)間它比mask顯示所需的時(shí)間要快,所以我們的機(jī)器它認(rèn)為mask還是處于display為none的情況
打個(gè)比方說(shuō):mask是這一整塊的老大,這個(gè)老大都還沒(méi)表演完事,你們這些做小弟就已經(jīng)出來(lái)?yè)岋L(fēng)頭了,你讓當(dāng)老大的面子往哪放,不行我得把你們這些搶我風(fēng)頭的都給干掉,看你們還得瑟。這個(gè)老大的人狠話不多,你搶了他風(fēng)頭不行,你想不表演他(用戶體驗(yàn))也不高興,而且他表演完了還不跟你說(shuō),那這個(gè)老大這么難伺候該怎么辦呢?有的小伙伴已經(jīng)感覺(jué)到迷茫了嗎,那還在等什么,趕快拿起你手中的電話撥打求助熱線。。。。。啊呸,扯遠(yuǎn)了
其實(shí)決解的方法很簡(jiǎn)單,沒(méi)錯(cuò)答案就是 setTimeout()函數(shù),來(lái),我們把代碼再改一遍:
page({ data: { show:false,//用于顯示或隱藏mask控件 runAM:false//用于動(dòng)畫(huà)執(zhí)行的根據(jù) }, chanMask:function(){ var isShow = this.data.show ? false : true;//如果顯示就隱藏,隱藏就顯示 var delay = isShow ? 30 : 1000;//第一個(gè)時(shí)間是博主測(cè)出來(lái)控件顯示所需的時(shí)間,第二個(gè)是動(dòng)畫(huà)所需的時(shí)間 if(isShow){ this.setData({ show:isShow }); }else{ this.setData({ runAM:isShow }) } setTimeout(function(){ if(isShow){ this.setData({ runAM:isShow }); }else{ this.setData({ show:isShow }); } }, delay); } })
<!--index.wxml--> <view class="container"> <button bindtap="chanMask">點(diǎn)我</button> <view class="mask {{show ? 'show' : 'hide'}}" bindtap="chanMask"> <view class="mask-shadow {{runAM ? 'mask-shadow-on' : ''}}"></view> <view class="mask-con {{runAM ? 'mask-con-show' : ''}}"> <view class="close" bindtap="chanMask">X</view> 慢慢飛起 </view> </view> </view>
在以上代碼中,我們給data新添加了一個(gè)變量runAM用于動(dòng)畫(huà)何時(shí)開(kāi)始執(zhí)行的憑證,再在chanMask函數(shù)定義了一個(gè)用于設(shè)置延時(shí)的變量delay 代碼可能有點(diǎn)繞博主在此粗暴的解釋一下
程序的整個(gè)過(guò)程都是根據(jù)isShow這個(gè)變量來(lái)走的,
當(dāng)isShow為true時(shí)也就是說(shuō)我們要打開(kāi)mask控件了,所以我們先把mask控件顯示出來(lái),然后在延時(shí)30毫秒后去為要執(zhí)行動(dòng)畫(huà)的控件添加上樣式類(lèi)名
當(dāng)isShow為false時(shí)我們先把動(dòng)畫(huà)控件的類(lèi)名去掉(去掉后會(huì)執(zhí)行動(dòng)畫(huà)回到原本的形態(tài)),然后在延時(shí)1000毫秒(動(dòng)畫(huà)所需的時(shí)間)后讓mask隱藏
關(guān)于delay的第一個(gè)值的設(shè)定時(shí)博主自己測(cè)出來(lái)的,如果各位小伙伴還擔(dān)心控件沒(méi)顯示的話可以設(shè)成50毫秒或100毫秒都無(wú)所這0.1秒的時(shí)間差對(duì)用戶體驗(yàn)的影響并不大,如過(guò)你設(shè)了1秒都沒(méi)反應(yīng),我只能說(shuō)換手機(jī)吧
最后你會(huì)發(fā)現(xiàn)在整個(gè)過(guò)程中博主都只調(diào)用一個(gè)函數(shù)進(jìn)行顯示或隱藏,并沒(méi)有為關(guān)閉新建函數(shù)處理,這種寫(xiě)法逼格滿滿有木有
此方法同樣適用于H5