vue实现歌词滚动
Vue 实现歌词滚动功能
歌词滚动是音乐播放器中常见的功能,可以通过 Vue 的动态数据绑定和动画效果实现。以下是实现歌词滚动的几种方法。
使用 CSS 动画和动态样式
通过绑定当前播放时间的歌词行高亮样式,结合 CSS 的滚动效果实现平滑过渡。
<template>
<div class="lyrics-container" ref="lyricsContainer">
<div
v-for="(line, index) in lyrics"
:key="index"
:class="{ 'active': currentLine === index }"
class="lyric-line"
>
{{ line.text }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
lyrics: [
{ time: 0, text: "第一行歌词" },
{ time: 5, text: "第二行歌词" },
{ time: 10, text: "第三行歌词" }
],
currentLine: 0,
currentTime: 0
};
},
methods: {
updateCurrentLine(time) {
this.currentTime = time;
for (let i = 0; i < this.lyrics.length; i++) {
if (time >= this.lyrics[i].time) {
this.currentLine = i;
}
}
this.scrollToCurrentLine();
},
scrollToCurrentLine() {
const container = this.$refs.lyricsContainer;
const activeLine = container.querySelector('.active');
if (activeLine) {
container.scrollTo({
top: activeLine.offsetTop - container.offsetHeight / 2,
behavior: 'smooth'
});
}
}
}
};
</script>
<style>
.lyrics-container {
height: 300px;
overflow-y: auto;
scroll-behavior: smooth;
}
.lyric-line {
padding: 8px;
text-align: center;
}
.lyric-line.active {
color: #42b983;
font-weight: bold;
}
</style>
结合第三方库实现
如果需要更复杂的滚动效果,可以使用第三方库如 better-scroll 或 vue-seamless-scroll。
安装 better-scroll:
npm install better-scroll
实现代码:
<template>
<div ref="lyricsWrapper" class="lyrics-wrapper">
<div class="lyrics-content">
<div
v-for="(line, index) in lyrics"
:key="index"
:class="{ 'active': currentLine === index }"
class="lyric-line"
>
{{ line.text }}
</div>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll';
export default {
data() {
return {
lyrics: [],
currentLine: 0,
bs: null
};
},
mounted() {
this.initScroll();
},
methods: {
initScroll() {
this.bs = new BScroll(this.$refs.lyricsWrapper, {
probeType: 3,
click: true
});
},
scrollToCurrentLine() {
const activeLine = this.$refs.lyricsWrapper.querySelector('.active');
if (activeLine) {
this.bs.scrollToElement(activeLine, 300);
}
}
}
};
</script>
动态解析歌词文件
通常歌词文件是 LRC 格式,需要解析时间戳和歌词内容。
function parseLRC(lrcText) {
const lines = lrcText.split('\n');
const result = [];
const timeRegex = /\[(\d+):(\d+\.\d+)\]/;
lines.forEach(line => {
const match = timeRegex.exec(line);
if (match) {
const minutes = parseFloat(match[1]);
const seconds = parseFloat(match[2]);
const time = minutes * 60 + seconds;
const text = line.replace(timeRegex, '').trim();
result.push({ time, text });
}
});
return result.sort((a, b) => a.time - b.time);
}
与音频播放同步
通过监听音频的 timeupdate 事件,实时更新当前歌词行。
const audio = new Audio('song.mp3');
audio.addEventListener('timeupdate', () => {
this.updateCurrentLine(audio.currentTime);
});
以上方法可以根据实际需求组合使用,实现流畅的歌词滚动效果。关键点在于准确解析歌词时间戳、高效更新当前行以及平滑滚动到目标位置。







