在普通的網頁開發中,動畫效果能夠經過css3來實現大部分需求,在小程序開發中一樣能夠使用css3
,同時也能夠經過api
方式來實現。javascript
指路:小程序animatiom動畫APIcss
小程序中,經過調用api
來建立動畫,須要先建立一個實例對象。這個對象經過wx.createAnimation
返回,animation
的一系列屬性都基於這個實例對象。html
let animation = wx.createAnimation({ duration: 2000, delay: 0, timingFunction: "linear", });
這個animation
就是經過wx.createAnimation
以後返回的實例。在建立過程當中,能夠給這個實例添加一些屬性,如以上代碼所示,等同於css3
中animation:$name 2s linear
的寫法。前端
實例建立完成以後,基於該實例,添加須要的動態效果,動態類型能夠查閱文檔得知,以最多見的移動,旋轉爲例:java
animation.translate($width, 0).rotate($deg);
.step()
表示一組動畫的結束webpack
animation.step();
動畫效果添加完成了,如何給想要的dom添加動效呢。這裏須要用到.export()
導出動畫隊列,賦值給某個dom對象。css3
this.setData({ moveOne: animation.export() })
<view animation="{{moveOne}}"></view>
如下將經過2組動畫,來對比一下css3
與api
實現方式的不一樣。git
下圖有兩組動畫,分別爲api
方式(上)與css3
方式(下)完成的效果,點擊move按鈕,動畫啓動。github
如下分別爲css3
與api
的核心代碼:web
<!-- wxml --> <view class='border'> <view class='css-block {{isMove && "one"}}'></view> <view class='css-block {{isMove && "two"}}'></view> <view class='css-block {{isMove && "three"}}'></view> <view class='css-block {{isMove && "four"}}'></view> </view>
// scss @mixin movePublic($oldLeft,$oldTop,$left,$top) { from { transform:translate($oldLeft,$oldTop); } to { transform:translate($left,$top); } } @mixin blockStyle($color,$name) { background: $color; animation:$name 2s linear infinite alternate; } .one { @include blockStyle(lightsalmon,onemove); } @keyframes onemove { @include movePublic(50rpx,-25rpx,-150rpx,0rpx); } .two { @include blockStyle(lightblue,twomove); } @keyframes twomove { @include movePublic(0rpx,25rpx,-50rpx,0rpx); } .three { @include blockStyle(lightgray,threemove); } @keyframes threemove { @include movePublic(0rpx,25rpx,50rpx,0rpx); } .four { @include blockStyle(grey,fourmove); } @keyframes fourmove { @include movePublic(-50rpx,-25rpx,150rpx,0rpx); }
// js moveFunction(){ this.setData({ isMove: true }) }
css3
中經過動態改變class
類名來達到動畫的效果,如上代碼經過one
、two
、three
、four
來分別控制移動的距離,經過sass能夠避免代碼過於冗餘的問題。(糾結如何在小程序中使用sass
的童鞋請看這裏哦:wechat-mina-template)
moveClick(){ this.move(-75,-12.5,25,'moveOne'); this.move(-25,12.5, 0,'moveTwo'); this.move(25, 12.5,0,'moveThree'); this.move(75, -12.5,-25,'moveFour'); this.moveFunction(); // 該事件觸發css3模塊進行移動 }, // 模塊移動方法 move: function (w,h,m,ele) { let self = this; let moveFunc = function () { let animation = wx.createAnimation({ duration: 2000, delay: 0, timingFunction: "linear", }); animation.translate(w, 0).step() self.setData({ [ele]: animation.export() }) let timeout = setTimeout(function () { animation.translate(m, h).step(); self.setData({ // [ele] 表明須要綁定動畫的數組對象 [ele]: animation.export() }) }.bind(this), 2000) } moveFunc(); let interval = setInterval(moveFunc,4000) }
效果圖可見,模塊之間都是簡單的移動,能夠將他們的運動變化寫成一個公共的事件,經過向事件傳值,來移動到不一樣的位置。其中的參數w,h,m,ele
分別表示發散水平方向移動的距離、聚攏時垂直方向、水平方向的距離以及須要修改animationData
的對象。
經過這種方法產生的動畫,沒法按照原有軌跡收回,因此在事件以後設置了定時器,定義在執行動畫2s以後,執行另外一個動畫。同時動畫只能執行一次,若是須要循環的動效,要在外層包裹一個重複執行的定時器到。
查看源碼,發現api
方式是經過js
插入並改變內聯樣式來達到動畫效果,下面這張動圖能夠清晰地看出樣式變化。
打印出賦值的animationData
,animates
中存放了動畫事件的類型及參數;options
中存放的是這次動畫的配置選項,transition
中存放的是wx.createAnimation
調用時的配置,transformOrigin
是默認配置,意爲以對象的中心爲起點開始執行動畫,也可在wx.createAnimation
時進行配置。
上面的模塊移動動畫不涉及邏輯交互,所以新嘗試了一個音樂播放動畫,該動畫須要實現暫停、繼續的效果。
兩組不一樣的動畫效果對比,分別爲api
(上)實現與css3
實現(下):
如下分別是css3
實現與api
實現的核心代碼:
<!-- wxml --> <view class='music musicTwo musicRotate {{playTwo ? " ": "musicPaused"}} ' bindtap='playTwo'> <text class="iconfont has-music" wx:if="{{playTwo}}"></text> <text class="iconfont no-music" wx:if="{{!playTwo}}"></text> </view>
// scss .musicRotate{ animation: rotate 3s linear infinite; } @keyframes rotate{ from{ transform: rotate(0deg) } to{ transform: rotate(359deg) } } .musicPaused{ animation-play-state: paused; }
// js playTwo(){ this.setData({ playTwo: !this.data.playTwo },()=>{ let back = this.data.backgroundAudioManager; if(this.data.playTwo){ back.play(); } else { back.pause(); } }) }
經過playTwo
這個屬性來判斷是否暫停,並控制css
類的添加與刪除。當爲false
時,添加.musicPaused
類,動畫暫停。
<!-- wxml --> <view class='music' bindtap='play' animation="{{play && musicRotate}}"> <text class="iconfont has-music" wx:if="{{play}}"></text> <text class="iconfont no-music" wx:if="{{!play}}"></text> </view>
// js play(){ this.setData({ play: !this.data.play },()=>{ let back = this.data.backgroundAudioManager; if (!this.data.play) { back.pause(); // 跨事件清除定時器 clearInterval(this.data.rotateInterval); } else { back.play(); // 繼續旋轉,this.data.i記錄了旋轉的程度 this.musicRotate(this.data.i); } }) }, musicRotate(i){ let self = this; let rotateFuc = function(){ i++; self.setData({ i:i++ }); let animation = wx.createAnimation({ duration: 1000, delay: 0, timingFunction: "linear", }); animation.rotate(30*(i++)).step() self.setData({ musicRotate: animation.export() }); } rotateFuc(); let rotateInterval = setInterval( rotateFuc,1000 ); // 全局定時事件 this.setData({ rotateInterval: rotateInterval }) }
經過api
實現的方式是經過移除animationData
來控制動畫,同時暫停動畫也須要清除定時器,因爲清除定時器須要跨事件進行操做,因此定了一個全局方法rotateInterval
。
api
方式定義了旋轉的角度,但旋轉到該角度以後便會中止,若是須要實現重複旋轉效果,須要經過定時器來完成。所以定義了變量i,定時器每執行一次便加1,至關於每1s旋轉30°,對animation.rotate()
中的度數動態賦值。暫停以後繼續動畫,須要從原有角度繼續旋轉,所以變量i須要爲全局變量。
下圖能夠看出,api
方式旋轉是經過不斷累加角度來完成,而非css3
中循環執行。
經過上述兩個小例子對比,不管是便捷度仍是代碼量,經過css3
來實現動畫效果相對來講是更好的選擇。api
方式存在較多侷限性:
綜合以上,推薦經過css3
來完成動畫效果。
本文發佈於薄荷前端週刊,歡迎Watch & Star ★,轉載請註明出處。