之前在B站上面看到一个视频:
https://www.bilibili.com/video/BV1Yz411z7An?t=16
感觉它的这个播放器挺好看的,原作者是用的PPT制作。
我的设计灵感一向很差,叫我自己设计UI一般会非常难看,于是就准备仿照他这个,用Vue通过web的形式,参照他的界面,做一款播放器玩玩。
目标
制作一个简单的播放器,拥有播放,暂停,上一首,下一首,歌曲列表等功能。音乐数据就通过axios
从我的后端服务器上面取得。
准备
既然有了目标,那么首先就需要创建一个Vue工程:
vue create music_player
注意:Vue的工程名称不能包含大写,但是可以有下划线。
因为是复刻嘛,想要做到完全一样难度还是比较大的,所以就大概相似就差不多了,我就使用Vant作为UI。
Vant UI – 快速上手youzan.github.io
该工程一看就是一个手机版的播放器,所以我还引入了rem
文件:
(function (doc, win) {
const docEl = doc.documentElement;
const resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
const recalc = function () {
const { clientWidth } = docEl;
if (!clientWidth) return;
docEl.style.fontSize = `${100 * (clientWidth / 375)}px`;
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
}(document, window));
该文件是为了使页面自适应。该文件的意思是100px
为0.1rem
,所以我们之后使用的所有px
都要换算成为rem
。
调试模式
因为主要是做的移动端的项目,所以需要将浏览器的调试模式设置为iPhone 6/7/8,这也是现在移动端开发最为主流的分辨率。但是后面我将模式切换到了iPhone X…因为iPhone 6模式下整个界面显得有点拥挤。
搭建界面
搭建界面几乎没有什么难度,CSS样式需要一点点的慢慢调整,最后调整到合适的样式。
先简单的搭出一个界面,等到跑通业务逻辑后,我们再来进行微调。
Vuex
这种播放器之间的数据传递还是需要使用Vuex如果单靠组件之间的单向传递,那可是太麻烦了。
从这里开始我将调试模式改为了iPhone X
我放入Vuex管理的数据有:
state: {
/* 歌曲列表 */
musicList: [{
id: 0, // 歌曲id
musicName: '',// 歌曲名字
musicSinger: '',// 歌手名字
musicImg: '',// 歌曲图片
musicUrl: '',// 歌曲地址
}],
/* 音乐是否在播放 */
musicStatus: false,
// 当前播放的音乐
musicIndex: 0,
// 管理音乐
music: {
play: Function,
pause: Function,
},
},
可以看到,集成Vuex后这些数据进行了正常显示,并且点击右下角的播放按钮,歌曲也能进行播放。
放到Vuex进行管理有个最大的好处就是,所有数据都只存在一份,如果一旦一个地方改变了数据,那么其它引用该数据的地方都会进行改变,比如:
可以看到,在第二个界面改变了数据后,第一个界面也发生了变化
剩下的就是播放动画了。
音乐频率图
由于最开始创建项目的时候我勾选了sass,所以这个音乐频率图用sass来做是十分快捷的。
/* 声明动画 */
@keyframes move {
from {
transform: translateY(0);
}
to {
transform: translateY(50px);
}
}
/* 因为上面有70个div所以这里就用sass的循环,如果是css就只有一个一个的添加 */
@for $i from 1 through 70 {
&:nth-child(#{$i}) {
/* 使用随机数声明 */
animation: move linear 0.5s ((random(1000)-500)/1000+s) infinite alternate;
}
}
最后微调
最主要是将开始的字体,行距,居中显示这些内容进行优化,因为开始只是大概的搭了一个界面后就先去做业务逻辑部分了,所以页面中还是有很多需要优化的地方。
进度条优化
根据音乐当前播放时间和总时间,计算出音乐进度,将小于这个值的进度条都附加上一个更换背景颜色的类。
<div v-for="(i,index) in 40" :key="index"
:class="`hight ${musicPlay?'anima':''} ${progress>index?'progress':''}`">
</div>
.progress {
background: #123a70;
}
计时器
this.timer = setInterval(() => {
this.progress = Math.floor((this.musicTime / this.music) * 40);
console.log(this.progress);
}, 1000);
// 页面销毁后销毁定时器
destroyed() {
clearInterval(this.timer);
},
因为播放进度是通过setInterval
每秒钟进行计算,所以计时器一定要在页面被销毁的时候一起给销毁掉,不然计时器会越来越多。
总结
整个播放器的制作不难,难点在于Vuex的使用,该项目里面可能会有很多隐藏的BUG,或者体验不佳的地方,因为只做了个大概,没有太在意细节部分,如果一个项目要上线还是要经过不断的测试优化。