Effect:
wxml:
<!-- 音乐列表 -->
<view class="musiclist">
<view class="mtitle">根据您的辨识结果,为您推荐一下音乐:</view>
<view class="list">
<view class="{
{ item.flag ? 'single play' : 'single' }}" wx:for="{
{ devices.files }}"
data-src="{
{ item.path }}" data-index="{
{ index }}" catchtap="playMusic">
<image src="{
{ item.flag ? '/static/images/icon/stop.png' : '/static/images/icon/startplay.png' }}" />
<text>{
{ item.name }}</text>
</view>
</view>
</view>
<!-- 单个播放 -->
<view class="musicsingle" data-index="{
{ tabindex }}" data-src="{
{ devices.files[tabindex].path }}" bindtap="playMusic">
<view class="myimg">
<image animation="{
{animationData}}" src="/static/images/index/musicpic.png" mode="aspectFill"/>
</view>
<text class="musicname">{
{ devices.files[tabindex].name }}</text>
<view class="myslider">
<slider class="slider-light" min="{
{ 0 }}" max="{
{ videoDuration }}" value="{
{ devices.files[tabindex].progress }}" activeColor="#944f4c" blockColor="#EFEFEF" bindchanging='sliderChange' activeColor='#E5A06D' block-size="{
{12}}" block-color="#fff"/>
</view>
<image class="playicon"
src="{
{ devices.files[tabindex].flag ? '/static/images/icon/play-y.png' : '/static/images/icon/stop-y.png' }}" />
</view>
wxss:
// slider滑块大小--估计得在父组件设置
.wx-slider-thumb {
width: 15rpx!important;
height: 15rpx!important;
top: 10rpx!important;
background: #fff;
}
.musiclist {
margin-top: 30rpx;
padding: 40rpx 36rpx;
background: #fff;
}
.musiclist .list .single {
display: flex;
padding: 20rpx;
box-sizing: border-box;
align-items: center;
box-shadow: 0rpx 4rpx 20rpx 0rpx rgba(193, 195, 205, 0.5);
border-radius: 16rpx;
margin-bottom: 24rpx;
}
.musiclist .list .single image {
width: 40rpx;
height: 40rpx;
margin-right: 8rpx;
}
.musiclist .list .single text {
color: #343A44;
font-size: 28rpx;
}
.musiclist .list .sinle:last-child {
margin-bottom: 0rpx;
}
.musiclist .list .play {
background: #3974FE;
}
.musiclist .list .play text {
color: #fff;
}
.musiclist .mtitle {
color: #343A44;
font-size: 30rpx;
font-weight: bold;
padding-left: 20rpx;
position: relative;
margin-bottom: 30rpx;
}
.musiclist .mtitle::before {
width: 6rpx;
top: 50%;
left: 0rpx;
content: '';
transform: translateY(-50%);
height: 28rpx;
background: #E5A06D;
border-radius: 4rpx;
position: absolute;
}
.musicsingle {
display: flex;
box-sizing: border-box;
align-items: center;
position: relative;
margin-top: 30rpx;
background: #fff;
padding: 36rpx;
}
.musicsingle .myslider {
width: 450rpx;
}
.musicsingle .myslider .slider-light {
margin: 0rpx;
}
.musicsingle .myimg {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
overflow: hidden;
margin-right: 18rpx;
padding: 18rpx;
background: #676767;
box-sizing: border-box;
}
.musicsingle .myimg image {
width: 100%;
height: 100%;
border-radius: 50%;
background: rgba(255, 192, 203, 0.377);
}
.musicsingle .playicon {
width: 40rpx;
height: 40rpx;
margin-left: 32rpx;
}
.musicsingle .musicname {
top: 45rpx;
left: 145rpx;
color: #333;
font-weight: bold;
position: absolute;
font-size: 30rpx;
font-size: 28rpx;
}
js:
数据格式---模拟musiclist数据
{
code: "",
flag:false,
id: "",
name: "",
path: "" ,
progress: 0,
}
data: {
devices: null,
musiclist: [],
tabindex: 0,
// new
videoDuration: 0, // 视频总时长
currentTime: '', // 播放时间
animationData: null,
rotateIndex: 1,
},
methods: {
// this.audioCtx = wx.createAudioContext('myAudio')
playMusic(e) {
let devices = this.data.devices //如果直接模拟的话,不需要devices。我们对接的数据是在musiclist外边有包了一个对象
let musiclist = devices.files
let index = e.currentTarget.dataset.index
let src = e.currentTarget.dataset.src
musiclist.forEach((ele, i) => {
if (index == i) {
ele.flag = !ele.flag
} else {
console.log("else")
ele.flag = false
}
})
this.data.audioCtx.src = src
if (musiclist[index].flag) {
this.data.audioCtx.pause()
this.data.audioCtx.play()
// 执行旋转或者点击图片旋转(如果你想要点击就在图片上添加点击事件我默认是添加的)
this.refreshList()
this.data.audioCtx.onTimeUpdate(() => {
let currentTime = this.data.audioCtx.currentTime
let duration = this.data.audioCtx.duration
musiclist[index].progress = currentTime
console.log("currentTime", duration)
devices.files = musiclist
this.setData({
devices,
currentTime: currentTime,
videoDuration: duration
})
})
} else {
this.data.audioCtx.pause()
this.stopRefresh()
}
this.setData({
devices,
tabindex: index
})
},
sliderChange(e) {
let value = e.detail.value
let devices = this.data.devices
devices.files[this.data.tabindex].progress = value
this.data.audioCtx.seek(value)
this.setData({
currentTime: value,
devices
})
},
refreshList() {
this.timeInterval = setInterval(function () {
let rotateIndex = this.data.rotateIndex + 1;
this.animation.rotate(30 * (this.data.rotateIndex - 1)).step()
let animationData = this.animation.export()
this.setData({
rotateIndex,
animationData
})
}.bind(this), 1000)
},
// 停止旋转
stopRefresh() {
if (this.timeInterval > 0) {
clearInterval(this.timeInterval)
this.timeInterval = 0
}
},
},
lifetimes: {
attached() {
// 创建播放对象
this.data.audioCtx = wx.createInnerAudioContext()
this.data.audioCtx.onCanplay(() => {
this.data.audioCtx.currentTime //监听进度变化必须有这一步
})
//创建动画对象
let animationData = wx.createAnimation({
duration: 0, //动画的时长
timingFunction: "ease", //动画的效果
delay: 0, //延迟执行的时间
transformOrigin: "50% 50%", //动画运行的基点坐标
})
this.animation = animationData
},
detached() {
// 在组件实例被从页面节点树移除时执行
},
},