600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > vue 音乐播放器之歌词解析和滚动(js源码)

vue 音乐播放器之歌词解析和滚动(js源码)

时间:2019-08-25 15:36:49

相关推荐

vue 音乐播放器之歌词解析和滚动(js源码)

效果图

注:歌词和图片来源于网络

总体思路

①:请求歌词资源②:解析歌词,生成html代码③:html代码插入歌词显示的区域④:监听歌曲播放进度,通过id选择器选中正在播放的歌词添加样式⑤:判断条件是否滚动⑥:歌曲播放完毕清除样式,滚动到顶部

①:请求歌词资源

init() {//请求资源this.axios.get("/dataJson/musicList.json").then(response => {let {data, status } = response;//对象解析if (status != 200) return Error("资源请求出错");if(data.list[0].lyc!=undefined){//请求歌词this.axios.get(data.list[0].lyc).then(response=>{//vuex全局状态管理,触发changeInfo事件this.$mit("changeInfo", {name: data.list[0].name,singer: data.list[0].singer,lyc:response.data});})}});

json文件格式

{"list":[{"name":"他只是经过","singer":"h3R3","compose":"h3R3","src":"./music/test1.mp3","lyc":"./music/test1.mp3"}]}

vuex中state数据和mutations中的方法

state: {title: "歌名",msg: "歌曲附加信息",lyc: "",lycArr: []},mutations: {//只有在mutations中才能修改state状态changeInfo(state, newValue) {//修改信息state.title = newValue.name;state.msg = newValue.singer;state.lyc = newValue.lyc;}}

②:解析歌词,生成html代码

解析歌词在vuex的mutations中

initialize(state, lyc) {//解析歌词let lycArr = state.lyc.split("\n"); //拆分为数组for (let item of lycArr) {let flag = false;let arr = item.match(/\[(\d+:.+?)\]/g); //提取时间字段,可能有多个let start = 0;for (let k of arr) {start += k.length; //计算歌词位置(用于下一步提取歌词)}let content = item.substring(start); //提取从start提取文字一直到最后for (let value of arr) {let t = value.substring(1, value.length - 1); //取[]间的内容let s = t.split(":"); //分离:前后文字let time = (parseFloat(s[0]) * 60 + parseFloat(s[1])).toFixed(0);for (let t of state.lycArr) {if (time == t.time) {//防止时间重复flag = true;t.c += ` ${content}`;break;}}if (!flag) {//如果时间不重复state.lycArr.push({//对象{t:时间,c:歌词}加入ms数组time: time,c: content});}}}//生成htmllet html = `<p>${state.title}</p>`;for (let item of state.lycArr) {html += `<p id=${item.time}>${item.c}</p>`;}//插入展示区lyc.lycContainer.innerHTML = html;}

state.lycArr数组生成的结果如下

③:html代码插入歌词显示的区域

第二步mutations中,这行代码就是把html代码插入到歌词显示区

//插入展示区lyc.lycContainer.innerHTML = html;

现在数据已经有了,来看一下显示区样式

<template><div v-bind:class="{ lycContainer: true }"></div></template><style lang="less">.lycContainer {height: 100%;padding: 0.625rem;box-sizing: border-box;font-size: 0.55rem;text-align: center;overflow-x: hidden;overflow-y: auto;scrollbar-width: none;//兼容火狐浏览器,隐藏滚动条}.lycContainer::-webkit-scrollbar {//兼容webkit内核浏览器,隐藏滚动条display: none;}</style>

④:监听歌曲播放进度,通过id选择器选中正在播放的歌词添加样式

当点击开始播放按钮时,进行歌曲播放进度监听

start() {if (!this.startFlag) {this.$refs.startClick.src = "./publicImg/pause.png";//图片,立即替换为暂停按钮this.startFlag = true;sound.title = "暂停";this.lycContainerHeight = document.getElementsByClassName("lycContainer")[0].getBoundingClientRect().height.toFixed(0);sound.addEventListener("timeupdate", this.lycMonitor, false);// 在音频/视频(audio/video)的播放位置发生改变时触发。sound.addEventListener("ended", this.musicEnd, false);//在音频/视频(audio/video)播放结束触发sound.play();} else {this.$refs.startClick.src = "./publicImg/start.png";this.startFlag = false;sound.title = "播放";sound.pause();}

歌词滚动。通过下面lycMonitor函数进行歌词滚动

lycMonitor() {//歌词监听滚动let lycId = document.getElementById(sound.currentTime.toFixed(0));if (lycId) {if (lycId.offsetTop >(this.lycContainerHeight / 2 +lycId.getBoundingClientRect().height).toFixed(0)) {document.getElementsByClassName("lycContainer")[0].scrollTop = (lycId.offsetTop -this.lycContainerHeight / 2).toFixed(0);}lycId.previousSibling.removeAttribute("style");//因为每个id,都不一样。当前lycid播放时,移出上一个歌词样式lycId.style.cssText ="background: linear-gradient(-3deg,rgba(184,134,11,0.9) 0%,rgba(255,255,0,0.6) 60%);-webkit-background-clip: text;color: transparent;transform: scale(1.2);transition: all .5s ease-in;";//添加歌词样式}},

⑤:判断条件是否滚动

判断滚动条件如下

if (lycId.offsetTop >(this.lycContainerHeight / 2 +lycId.getBoundingClientRect().height).toFixed(0)) {document.getElementsByClassName("lycContainer")[0].scrollTop = (lycId.offsetTop -this.lycContainerHeight / 2).toFixed(0);}

当当前歌词距离页面顶部距离大于歌词显示区域一半加上当前歌词高度时,开始滚动

⑥:歌曲播放完毕清除样式,滚动到顶部

musicEnd() {document.getElementsByClassName("lycContainer")[0].lastChild.removeAttribute("style"); //删除最后一个p的stylelet timer = setInterval(() => {//匀速回到开头document.getElementsByClassName("lycContainer")[0].scrollTop -= 10;if (document.getElementsByClassName("lycContainer")[0].scrollTop == 0) {clearInterval(timer);}}, 10);}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。