在微信開發中,寫過的一個簡單的音樂播放組件,記錄下。javascript
音樂播放組件。css
屬性名 | 類型 | 默認值 | 說明 |
---|---|---|---|
music | String | 傳入的音樂資源地址 | |
musicStyle | String | (隨便寫了個) | 音樂組件的樣式 |
rotate | Boolean | true | 播放時是否有旋轉效果 |
iconOn | String | (隨便寫了個) | 音樂播放時的icon地址 |
iconOff | String | (隨便寫了個) | 音樂暫停時的icon地址 |
properties: { // 音樂路徑 music: { type: String, value: '', observer: function (newVal) { this._initMusic(newVal) } }, // 樣式 musicStyle: { type: String, value: 'position: absolute; right: 20rpx; top: 20rpx; width: 100rpx; height: 100rpx;' }, // 播放時是否有旋轉效果 rotate: { type: Boolean, value: true }, // 播放時的icon路徑 iconOn: { type: String, value: '/resources/img/music-on.png' // 請填寫默認的圖片地址 }, // 暫停時的icon路徑 iconOff: { type: String, value: '/resources/img/music-off.png' // 請填寫默認的圖片地址 } }
首先,在properties
中接收頁面傳來的音樂文件地址,html
music: { type: String, value: '', observer: function (newVal) { this._initMusic(newVal) } }
這裏的處理是,一旦接收到頁面傳來的 music 地址,就初始化音樂:java
_initMusic: function (newVal) { // 當頁面傳來新的music時,先銷燬以前的audioCtx,不然頁面會很嗨 if (this.data.audioCtx) { this.data.audioCtx.destroy() } if (newVal) { var audioCtx = wx.createInnerAudioContext() this.setData({ audioCtx: audioCtx }) if (this.data.audioStatus == '1') { audioCtx.autoplay = true } audioCtx.loop = true audioCtx.src = newVal } }
audioStatus 用來記錄音樂播放狀態,在data
中默認設置爲1:git
data: { icon: '', audioStatus: 1, audioCtx: '', musicClass: 'music-on' }
wxml文件裏,只用一個 <image> 標籤:github
<image class='music {{ rotate && musicClass }}' style="{{ musicStyle }}" src="{{ icon }}" bindtap='_switch' wx:if="{{ music }}"></image>
其中, icon 在組件ready()
時賦值成播放狀態的icon:web
ready() { this.setData({ icon: this.data.iconOn }) }
音樂播放時的旋轉效果,是用css動畫實現的,wxss文件以下:c#
.music { position: absolute; z-index: 99; -webkit-animation-iteration-count: infinite; } /* 旋轉class */ .music-on { animation: music-rotate 4s linear infinite; } /* 旋轉動畫 */ @keyframes music-rotate { 0% { transform: rotateZ(0deg); } 100% { transform: rotateZ(360deg); } }
當 rotate 爲true時,使 musicClass 的值爲 music-on,就能實現旋轉了。微信
固然, musicClass 須要用 this.setData 的方式來切換值。微信開發
爆醜照:
手動點擊時,用取反的邏輯控制音樂的播放和暫停:
_switch: function () { // 若是是播放就中止 if (this.data.audioStatus) { this.setData({ audioStatus: 0, icon: this.data.iconOff, musicClass: '' }) this.data.audioCtx.pause() // 若是是中止就播放 } else { this.setData({ audioStatus: 1, icon: this.data.iconOn, musicClass: 'music-on' }) this.data.audioCtx.play() } }
同時,還要對下列狀況作處理:
解決的方法,是在組件的methods中又寫了兩個方法:
// 寫在組件的methods中: // 在引用組件頁面的onShow()中調用 // 不然,若是當發生分享頁面行爲並返回時,音樂不會自動播放 onShow: function () { if (this.data.music && this.data.audioStatus) { this.data.audioCtx.play() } }, // 在引用組件頁面的onHide()中調用 // 不然,在跳轉到下一個頁面後,音樂還在繼續 onHide: function () { if (this.data.music && this.data.audioStatus) { this.data.audioCtx.pause() } this.setData({ animationData: {} }) }
這兩個方法分別在頁面中的 onShow 和 onHide 中調用,調用方式就是父組件獲取到子組件實例對象:
例如,給<music>
組件加id爲"music-componet",調用時就是:
// 寫在調用頁面中 onShow: function () { this.selectComponent('#music-component').onShow() }, onHide: function () { this.selectComponent('#music-component').onHide() }
最後,在組件的detached
中也調用一下 onHide 方法:
// 頁面關閉時銷燬音樂 detached() { this.onHide() }
你能夠