阅读量:0
1.结构
<template> <div class="lyricScroll"> <div class="audio"> <audio id="audio" src="./common/周传雄-青花1.mp3" controls></audio> </div> <div class="container" id="container"> <ul id="ul"> <li v-for="item in dataArr" :key="item.time"> {{ item.word }} </li> </ul> </div> </div> </template> <script> import {data} from "./common/data"; export default { name: 'lyricScroll', data() { return { dataArr: [], doms: {} } }, mounted(){ this.parseLrc() this.getDoms() this.audioTimeUpdata() }, methods:{ /** * 获取dom */ getDoms(){ this.doms['audio'] = document.getElementById("audio") this.doms['container'] = document.getElementById("container") this.doms['ul'] = document.getElementById("ul") }, /** * 将字符串转为对象数组[{ time: 0, word: 'x' }] */ parseLrc(){ let lines = data.split('\n'); this.dataArr = lines.map(item => { return { time: this.parseTime(item.split(']')[0].split("[")[1]), word: item.split(']')[1] } }) }, /** * 将时间字符串转为数字(秒) * @param {String} timeStr 时间字符串 * @param {Number} offset 设置时间偏移 */ parseTime(timeStr, offset = 0.5){ let parts = timeStr.split(":"); return +parts[0] * 60 + +parts[1] - offset }, /** * 计算出,在当前播放器播放到第几秒的情况下,应该高亮的歌词下标 */ findIndex(){ let curTime = this.doms.audio.currentTime; let nowIndex = this.dataArr.findIndex(item => { return item.time > curTime }) return nowIndex != -1 ? nowIndex - 1 : this.dataArr.length - 1 }, /** * 设置ul的偏移量 */ setOffset(){ let { ul, container } = this.doms let liHieght = ul.children[0].clientHeight let containerHeight = container.clientHeight let ulHeight = ul.clientHeight let index = this.findIndex(); let oldLi = ul.querySelector('.active') if(oldLi){ oldLi.classList.remove('active') } let offset = liHieght * index + liHieght / 2 - containerHeight / 2 let resultOffset = offset < 0 ? 0 : (offset > ulHeight ? ulHeight : offset) ul.style.transform = `translateY(${-resultOffset}px)` ul.children[index].classList.add('active') }, /** * 给audio监听时间轴改变事件 */ audioTimeUpdata(){ let { audio } = this.doms audio.addEventListener('timeupdate', this.setOffset) } } }; </script> <style lang="less" scoped> * { margin: 0; padding: 0; } .lyricScroll { width: 100%; height: 100%; background: black; display: flex; flex-direction: column; align-content: center; .audio{ audio{ width: 400px; margin: 0 auto; display: block; } } .container { flex: 1; overflow: hidden; ul { transition: 0.6s; li { height: 50px; line-height: 50px; transition: 0.3s; text-align: center; font-size: 30px; &.active{ color: #fff; font-size: 40px; } } } } }</style>
2.效果
歌词滚动效果