vue实现歌词效果
Vue实现歌词效果
数据准备
歌词通常以时间轴和文本形式存储,可采用数组或对象格式。例如:
lyrics: [
{ time: 0.5, text: "第一句歌词" },
{ time: 3.2, text: "第二句歌词" }
]
音频播放监听
通过audio元素的timeupdate事件实时获取当前播放时间:
<audio ref="audio" @timeupdate="handleTimeUpdate" src="music.mp3"></audio>
methods: {
handleTimeUpdate() {
const currentTime = this.$refs.audio.currentTime;
this.updateLyric(currentTime);
}
}
歌词高亮逻辑
遍历歌词数组,匹配当前时间点对应的歌词行:
updateLyric(currentTime) {
for (let i = 0; i < this.lyrics.length; i++) {
if (currentTime >= this.lyrics[i].time &&
(i === this.lyrics.length - 1 || currentTime < this.lyrics[i + 1].time)) {
this.currentLine = i;
break;
}
}
}
滚动效果实现
使用CSS过渡和动态样式实现平滑滚动:
<div class="lyric-container" ref="container">
<div
v-for="(line, index) in lyrics"
:key="index"
:class="{ 'active': currentLine === index }"
>
{{ line.text }}
</div>
</div>
.lyric-container {
height: 300px;
overflow-y: auto;
transition: transform 0.3s ease;
}
.active {
color: #ff0000;
font-weight: bold;
}
自动滚动定位
通过计算偏移量使当前歌词始终居中:
scrollToCurrent() {
const container = this.$refs.container;
const activeItem = container.querySelector('.active');
if (activeItem) {
const offset = activeItem.offsetTop - container.offsetHeight / 2;
container.scrollTo({
top: offset,
behavior: 'smooth'
});
}
}
性能优化
使用节流函数避免频繁触发滚动计算:
import { throttle } from 'lodash';
export default {
methods: {
updateLyric: throttle(function(currentTime) {
// 原有逻辑
}, 300)
}
}
完整组件示例
<template>
<div>
<audio ref="audio" @timeupdate="handleTimeUpdate"></audio>
<div class="lyric-wrapper">
<div class="lyric-container" ref="container">
<div
v-for="(line, index) in lyrics"
:key="index"
:class="{ 'active': currentLine === index }"
>
{{ line.text }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
currentLine: 0,
lyrics: [] // 从接口获取或直接定义
}
},
methods: {
handleTimeUpdate() {
const currentTime = this.$refs.audio.currentTime;
this.updateLyric(currentTime);
},
updateLyric(currentTime) {
// 匹配逻辑
this.scrollToCurrent();
},
scrollToCurrent() {
// 滚动逻辑
}
}
}
</script>






