赞
踩
此设计界面比较简陋,请大家海涵。针对初学者的布局与js的结合用法
1.运用到了view、swiper(滑块视图容器)、swiper-item、include(跳转到自己的页面)、image(放置图片)、block(占位符)、slider(滑动选择)、scroll-view(可滚动视图区域)等标签。理解所涉及标签的方法和属性。
1.index.wxml
<!-- 上导航部分 --> <view class="tab"> <view class="tab-item {{tab==0?'active':''}}" bindtap="changeitem" data-item="0">音乐播放</view> <view class="tab-item {{tab==1?'active':''}}" bindtap="changeitem" data-item="1">播放器</view> <view class="tab-item {{tab==2?'active':''}}" bindtap="changeitem" data-item="2">播放列表</view> </view> <!-- 内容 --> <view class="content"> <!-- 滑块视图容器 current当前所在滑块的 index--> <swiper current="{{item}}" bindchange="changetab"> <swiper-item> <!-- 跳转当前自己的文件 --> <include src="info.wxml"></include> </swiper-item> <swiper-item> <include src="play.wxml"></include> </swiper-item> <swiper-item> <include src="playlist.wxml"></include> </swiper-item> </swiper> </view> <!-- 音乐导航底部 --> <view class="player"> <image class="player-cover" src="{{play.coverImgUrl}}" /> <view class="player-info"> <view class="player-info-title">{{play.title}}</view> <view class="player-info-singer">{{play.singer}}</view> </view> <view class="player-controls"> <!-- 切换到播放列表 --> <image src="http://localhost:3000/images/16.png" bindtap="changePage" data-page="2" /> <!-- 播放或暂停 --> <image wx:if="{{state=='paused'}}" src="http://localhost:3000/images/17.png" bindtap="play" /> <image wx:else src="http://localhost:3000/images/19.png" bindtap="pause" /> <!-- 下一曲 --> <image src="http://localhost:3000/images/18.png" bindtap="next" /> </view> </view>
2.info.wxml
<swiper indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}"> <block wx:for="{{imgUrls}}" wx:key="unique"> <swiper-item> <image src="{{item}}" class="slide-imge" style="width: 100%;"></image> </swiper-item> </block> </swiper> <view class="content-info-portal"> <view> <image src="http://localhost:3000/images/22.png"></image> <text>私人FM</text> </view> <view> <image src="http://localhost:3000/images/20.png"></image> <text>每日歌曲推荐</text> </view> <view> <image src="http://localhost:3000/images/21.png"></image> <text>云音乐新歌榜</text> </view> </view> <view class="content-info-list"> <view class="list-title">推荐歌曲</view> <view class="list-inner"> <view class="list-item"> <image src="http://localhost:3000/images/05.png"></image><view>流行--歌曲</view> </view> <view class="list-item"> <image src="http://localhost:3000/images/06.png"></image><view>经典--歌曲</view> </view> <view class="list-item"> <image src="http://localhost:3000/images/07.png"></image><view>民谣--歌曲</view> </view> <view class="list-item"> <image src="http://localhost:3000/images/08.png"></image><view>火爆--歌曲</view> </view> <view class="list-item"> <image src="http://localhost:3000/images/09.png"></image><view>翻唱--歌曲</view> </view> <view class="list-item"> <image src="http://localhost:3000/images/10.png"></image><view>温情--歌曲</view> </view> </view> </view>
3.play.wxml
<view class="content-play"> <!-- 显示音乐信息 --> <view class="content-play-info"> <text>{{play.title}}</text> <view>--{{play.singer}}--</view> </view> <!-- 专题封皮 --> <view class="content-play-cover"> <image src="{{play.coverImgeUrl}}" style="animation-play-state: {{stata}};"></image> </view> <view class="content-play-progress"></view> <!-- 播放进度和时间 --> <view class="content-play-progress"> <text>{{play.currentTime}}</text> <view> <!-- 滑动选择器 --> <slider bindtap="sliderChange" activeColor="#d33a31" block-size="12" backgroundColor="#dadada" value="{{play.percent}}"></slider> </view> <text>{{play.duration}}</text> </view> </view>
4.playlist.wxml
<scroll-view class="content-playlist" scroll-y>
<view class="playlist-item" wx:for="{{playlist}}" wx:key="id" bindtap="change" data-index="{{index}}">
<image class="playlist-cover" src="{{item.coverImgeUrl}}" />
<view class="playlist-info">
<view class="playlist-info-title">{{item.title}}</view>
<view class="playlist-info-singer">{{item.singer}}</view>
</view>
<view class="playlist-controls">
<text wx:if="{{index==playIndex}}">正在播放</text>
</view>
</view>
</scroll-view>
page{ display: flex; flex-direction: column; background: #141b10; color: #ccc; height: 100%; } .tab{ /* r让他变成伸缩盒子 */ display: flex; } .tab-item{ flex: 1; font-size: 10pt; text-align: center; line-height: 72rpx; height: 72rpx; border-bottom: 6rpx solid #eee; } /* 激活当前选项 */ .tab-item.active{ color: #c25b5b; border-bottom-color:#c25b5b; } .content{ flex: 1; } .content > swiper{ /* 宽度给其自适应 */ height: 100%; } .player{ background: #222; border-top: 2rpx solid #252525; height: 112rpx; } .slide-image{ width: 100%; height: 100%; } .content-slide-imge{ height: 30rpx; margin-bottom: auto; } .content-info-portal{ display: flex; margin-bottom: 15px; } .content-info-portal > view{ flex: 1; font-size: 11pt; text-align: center; } .content-info-portal image{ width: 120rpx; height: 120rpx; display: block; margin: 20rpx auto; } .content-info-list{ font-size: 11pt; margin-bottom: 20rpx; } .content-info-list > .list-title{ margin: 20rpx 35rpx; } .content-info-list > .list-inner{ display: flex; flex-wrap: wrap; margin: 0 20rpx; } .content-info-list > .list-inner > .list-item{ flex: 1; } .content-info-list > .list-inner > .list-item > image{ display: block; width: 200rpx; height: 200rpx; margin: 0 auto; border-radius: 10rpx; border: 1rpx solid #555; } .content-info-list > .list-inner > .list-item > view{ width: 200rpx; margin: 10rpx auto; font-size: 10pt; } /* 音乐导航底部 */ .player { display: flex; align-items: center; background: #222; border-top: 1px solid #252525; height: 112rpx; } .player-cover { width: 100rpx; height: 100rpx; margin-left: 15rpx; border-radius: 8rpx; border: 1px solid #333; } .player-info { flex: 1; font-size: 10pt; line-height: 38rpx; margin-left: 20rpx; padding-bottom: 8rpx; } .player-info-singer { color: #888; } .player-controls image { width: 80rpx; height: 80rpx; margin-right: 15rpx; } /* 播放器页面样式 */ .content-play{ display: flex; /* 让排布均匀分布 */ justify-content: space-around; /* 决定主轴,从上到下排列 还有一个从左到右row,相反则加-reverse*/ flex-direction: column; height: 100%; text-align: center; } .content-play-info > view{ color: #888; font-size: 11pt; } .content-play-cover image{ animation: rotateImage 10s linear infinite; width: 400rpx; height: 400rpx; border-radius: 50%; border: 1px solid #333; } @keyframes rotateImage{ from{ transform: rotate(0deg); } to{ transform: rotate(360deg); } } .content-play-progress{ display: flex; align-items: center; margin: 0 35rpx; font-size: 9pt; text-align: center; } .content-play-progress > view{ flex: 1; } /* 页面结构 */ .playlist-item{ display: flex; align-items: center; border-bottom: 1rpx solid #333; height: 112rpx; } .playlist-cover{ width: 80rpx; height: 80rpx; margin-left: 15rpx; border-radius: 8rpx; border: 1px solid #333; } .playlist-info{ float: 1px; font-size: 10pt; line-height: 38rpx; margin-left: 20rpx; padding-bottom: 8rpx; } .playlist-info-singer{ color: #888; } .playlist-controls{ font-size: 10pt; margin-right: 20rpx; color: #c25b5b; } /* 播放和暂停的效果 */ .player-play > image:first-child{ animation-play-state: running; } .player-play > image:last-child{ animation: musicStart 0.2s linear forwards; } .player-pause > image:first-child{ animation-play-state: paused; } .player-pause > image:last-child{ animation: musicStop 0.2s linear forwards; } @keyframes musicStart{ from{transform: rotate(0deg);} to{transform: rotate(20deg);} } @keyframes musicStop{ from{transform: rotate(20deg);} to{transform: rotate(0deg);} }
data:{
变量:值
}
数组名称:[…]
绑定设置的名称:function(){ 方法 }
绑定设置的名称:function(){
this.setData({ console.log(); })
}
// index.js // 获取应用实例 const app = getApp() Page({ data:{ item:0, tab:0, isPlayingMusic:false, playlist:[ { id:0,title:'钢琴曲',singer:'肖邦',src:'http://localhost:3000/images/song.mp3',coverImgeUrl:'http://localhost:3000/images/11.png' }, { id:1,title:'奏鸣曲',singer:'莫扎特',src:'http://localhost:3000/images/song.mp3',coverImgeUrl:'http://localhost:3000/images/12.png' }, { id:2,title:'欢乐颂',singer:'贝多芬',src:'http://localhost:3000/images/song.mp3',coverImgeUrl:'http://localhost:3000/images/13.png' }, { id:3,title:'爱之梦',singer:'李斯特',src:'http://localhost:3000/images/song.mp3',coverImgeUrl:'http://localhost:3000/images/14.png' }, ], stata:'paused', playIndex:0, play:{ currentTime:'00:00', duration:'00:00', percent: 0, title:'', singer:'', coverImgeUrl:'http://localhost:3000/images/11.png', }, imgUrls:[ "http://localhost:3000/images/01.png", "http://localhost:3000/images/02.png", "http://localhost:3000/images/03.png", "http://localhost:3000/images/04.png" ], indicatorDots:true, autoplay:true, interval:3000, duration:500, }, changeitem(e){ // 获取点击的索引数据 this.setData({ // 给这个item赋值 item:e.target.dataset.item }) }, changetab(e){ this.setData({tab:e.detail.current}) }, audioCtx:null, onReady:function(){ // 音乐接口 this.audioCtx = wx.createInnerAudioContext() //调用 this.setMusic(0) }, setMusic(index){ var music = this.data.playlist[index] this.audioCtx.src = music.src this.setData({ playIndex:index, 'play.title':music.title, 'play.singer':music.singer, 'play.coverImgUrl':music.coverImgeUrl, 'play.currentTime':'00:00', 'play.duration':'00:00', 'play.percent':0 }) }, //播放 play: function(){ this.audioCtx.play() this.setData({ state:'running'}) }, //暂停 pause: function(){ this.audioCtx.pause() this.setData({ state:'paused'}) }, next: function(){ // 如果满足,就等于0,不满足就加一 var index = this.data.playIndex >= this.data.playlist.length - 1?0: this.data.playIndex + 1 this.setMusic(index) if (this.data.state ==='running'){ this.play() }else{ this.pause() } }, //点击下一曲 changer:function(e){ this.setMusic(e.Target.dataset.index) this.play() }, onReady:function(){ this.audioCtx = wx.createInnerAudioContext() var that = this // 播放失败检测 this.audioCtx.onError(function(){ console.log('播放失败:'+ that.audioCtx.src) }) // 播放完成自动换下一曲 this.audioCtx.onEnded(function(){ thta.next() }) // 自动更新播放进度 this.audioCtx.onPlay(function(){}) this.audioCtx.onTimeUpdate(function(){//音乐播放,进度更新就触发 that.setData({ 'play.duration':formatTime(that.audioCtx.duration),//滑动时间 'play.currentTime':formatTime(that.audioCtx.currentTime),//总时长 'play.percent':that.audioCtx.currentTime / that.audioCtx.duration * 100 }) }) // 默认选择第一曲 this.setMusic(0) // 格式化时间 function formatTime(time){ var minute = Math.floor(time / 60) % 60; var second = Math.floor(time) % 60 return (minute < 10 ? '0' + minute: minute) + ':' + (second < 10 ? '0' + second : second) } }, //进度条到哪,就播放到哪 sliderChange: function(e){ var second = e.detail.value * this.audioCtx.duration / 100 this.audioCtx.seek(second) }, sliderChanging:function(e){ console.log(e.detail.value) }, })
1.如果还不会用node的同学,可以跟一下以下教程:
下载地址与教程:https://nodejs.org/en/download/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。