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.domslet liHieght = ul.children[0].clientHeightlet containerHeight = container.clientHeightlet ulHeight = ul.clientHeightlet index = this.findIndex();let oldLi = ul.querySelector('.active')if(oldLi){oldLi.classList.remove('active')}let offset = liHieght * index + liHieght / 2 - containerHeight / 2let 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.domsaudio.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.效果
歌词滚动效果