Vue实现歌词解析+滚动效果

1.获取歌词(字符串格式)

调用接口,从后台拿到歌词数据,默认是字符串格式 像这样

 let lyric = "
 [by:小懒猫stad]
 [00:02.689]我多想回到那个夏天
 [00:05.939]蝉鸣在田边吹过眼睫
 [00:09.948]贪恋夏夜星空你侧脸
 [00:13.197]犹记得清风撩拨心弦
 [00:17.162]初夏的味道是你微笑
 [00:20.343]我捧着月亮别来无恙
 "

2.解析歌词 拿到时间和歌词存放在对象数组里

2.1 拿到每一行歌词

我们可以用正则匹配换行字符对字符串进行分割

const regNewLine = /\n/
const lineArr = lyric.split(regNewLine) // 每行歌词的数组

这样就拿到了每一行歌词的数组

2.2 分隔时间和歌词

这里用正则来匹配中括号里面的时间

const regTime = /\[\d{2}:\d{2}.\d{2,3}\]/

对lineArr数组进行遍历分隔

lineArr.forEach(item => {
 if (item === '') return
  const obj = {}
  const time = item.match(regTime)

  obj.lyric = item.split(']')[1].trim() === '' ? '' : item.split(']')[1].trim()
  obj.time = time ? this.formatLyricTime(time[0].slice(1, time[0].length - 1)) : 0
  obj.uid = Math.random().toString().slice(-6)
  if (obj.lyric === '') {
    console.log('这一行没有歌词')
  } else {
    lyricsObjArr.push(obj)
  }
})

这里需要注意的是 ①时间获取出来是包含中括号的,要用slice截取一下,并且要转成(秒.毫秒 88.9)格式 这样才方便与audio的currentTime进行对比 ②有些时间后面没有歌词,所以我们要把这一行给去掉 所有就有代码下面的if判断

这里有一个转换时间的函数 formatLyricTime 代码如下 比较粗糙

formatLyricTime (time) { // 格式化歌词的时间 转换成 sss:ms
     const regMin = /.*:/
     const regSec = /:.*\./
     const regMs = /\./

     const min = parseInt(time.match(regMin)[0].slice(0, 2))
     let sec = parseInt(time.match(regSec)[0].slice(1, 3))
     const ms = time.slice(time.match(regMs).index + 1, time.match(regMs).index + 3)
     if (min !== 0) {
       sec += min * 60
     }
     return Number(sec + '.' + ms)
   }

lyricsObjArr这就是最终生成的数组了格式是这样的:

lyricsObjArr : [
	{
		time: 34.5,
		lyric: '爱上你是我情非得已',
		uid: '234432'
	},
	{
		time: 64.5,
		lyric: 'WDNMD非得已',
		uid: '233332'
	}
]

3.循环数据 渲染dom

html结构

<ul ref="lyricUL">
   <li v-for="(item, i) in lyricsObjArr" :style="{color: lyricIndex === i ? 'skyblue' : '#ded9d9'}" :key="item.uid" :data-index='i' ref="lyric">{{item.lyric}}</li>
 </ul>

4.歌词滚动

audiotimeupdate事件进行监听 具体思路是:

循环 lyricsObjArr 数组 拿到时间并与 currentTime 进行对比 如果 currentTime 大于歌词时间 拿到当前 li 标签 data-index 的值 和循环的 i 进行对比 如果相同就更新data里面的 lyricIndex 值 用它来绑定颜色,同时控制外层 ul 标签的滚动 改变他的 transfrom:translateY() 的值。 具体代码如下

// 匹配歌词
for (let i = 0; i < this.lyricsObjArr.length; i++) {
    if (this.currentTime > (parseInt(this.lyricsObjArr[i].time))) {
      const index = this.$refs.lyric[i].dataset.index
      if (i === parseInt(index)) {
        this.lyricIndex = i
        this.$refs.lyricUL.style.transform = `translateY(${170 - (30 * (i + 1))}px)`
      }
    }
  }

5.总结

自己慢慢摸索做出来的,感觉还是不错!

  • 13
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值