html如何让歌词动起来

HTML、CSS和JavaScript结合,通过解析歌词时间戳与音频播放进度同步,动态控制歌词显示位置实现滚动效果

HTML中实现歌词的动态效果,通常需要结合CSS和JavaScript来控制歌词的显示、滚动和高亮等行为,以下是实现这一功能的详细步骤和示例代码:

html如何让歌词动起来

基本结构搭建

  1. HTML部分
    • 创建一个<audio>标签用于播放音乐。
    • 创建一个容器(如<div>)来放置歌词,通常使用<ul><li>标签来逐行显示歌词。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">Lyrics Scrolling Effect</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <audio id="musicPlayer" src="song.mp3" controls></audio>
    <div class="lyrics-container">
        <ul id="lyricsList"></ul>
    </div>
    <script src="script.js"></script>
</body>
</html>
  1. CSS部分
    • 设置歌词容器的样式,包括大小、背景、溢出隐藏等。
    • 设置歌词列表的样式,如行高、字体、颜色等。
    • 定义高亮显示的样式,如改变颜色、放大等。
body {
    font-family: Arial, sans-serif;
    background-color: #f0f0f0;
    text-align: center;
}
.lyrics-container {
    width: 50%;
    height: 300px;
    margin: 20px auto;
    overflow: hidden;
    border: 1px solid #ccc;
    background-color: #fff;
}
#lyricsList {
    list-style: none;
    padding: 0;
    margin: 0;
    transition: top 0.5s ease-in-out;
}
#lyricsList li {
    height: 30px;
    line-height: 30px;
    font-size: 18px;
}
.active {
    color: red;
    font-weight: bold;
    transform: scale(1.1);
}

JavaScript实现逻辑

  1. 解析歌词文件

    通常歌词文件是LRC格式,包含时间戳和歌词文本,需要编写函数来解析这种格式,将歌词按时间顺序存储到数组中。

function parseLyrics(lyricsText) {
    const lines = lyricsText.split('n');
    const lyrics = [];
    lines.forEach(line => {
        const match = line.match(/[(d{2}):(d{2}).(d{2})](.+)/);
        if (match) {
            const minutes = parseInt(match[1], 10);
            const seconds = parseInt(match[2], 10);
            const milliseconds = parseInt(match[3], 10);
            const time = (minutes  60 + seconds)  1000 + milliseconds  10;
            lyrics.push({ time, text: match[4] });
        }
    });
    return lyrics;
}
  1. 同步歌词与音乐播放
    • 监听<audio>标签的timeupdate事件,获取当前播放时间。
    • 根据当前时间找到应该显示的歌词,并更新歌词列表的显示。
const musicPlayer = document.getElementById('musicPlayer');
const lyricsList = document.getElementById('lyricsList');
let lyrics = []; // 假设已经通过AJAX或其他方式加载并解析了歌词
let currentLine = 0;
musicPlayer.addEventListener('timeupdate', () => {
    const currentTime = musicPlayer.currentTime  1000; // 转换为毫秒
    while (currentLine < lyrics.length && lyrics[currentLine].time <= currentTime) {
        lyricsList.children[currentLine].classList.remove('active');
        currentLine++;
    }
    if (currentLine < lyrics.length) {
        lyricsList.children[currentLine].classList.add('active');
        // 调整歌词列表的位置,使当前行可见
        const scrollAmount = currentLine  lyricsList.children[0].offsetHeight;
        lyricsList.style.top = `-${scrollAmount}px`;
    }
});
  1. 动态加载歌词

    如果歌词是从外部文件加载的,可以使用AJAX或Fetch API来获取歌词文本,然后调用解析函数。

fetch('lyrics.lrc')
    .then(response => response.text())
    .then(lyricsText => {
        lyrics = parseLyrics(lyricsText);
        // 将歌词添加到页面中
        lyrics.forEach(lyric => {
            const li = document.createElement('li');
            li.textContent = lyric.text;
            lyricsList.appendChild(li);
        });
    });

优化与扩展

  1. 平滑滚动

    html如何让歌词动起来

    • 使用CSS的transition属性或JavaScript的动画库来实现歌词滚动的平滑效果。
  2. 歌词对齐

    • 确保歌词文本在容器中垂直居中,可以通过调整line-height或使用Flexbox布局来实现。
  3. 错误处理

    添加错误处理机制,如歌词文件加载失败时的提示信息。

    html如何让歌词动起来

  4. 用户交互

    • 允许用户点击歌词来跳转到歌曲的特定位置。
    • 提供暂停、播放、快进、快退等控制按钮。

完整示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">Lyrics Scrolling Effect</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f0f0f0;
            text-align: center;
        }
        .lyrics-container {
            width: 50%;
            height: 300px;
            margin: 20px auto;
            overflow: hidden;
            border: 1px solid #ccc;
            background-color: #fff;
            position: relative;
        }
        #lyricsList {
            list-style: none;
            padding: 0;
            margin: 0;
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            transition: top 0.5s ease-in-out;
        }
        #lyricsList li {
            height: 30px;
            line-height: 30px;
            font-size: 18px;
        }
        .active {
            color: red;
            font-weight: bold;
            transform: scale(1.1);
        }
    </style>
</head>
<body>
    <audio id="musicPlayer" src="song.mp3" controls></audio>
    <div class="lyrics-container">
        <ul id="lyricsList"></ul>
    </div>
    <script>
        function parseLyrics(lyricsText) {
            const lines = lyricsText.split('n');
            const lyrics = [];
            lines.forEach(line => {
                const match = line.match(/[(d{2}):(d{2}).(d{2})](.+)/);
                if (match) {
                    const minutes = parseInt(match[1], 10);
                    const seconds = parseInt(match[2], 10);
                    const milliseconds = parseInt(match[3], 10);
                    const time = (minutes  60 + seconds)  1000 + milliseconds  10;
                    lyrics.push({ time, text: match[4] });
                }
            });
            return lyrics;
        }
        const musicPlayer = document.getElementById('musicPlayer');
        const lyricsList = document.getElementById('lyricsList');
        let lyrics = []; // 假设已经通过AJAX或其他方式加载并解析了歌词
        let currentLine = 0;
        musicPlayer.addEventListener('timeupdate', () => {
            const currentTime = musicPlayer.currentTime  1000; // 转换为毫秒
            while (currentLine < lyrics.length && lyrics[currentLine].time <= currentTime) {
                lyricsList.children[currentLine].classList.remove('active');
                currentLine++;
            }
            if (currentLine < lyrics.length) {
                lyricsList.children[currentLine].classList.add('active');
                // 调整歌词列表的位置,使当前行可见
                const scrollAmount = currentLine  lyricsList.children[0].offsetHeight;
                lyricsList.style.top = `-${scrollAmount}px`;
            }
        });
        fetch('lyrics.lrc')
            .then(response => response.text())
            .then(lyricsText => {
                lyrics = parseLyrics(lyricsText);
                // 将歌词添加到页面中
                lyrics.forEach(lyric => {
                    const li = document.createElement('li');
                    li.textContent = lyric.text;
                    lyricsList.appendChild(li);
                });
            });
    </script>
</body

原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/60957.html

(0)
酷盾叔的头像酷盾叔
上一篇 2025年7月14日 13:28
下一篇 2025年7月14日 13:34

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN