写在前面: js里面如果存在两个定时器,他们会相互影响。window.innerWidth是可视区域的宽度
1:
获取歌词数据。
这里获取歌词数据不像之前那么容易,qq音乐设置了防盗链,我们需要用本地的服务器去修改自己的header,用后台去获取到他的数据,然后再用axios向本地服务器请求数据。(关于webpack我会在之后单独写一篇文章)
新版的vue-cli构建工具没有了dev-server文件,你要配置本地服务器 要在webpack.dev.conf.js里面配置before(app)函数
当然,这里的axios返回的是一个promise对象,上面的图片的含义是,当axios请求成功厚,把得到的信息放在then方法里(就是res),再返回一个Promise解析成功的对象res.data。 然后我们思考,是不是每一首歌都有自己对应的歌词?对吧!,那我们就把getLyric封装到Song类里面去,并且将它再次封装为一个promise对象
然后这里还有好多坑:
1:
我们如果切换歌曲的时候回到了之前的歌曲,那他已经有lyric了,我们就不需要再获取一次增加开销,所以我们要加上前两句话
2:
得到的歌词是base64位加密的,所以我们要调用第三方库Base64解密它。解码之后返回一个promise对象,在player组件里面调用
3:
之前我们得到的只是一个字符串,但我们想让这个字符串跟着歌曲动起来,所以我们再用一个第三方库 lyricParser
它会将歌词字符串解析成一个对象(具体的大家可以去github上看文档)。
它还接受一个回调函数,当歌词的每一行变化的时候执行(具体功能下面会讲),那我们什么时候开始让这个歌词动起来呢?在currentSong改变的时候当然是个最好的时机啦!因为它同时也让歌曲播放了起来
2
接下来我们要让歌词滚动起来了
先添加一段dom结构,让它只有在currentLyric存在的时候才显示,并显示每一条歌词
我们要让它进行滚动,知道当前的歌词是哪一首。这样我们就必须知道当前歌词的行数,这时候就需要创建一个data: currentLineNumber
如果歌词的索引等于currentLineNumber就让它高亮,那我们怎么设置currentLineNumber呢? 这时候就要用到我在上面写的回调函数了,它在每次歌词换行的时候触发,且它接受一个对象,lineNum是歌词播放的行数,txt是当前行的歌词
这样我们就可以让它歌词开始播放,并且让当前的歌词进行高亮显示。
但是我们还不满足于此,我们要让每次滚动的歌词在屏幕中央
像这样,这样大家再回头看看哪个handler函数是不是就看懂了?
还有一个小功能,当你暂停歌曲的时候,就要暂停歌词的播放。即调用currentLyric的togglePlay方法
3
现在我们要实现cd页面和歌词页面两个互相滑动的效果
之前我们只是把lyric写在cdWrapper的右边,必须删除cdWrapper才看得到。我们现在就做一个滑动的效果。
这里的代码跟之前我们写progressBar组件的逻辑很像,都是滑动的时候记下第一次位置,滑动过程中记下最后的位置,滑动结束后执行一些动画。所以在cdWrapper外面的Dom结构添加事件监听
太过具体的我也不说了,都在我的注释上写着呢,只写一些容易弄混的点。在你滑动的时候lyric界面最多不能滑过左边,也不能离屏幕最右侧的距离大于0。所以要写下图的逻辑。当你的界面是cdWrapper 的时候,说明lyric界面离cdWrapper最右侧 0距离,当你是lyric界面的时候,则离最右侧-window.innerwidth距离。所以你往左划,lyric只能移动 -window.innerwidth宽度,向右滑,lyric最多只能移动0.注意这里是lyric移动的距离!!
还要有渐隐渐显动画,只要设置opacity和transition
但是我们还希望当你只滑动了10%的时候,我们让你自动滑过去,这样就要考虑两种可能。话不多说 大家仔细看代码
还有,你在touchend的时候设置了transitionDuration 那么在touchmove的时候要取消他,否则你的拖动会有延迟
4
最后,我们需要当你滑动progressBar的时候,歌词也要切换,这里我们要用到lyric Parser的seek()方法。
lyricParse内部有计时器用于播放歌词,当你切换歌的时候并没有清空currentLyric,所以会存在两个计时器,导致currentLyric在跳动。所以每次在切换歌曲的时候 如果之前的Song有currentLyric的话,要让它stop。(必须写在getLyric之前!!)