这个项目复刻了一个 Vue 网站的 LRC 歌词显示功能,提取了核心的 CSS 样式和交互逻辑,实现了纯原生 HTML/CSS/JavaScript 版本。
/workspace/ ├── lyric-player.css # 提取的核心样式 ├── lyric-player.html # 主页面 ├── lyric-player.js # 核心逻辑实现 └── README-LYRIC-PLAYER.md # 使用说明
[mm:ss.xx]歌词/* 主容器 - 80vh 高度,固定在视口中 */
.lyric-layout {
height: 80vh;
overflow: hidden;
}
/* 滚动容器 - 支持触摸滚动 */
.scroll {
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
/* Android/iOS 对话框高度适配 */
body.platform-android:not(.native-mobile) .q-dialog__inner--minimized > div,
body.platform-ios .q-dialog__inner--minimized > div {
max-height: calc(100vh - 108px);
}
.q-item.active {
background-color: rgba(25, 118, 210, 0.1);
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% {
background-color: rgba(25, 118, 210, 0.1);
}
50% {
background-color: rgba(25, 118, 210, 0.2);
}
}
parseLRC(lrcText) {
const pattern = /\[(\d{2}):(\d{2})\.(\d{2,3})\](.*)/;
// 解析时间戳和歌词文本
// 返回排序后的歌词数组
}
syncLyrics() {
const currentTime = this.audioElement.currentTime + this.offset;
const newIndex = this.getCurrentLyricIndex(currentTime);
if (newIndex !== this.currentIndex) {
this.highlightLyric(newIndex);
this.scrollToActiveLyric();
}
}
scrollToActiveLyric() {
const containerHeight = container.clientHeight;
const itemTop = activeItem.offsetTop;
const itemHeight = activeItem.clientHeight;
const scrollTop = itemTop - containerHeight / 2 + itemHeight / 2;
container.scrollTo({
top: scrollTop,
behavior: 'smooth'
});
}
lyric-player.html// 方法1:在页面中添加 audio 元素
<audio id="my-audio" src="music.mp3"></audio>
// 方法2:在 JavaScript 中设置
const audioElement = document.getElementById('my-audio');
window.lyricPlayer.setAudioElement(audioElement);
const player = new LyricPlayer({
audioElement: document.querySelector('audio'),
lyricListElement: document.getElementById('lyric-list'),
playBtnElement: document.getElementById('play-btn'),
offsetInputElement: document.getElementById('offset-input'),
fileNameElement: document.getElementById('file-name')
});
parseLRC(text) - 解析 LRC 格式parseVTT(text) - 解析 VTT 格式parseSRT(text) - 解析 SRT 格式renderLyrics() - 渲染歌词列表syncLyrics() - 同步歌词高亮jumpToLyric(index) - 跳转到指定歌词adjustOffset(delta) - 调整时间偏移resetOffset() - 重置偏移togglePlay() - 切换播放/暂停修改 CSS 中的变量和颜色值:
/* 当前歌词高亮颜色 */
.q-item.active {
background-color: rgba(25, 118, 210, 0.1); /* 蓝色 */
color: #1976d2;
}
.q-item__label {
font-size: 14px;
font-family: 'Your Custom Font', sans-serif;
}
@keyframes custom-pulse {
0% { opacity: 1; }
50% { opacity: 0.7; }
100% { opacity: 1; }
}
.q-item.active {
animation: custom-pulse 2s infinite;
}
核心思路:
useEffect 监听音频 timeupdate 事件useState 管理当前歌词索引useRef 实现自动滚动核心思路:
watch 监听音频时间computed 计算当前歌词nextTick 确保滚动动画核心思路:
LaunchedEffect 监听音频播放LazyColumn + items 渲染歌词列表rememberScrollState 实现自动滚动核心思路:
StreamBuilder 监听音频流ListView.builder 渲染歌词ScrollController 实现自动滚动timeupdate 事件进行节流本项目基于原网站样式提取,仅供学习参考使用。
欢迎提交 Issue 和 Pull Request!