1. 效果
1. 逻辑
- 点击首页的每日推荐,跳转到推荐页面
- 推荐页面进行判断,如果没有登录重定向到登录页面; 如果已经登录就获取推荐列表并且进行展示
- 点击音乐能跳转到音乐详情页
- 音乐详情页可以进行播放暂停;同时可以上一首、下一首进行切换
2. 界面展示
- 推荐页面
- 详情页面
2. 核心知识点
1. 推荐页面-顶部日期定位
父元素设置为relative 相对定位; 当前日期元素设置为绝对定位
.recommendSongContainer .header {
position: relative;
width: 100%;
height: 300rpx;
}
.recommendSongContainer .header image {
width: 100%;
height: 100%;
}
.recommendSongContainer .header .date {
position: absolute;
left: 50%;
top: 50%;
margin-left: -150rpx;
margin-top: -50rpx;
width: 300rpx;
height: 100rpx;
text-align: center;
line-height: 100rpx;
color: #fff;
}
.header .date .day {
font-size: 38rpx;
}
2. 详情页-摇杆与头像的动画(旋转一定角度)
默认摇杆提起来,旋转-20度。播放的时候摇杆落下。 根据当前是否在播放然后加对应的class,根据class 展示效果。
- Css 两个class 效果
/* 摇杆 */
.needle {
position: relative;
z-index: 99;
top: -40rpx;
left: 60rpx;
width: 192rpx;
height: 274rpx;
transform-origin: 40rpx 0;
transform: rotate(-20deg);
transition: transform 1s;
}
.needleRotate {
transform: rotate(0deg);
}
- 摇杆类上class 控制
<image class="needle {{isPlay && 'needleRotate'}}" src="/static/images/song/needle.png"></image>
这里有个根据isPlay 动态判断class是否加 needleRotate 的判断。
3. 详情页-头像旋转(整体元素转圈)
默认头像不转,当播放音乐的时候头像进行旋转。和上面摇杆一样,采用动态class 元素+c3来实现。
- css
/* 磁盘 */
.discContainer {
position: relative;
top: -170rpx;
width: 598rpx;
height: 598rpx;
}
.discAnimation {
animation: disc 4s linear infinite;
animation-delay: 1s;
}
/*
@keyframes: 设置动画帧
1) from to
- 使用于简单的动画,只有起始帧和结束帧
- 北京 - 上海 直达
2) 百分比
- 多用于复杂的动画,动画不止两帧
- 北京 - 上海 ---> 北京 -- 天津 --- 深圳 --- 上海
- 0% - 100%, 可以任意拆分
*/
- 头像上class控制
<view class="discContainer {{isPlay && 'discAnimation'}}">
<image class="disc" src="/static/images/song/disc.png"></image>
<image class="musicImg" src="{{song.al.picUrl}}"></image>
</view>
4. 详情页-音乐播放
wx.getBackgroundAudioManager() 获取全局唯一的背景音频管理器。
小程序切入后台,如果音频处于播放状态,可以继续播放。但是后台状态不能通过调用API操纵音频的播放状态。
若需要在小程序切后台后继续播放音频,需要在 app.json中配置 requiredBackgroundModes 属性。
实例代码:
const backgroundAudioManager = wx.getBackgroundAudioManager()
backgroundAudioManager.title = '寂寞沙洲冷'
backgroundAudioManager.epname = '寂寞沙洲冷'
backgroundAudioManager.singer = '于潼'
backgroundAudioManager.coverImgUrl = 'https://p1.music.126.net/-GVV1FnjB3iawDY0yyHOBg==/109951165048523233.jpg'
// 设置了 src 之后会自动播放
backgroundAudioManager.src = 'http://m801.music.126.net/20230730192632/da76bfd77d56c673c7fc00d1f6d14e9d/jdymusic/obj/wo3DlMOGwrbDjj7DisKw/14096641426/b997/eb2b/3ea7/e4bb8998c7b2c29cf8a9b2e29668f54b.mp3'
和视频管理器一样,有核心的方法回调: (下面的API是点击微信自带的音频控制器的回调)
// 创建控制音乐播放的实例
this.backgroundAudioManager = wx.getBackgroundAudioManager();
// 监视音乐播放/暂停/停止
this.backgroundAudioManager.onPlay(() => {
this.changePlayState(true);
// 修改全局音乐播放的状态
appInstance.globalData.musicId = musicId;
});
this.backgroundAudioManager.onPause(() => {
this.changePlayState(false);
});
this.backgroundAudioManager.onStop(() => {
this.changePlayState(false);
});
// 监听音乐播放自然结束
this.backgroundAudioManager.onEnded(() => {
// 自动切换至下一首音乐,并且自动播放
PubSub.publish('switchType', 'next')
// 将实时进度条的长度还原成 0;时间还原成 0;
this.setData({
currentWidth: 0,
currentTime: '00:00'
})
});
// 监听音乐实时播放的进度
this.backgroundAudioManager.onTimeUpdate(() => {
// console.log('总时长: ', this.backgroundAudioManager.duration);
// console.log('实时的时长: ', this.backgroundAudioManager.currentTime);
// 格式化实时的播放时间
let currentTime = moment(this.backgroundAudioManager.currentTime * 1000).format('mm:ss')
let currentWidth = this.backgroundAudioManager.currentTime/this.backgroundAudioManager.duration * 450;
this.setData({
currentTime,
currentWidth
})
})
5. 详情页-保存页面级数据
将音乐的数据进行保存,当点击回退重新进入页面可以正确的显示数据。 第一种是存到本地,第二种是存到全局数据App.js 中。相当于全局数据,页面销毁数据还在,重新加载应用数据才会初始化。
- app.js 加数据
App({
// 全局数据
globalData: {
isMusicPlay: false, // 是否有音乐在播放
musicId: '' // 音乐id
},
...
- 页面js 使用, songDetail.js
import PubSub from 'pubsub-js';
import moment from 'moment'
import request from '../../utils/request'
// 获取全局实例
const appInstance = getApp();
...
if(appInstance.globalData.isMusicPlay && appInstance.globalData.musicId === musicId){
...
6. 详情页-页面通信(npm 模块使用)
详情页点击下一页,需要从推荐页面获取数据就涉及到页面通信。需要用到npm。
PubSubJS 是一个用 JavaScript 编写的基于主题的 发布/订阅库。PubSubJS 有同步解耦,所以主题是异步发布的。这有助于使您的程序保持可预测性,因为在消费者处理主题时,主题的发起者不会被阻止。
- 项目根路径执行:
npm init -y
- 安装相关模块
npm install pubsub-js
安装之后的目录在node_modules。
- 安装之后, 需要在微信开发者工具-》工具-》构建npm,然后会生成miniprogram_npm
- 简单使用
import PubSub from 'pubsub-js';
PubSub.subscribe('musicId', (msg, data) => {
console.log(msg, data); // musicId data111222
// 取消订阅
PubSub.unsubscribe('musicId');
})
PubSub.publish('musicId', 'data111222')
7. 详情页-音乐播放时长格式化
- 安装moment 包
npm install moment
- 使用
import moment from 'moment'
let currentTime = moment(35 * 1000).format('mm:ss')
console.log("currentTime", currentTime)
8. 详情页-进度条展示
思路是一个固定宽度为450rpx 的进度条,然后根据当前播放的时长与总时长的比例计算已经播放的宽度。
- wxml
<!-- 进度条控制区域 -->
<view class="progressControl">
<text>{{currentTime}}</text>
<!-- 总进度条 -->
<view class="barControl">
<!-- 实时进度条 -->
<view class="audio-currentTime-Bar" style="width: {{currentWidth + 'rpx'}}">
<!-- 小圆球 -->
<view class="audio-circle"></view>
</view>
</view>
<text>{{durationTime}}</text>
</view>
- wxss
/* 进度条控制区域 */
.progressControl {
position: absolute;
bottom: 200rpx;
width: 640rpx;
height: 80rpx;
line-height: 80rpx;
display: flex;
}
.barControl {
position: relative;
width: 450rpx;
height: 4rpx;
background: rgba(0, 0, 0, 0.4);
margin: auto;
}
.audio-currentTime-Bar {
position: absolute;
top: 0;
left: 0;
z-index: 1;
height: 4rpx;
background: red;
}
- js 实时计算宽度
// 监听音乐实时播放的进度
this.backgroundAudioManager.onTimeUpdate(() => {
// console.log('总时长: ', this.backgroundAudioManager.duration);
// console.log('实时的时长: ', this.backgroundAudioManager.currentTime);
// 格式化实时的播放时间
let currentTime = moment(this.backgroundAudioManager.currentTime * 1000).format('mm:ss')
let currentWidth = this.backgroundAudioManager.currentTime/this.backgroundAudioManager.duration * 450;
this.setData({
currentTime,
currentWidth
})
标签:currentTime,微信,音乐,详情页,backgroundAudioManager,播放,页面
From: https://www.cnblogs.com/qlqwjy/p/17598879.html