文章目录
- 第一章 开发前的准备
- 一、项目展示
- 二、项目分析
- 三、项目初始化
- 第二章 标签页切换
- 一、任务分析
- 二、常用组件介绍
- 三、编写页面结构和样式
- 第三章 音乐推荐
- 一、任务分析
- 二、组件介绍
- 三、编写音乐推荐页面结构和样式
- 第四章 播放器
- 一、任务分析
- 二、组件介绍
- 三、实现播放器功能
- 四、编写播放器页面
- 第五章 播放列表
- 一、任务分析
- 二、实现播放列表功能
- 三、测试播放列表切换功能
第一章 开发前的准备
一、项目展示
音乐小程序项目效果展示
音乐推荐页面展示
播放器展示
播放列表展示
二、项目分析
- 音乐小程序项目页面结构:
1.tab导航栏2.content内容区3.player音乐播放器控件
- 音乐小程序项目目录结构
标签 | 功能 |
---|---|
app.js | 应用程序的逻辑文件 |
app.json | 应用程序的配置文件 |
pages/index/index.js | index页面的逻辑文件 |
pages/index/index.json | index页面的配置文件 |
pages/index/index.wxss | index页面的样式文件 |
三、项目初始化
- 开发者工具创建空白项目:
- 创建完成的页面
- 修改
app.json
{ "pages":[ "pages/index/index" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "音乐", "navigationBarTextStyle":"black" }, "style": "v2", "sitemapLocation": "sitemap.json"}
- 删除
index.wxml
、index.wxss
里的内容使其成为一个空白的页面
第二章 标签页切换
一、任务分析
- 标签页和页面(
info.wxml、play.wxml、palylist.wxml
)结构图:
二、常用组件介绍
swiper
常用属性:
可选值 | 说明 | 默认 |
---|---|---|
indicator-dots | Boolean | 是否显示面板指示点,默认为false |
indicator-color | Color | 指示点颜色,默认为rgba(0,0,0,.3) |
indicator-active-color | Color | 当前选中的指示点颜色,默认为#000000 |
autoplay | Boolean | 是否自动切换,默认为false |
current | Number | 当前所在滑块的index,默认为0 |
current-item-id | String | 当前所在滑块的item-id(不能同时指定current) |
interval | Number | 自动切换时间间隔(毫秒),默认为5000 |
duration | Number | 滑动动画时长(毫秒),默认为500 |
circular | Boolean | 是否采用衔接滑动,默认为false |
vertical | Boolean | 滑动方向是否为纵向,默认为false |
bindchange | EventHandle | current改变时会触发change事件 |
swiper
组件编写滑动页面结构:
<swiper> <swiper-item style="background:#ccc">0</swiper-item> <swiper-item style="background:#ddd">1</swiper-item> <swiper-item style="background:#eee">2</swiper-item></swiper>
三、编写页面结构和样式
- 在
pages/index/index.wxml
编写页面和tab
导航栏
<view class="tab"> <view class="tab-item {{tab==0" /> - 在
pages/index/index.wxss
编写页面样式和tab
导航栏样式
page { display: flex; flex-direction: column; background: #17181a; color: #ccc; height: 100%;}.tab { display: flex;}.tab-item { flex: 1; font-size: 10pt; text-align: center; line-height: 72rpx; border-bottom: 6rpx solid #eee;}.tab-item.active { color: #c25b5b; border-bottom-color: #c25b5b;}
- 添加页面
info.wxml、playlist.wxml、play.wxml
文件
- 实现标签页切换,通过滚动事件切换页面效果
<view class="tab"> <view class="tab-item {{tab==0" /> - 滚动事件
// tab切换 changeTab: function(e) { this.setData({ tab: e.detail.current }) },
- 通过滚动事件切换页面
第三章 音乐推荐
一、任务分析
- 音乐推荐页面结构图
二、组件介绍
scroll-view
组件的属性及说明
可选值 说明 默认 scroll-x Boolean 允许横向滚动,默认为false scroll-y Boolean 允许纵向滚动,默认为false scroll-top Number / String 设置竖向滚动条的位置 scroll-left Number / String 设置横向滚动条的位置 bindscrolltoupper EventHandle 滚动到顶部/左边时触发的事件 bindscrolltolower EventHandle 滚动到底部/右边时触发的事件 scroll-with-animation Boolean 滚动到顶部/左边时触发的事件 scroll-into-view String 设置哪个方向可滚动,则在哪个方向滚动到该元素。值应为某子元素id(id不能以数字开头) bindscroll EventHandle 滚动时触发的事件
三、编写音乐推荐页面结构和样式
- 在
info.wxml
里实现内容区域滚动和轮播图
<scroll-view class="content-info" scroll-y> <swiper class="content-info-slide" indicator-color="rgba(255,255,255,.5)" indicator-active-color="#fff" indicator-dots circular autoplay> <swiper-item> <image src="/images/banner.jpg" /> </swiper-item> <swiper-item> <image src="/images/banner.jpg" /> </swiper-item> <swiper-item> <image src="/images/banner.jpg" /> </swiper-item> </swiper></scroll-view>
.content-info { height: 100%;}::-webkit-scrollbar { width: 0; height: 0; color: transparent;}/* 轮播图 */.content-info-slide { height: 302rpx; margin-bottom: 20px;}.content-info-slide image { width: 100%; height: 100%;}
- 实现展示
- 在
info.html
里实现功能按钮
<view class="content-info-portal"> <view> <image src="/images/04.png" /> <text>私人FM</text> </view> <view> <image src="/images/05.png" /> <text>每日歌曲推荐</text> </view> <view> <image src="/images/06.png" /> <text>云音乐新歌榜</text> </view> </view>
/* 功能按钮 */.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;}
- 实现展示
flex
布局实现热门音乐的页面布局
<view class="content-info-list"> <view class="list-title">推荐歌曲</view> <view class="list-inner"> <view class="list-item"> <image src="/images/cover.jpg" /> <view>紫罗兰</view> </view> <view class="list-item"> <image src="/images/cover.jpg" /> <view>五月之歌</view> </view> <view class="list-item"> <image src="/images/cover.jpg" /> <view>菩提树</view> </view> <view class="list-item"> <image src="/images/cover.jpg" /> <view>欢乐颂</view> </view> <view class="list-item"> <image src="/images/cover.jpg" /> <view>安魂曲</view> </view> <view class="list-item"> <image src="/images/cover.jpg" /> <view>摇篮曲</view> </view> </view> </view>
/* 热门音乐 */.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;}
- 实现展示
- 在
index.wxml
里编写底部播放器
<view class="player"> <image class="player-cover" src="/images/cover.jpg" /> <view class="player-info"> <view class="player-info-title">钢琴协奏曲</view> <view class="player-info-singer">肖邦</view> </view> <view class="player-controls"> <image src="/images/01.png" bindtap="changePage" data-page="2" /> <image wx:if="{{state=='paused'}}" src="/images/02.png" bindtap="play" /> <image wx:else src="/images/02stop.png" bindtap="pause" /> <image src="/images/03.png" bindtap="next" /> </view></view></view>
- 底部播放器样式
/* 底部播放器 */.player { display: flex; align-items: center; background: #222; border-top: 1px solid #252525; height: 112rpx;}.player-cover { width: 80rpx; height: 80rpx; 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;}
- 测试效果
第四章 播放器
一、任务分析
- 播放器标签页结构图:
- 播放器具体功能分析
1.音乐信息:显示当前播放曲目的标题和艺术家2.专辑封面:当音乐播放时,专辑封面会顺时针旋转3.播放进度:显示播放进度,调节音乐进度
二、组件介绍
audioCtx
对象声明的方式
var audioCtx = wx.createInnerAudioContext();
- 音频
API
接口的属性及说明
可选值 名称 说明 属性 src 音频资源的地址,用于直接播放 startTime 开始播放的位置(秒),默认为0 autoplay 是否自动开始播放,默认为false loop 是否循环播放,默认为false volume 音量。范围0~1。默认为1 duration 音频的长度(秒)。在当前有合法的src时返回(只读) currentTime 音频的播放位置(秒)。在当前有合法的src时返回(只读) paused 开始播放的位置(秒),默认为0
三、实现播放器功能
- 在
index.js
里定义基础播放列表和音乐状态数据
/** * 页面的初始数据 */ data: { item: 0, tab: 0, // 播放列表数据 playlist: [{ id: 1, title: '玫瑰花的葬礼', singer: '许嵩', src: 'https://www.ytmp3.cn/down/78393.mp3', coverImgUrl: '/images/cover.jpg' }, { id: 2, title: '幻听', singer: '许嵩', src: 'https://www.ytmp3.cn/down/59696.mp3', coverImgUrl: '/images/cover.jpg' }, { id: 3, title: '清明雨上', singer: '许嵩', src: 'https://www.ytmp3.cn/down/36119.mp3', coverImgUrl: '/images/cover.jpg' }, { id: 4, title: '灰色头像', singer: '许嵩', src: 'https://www.ytmp3.cn/down/59697.mp3', coverImgUrl: '/images/cover.jpg' }], state: 'paused', playIndex: 0, play: { currentTime: '00:00', duration: '00:00', percent: 0, title: '', singer: '', coverImgUrl: '/images/cover.jpg', } },
- 在
index.js
编辑音乐播放逻辑代码
// 实现播放器播放功能 audioCtx: null, onReady: function() { this.audioCtx = wx.createInnerAudioContext() // 默认选择第1曲 this.setMusic(0) var that = this // 播放进度检测 this.audioCtx.onError(function() { console.log('播放失败:' + that.audioCtx.src) }) // 播放完成自动换下一曲 this.audioCtx.onEnded(function() { that.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 }) }) // 格式化时间 function formatTime(time) { var minute = Math.floor(time / 60) % 60; var second = Math.floor(time) % 60 return (minute < 10 " /> - 修改底部播放器的结构代码
<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="/images/01.png" bindtap="changePage" data-page="2" /> <image wx:if="{{state=='paused'}}" src="/images/02.png" bindtap="play" /> <image wx:else src="/images/02stop.png" bindtap="pause" /> <image src="/images/03.png" bindtap="next" /> </view></view>
- 底部播放器样式代码
/* 底部播放器 */.player { display: flex; align-items: center; background: #222; border-top: 1px solid #252525; height: 112rpx;}.player-cover { width: 80rpx; height: 80rpx; 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;}
- 底部播放器播放功能
- 在indexjs里编写底部播放器暂停/播放按钮控制歌曲以及播放器切换下一曲歌曲功能
// 播放按钮 play: function() { this.audioCtx.play() this.setData({ state: 'running' }) }, // 暂停按钮 pause: function() { this.audioCtx.pause() this.setData({ state: 'paused' }) }, // 下一曲按钮 next: function() { var index = this.data.playIndex >= this.data.playlist.length - 1 " /> - 测试底部播放功能
四、编写播放器页面
- 在
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.coverImgUrl}}" style="animation-play-state:{{state}}" /> </view> <view class="content-play-progress"> <text>{{play.currentTime}}</text> <view> <slider bindchange="sliderChange" activeColor="#d33a31" block-size="12" backgroundColor="#dadada" value="{{play.percent}}" /> </view> <text>{{play.duration}}</text> </view></view>
- 查看页面
- 在
index.wxss
编写播放器样式
/* 播放器 */.content-play { display: flex; justify-content: space-around; 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.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.coverImgUrl}}" /> <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>
- 查看结果
- 在
index.wxss
编写播放列表样式
/* 播放列表 */.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 { flex: 1; 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;}
- 查看结果
- 在
index.js
里实现播放列表的切换功能
// 播放列表换曲功能 change: function(e) { this.setMusic(e.currentTarget.dataset.index) this.play() }
三、测试播放列表切换功能
- 播放列表测试