大家可能有时候可能会用到歌词同步,歌词滚动,大致的歌词滚动效果就是这样的,具体实现的方法需要JS/jQuery+CSS+H5的方式,具体代码如下。
首先你需要有一个lrc的歌词,大致格式是
别的不多说,直接上代码👇
歌词打印在界面上的代码是:
<!--歌词显示部分H5代码-->
<div class="lyrics">
<ul class="lyricsList" style="color:#86ff85;"></ul><!--#b1d4f3-->
</div>
Js代码部分
var lrcArray = [];//新建数组,用于存放歌词
function(lrcPath) {
var lrctxt = lrcPath;//你的lrc歌词地址
lrcArray = [];//情感歌词数组
// 清空现有歌词列表
$('.lyricsList').empty();
var lrcGet = lrctxt;//提取歌词
if (lrcGet == "") {
$('.lyricsList').empty();
}
var lrc = lrcGet.split('\n');
$.each(lrc, function (i, item) {
//转化时间
var timeStr = item.substring(item.indexOf("[") + 1, item.indexOf("]"));
var min = parseInt(timeStr.split(':')[0]) * 60;
// 检查分钟和秒是否为数字
if (isNaN(min)) {
// 如果分钟或秒不是有效的数字,跳过这个项
return true;
}
var sec = parseFloat(timeStr.split(':')[1]);
var time = parseFloat((min + sec).toFixed(2));
var content = "";
var text = item.substring(item.indexOf(']') + 1);
if (text === "" || text === null || text === undefined) {
content = "------";
} else {
content = text;
}
//添加进数组
lrcArray.push({
t: time,
c: content
});
});
//显示歌词打印全部在页面
var html = "";
$.each(lrcArray, function (i, v) {
html += '<li>' + v.c + '</li>';
});
$('.lyricsList').append(html);
}
歌词样式部分:
.lyrics {
float: right;
width: 48%;
/* height: 90%; */
height: 75vh;
margin-top: 50px;
padding-top: 8px;
overflow: hidden;
}
.lyrics .lyricsList {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.lyrics .lyricsList li {
height: 30px;
line-height: 15px;
list-style: none;
font-size: 18px;
transition: font-size 0.3s ease;
/* 字体大小变化的过渡效果 */
}
/* 歌词高亮 */
.highlight {
color: #FF4500;
font-weight: bold;
text-shadow: 0 0 10px #ded1fc;
font-size: 2em !important;
}
歌词样式和歌词的显示也都完成了,解决改解决歌词同步歌曲进度的问题了,因为每行歌词都有对应的歌曲进度时间,所以我们可以根据歌词所在行的时间和audio控件的监听时间进度时间来控制歌词的实时滚动和同步。废话不多说,直接上代码。
<audio id="bottomSpinner" controls autoplay="autoplay">
<source src="" type="audio/mpeg">
你的浏览器不支持
</audio>
//同步歌词
$('#bottomSpinner').on('timeupdate', function () {
var currentTime = $('#bottomSpinner')[0].currentTime; // 获取当前播放时间
$.each(lrcArray, function (i, v) {
if (currentTime >= lrcArray[i].t) {
$('.lyricsList').css('margin-top', '');// 避免进度变动时数值产生混乱
$('.lyricsList li').eq(i).addClass('highlight');
$('.lyricsList li').eq(i).siblings().removeClass('highlight');
if (i > 10) {
$('.lyricsList').css('margin-top', (-i + 10) * 30 + 'px');
}
}
});
});
//歌词滚动
$('#bottomSpinner').on('timeupdate', function () {
var currentTime = this.currentTime;
var index = findLyricIndex(currentTime);
// 使用 requestAnimationFrame 来优化滚动性能
requestAnimationFrame(function () {
highlightLyric(index);
scrollLyricList(index);
});
});
function findLyricIndex(currentTime) {
var lyricsData = lrcArray;
// 初始化索引为0,如果音频在开始或之前,则返回第一句歌词
var closestIndex = 0;
// 遍历歌词数据,寻找最接近但不超过当前播放时间的歌词
for (var i = 0; i < lyricsData.length; i++) {
if (lyricsData[i].t > currentTime) {
break; // 找到了第一个大于currentTime的时间戳,因此前一个就是我们要找的
}
closestIndex = i;
}
return closestIndex;
}
//当前歌词高亮
function highlightLyric(index) {
$('.lyricsList li').removeClass('highlight');
$('.lyricsList li').eq(index).addClass('highlight');
}
function scrollLyricList(index) {
var lyricsList = document.querySelector('.lyricsList');
var lyricItemHeight = 30; // 假设每个歌词项的高度是30px
if (index > 8) {
lyricsList.scrollTop = (index - 8) * lyricItemHeight;
}
}
上述代码的命名不是很规范,是一个Demo,大家在使用的时候记得要规范命名方式,“bottomSpinner”就是audio播放器的id,不要误会了大家。大致的实现方法就在上面了,最后放一个完整的代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>歌词滚动显示</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<style>
.lyrics {
float: right;
width: 48%;
/* height: 90%; */
height: 75vh;
margin-top: 50px;
padding-top: 8px;
overflow: hidden;
}
.lyrics .lyricsList {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.lyrics .lyricsList li {
height: 30px;
line-height: 15px;
list-style: none;
font-size: 18px;
transition: font-size 0.3s ease;
/* 字体大小变化的过渡效果 */
}
/* 歌词高亮 */
.highlight {
color: #FF4500;
font-weight: bold;
text-shadow: 0 0 10px #ded1fc;
font-size: 2em !important;
}
</style>
<script>
$(function () {
var lrcArray = [];//新建数组,用于存放歌词
function(lrcPath){
var lrctxt = lrcPath;//你的歌词路径
lrcArray = [];//清空歌词数组
// 清空现有歌词列表
$('.lyricsList').empty();
var lrcGet = lrctxt;//提取歌词
if (lrcGet == "") {
$('.lyricsList').empty();
}
var lrc = lrcGet.split('\n');
$.each(lrc, function (i, item) {
//转化时间
var timeStr = item.substring(item.indexOf("[") + 1, item.indexOf("]"));
var min = parseInt(timeStr.split(':')[0]) * 60;
// 检查分钟和秒是否为数字
if (isNaN(min)) {
// 如果分钟或秒不是有效的数字,跳过这个项
return true;
}
var sec = parseFloat(timeStr.split(':')[1]);
var time = parseFloat((min + sec).toFixed(2));
var content = "";
var text = item.substring(item.indexOf(']') + 1);
if (text === "" || text === null || text === undefined) {
content = "------";
} else {
content = text;
}
//添加进数组
lrcArray.push({
t: time,
c: content
});
});
//显示歌词打印全部在页面
var html = "";
$.each(lrcArray, function (i, v) {
html += '<li>' + v.c + '</li>';
});
$('.lyricsList').append(html);
}
//同步歌词
$('#bottomSpinner').on('timeupdate', function () {
var currentTime = $('#bottomSpinner')[0].currentTime; // 获取当前播放时间
$.each(lrcArray, function (i, v) {
if (currentTime >= lrcArray[i].t) {
$('.lyricsList').css('margin-top', '');// 避免进度变动时数值产生混乱
$('.lyricsList li').eq(i).addClass('highlight');
$('.lyricsList li').eq(i).siblings().removeClass('highlight');
if (i > 10) {
$('.lyricsList').css('margin-top', (-i + 10) * 30 + 'px');
}
}
});
});
//歌词滚动
$('#bottomSpinner').on('timeupdate', function () {
var currentTime = this.currentTime;
var index = findLyricIndex(currentTime);
// 使用 requestAnimationFrame 来优化滚动性能
requestAnimationFrame(function () {
highlightLyric(index);
scrollLyricList(index);
});
});
function findLyricIndex(currentTime) {
var lyricsData = lrcArray;
// 初始化索引为0,如果音频在开始或之前,则返回第一句歌词
var closestIndex = 0;
// 遍历歌词数据,寻找最接近但不超过当前播放时间的歌词
for (var i = 0; i < lyricsData.length; i++) {
if (lyricsData[i].t > currentTime) {
break; // 找到了第一个大于currentTime的时间戳,因此前一个就是我们要找的
}
closestIndex = i;
}
return closestIndex;
}
function highlightLyric(index) {
$('.lyricsList li').removeClass('highlight');
$('.lyricsList li').eq(index).addClass('highlight');
}
function scrollLyricList(index) {
var lyricsList = document.querySelector('.lyricsList');
var lyricItemHeight = 30; // 假设每个歌词项的高度是30px
if (index > 8) {
lyricsList.scrollTop = (index - 8) * lyricItemHeight;
}
}
});
</script>
</head>
<body>
<!--歌词显示部分-->
<div class="lyrics">
<ul class="lyricsList" style="color:#86ff85;"></ul><!--#b1d4f3-->
</div>
<!--播放器部分-->
<audio id="bottomSpinner" controls autoplay="autoplay">
<source src="" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
</body>
</html>
歌词显示的宽度高度的大家根据自己的需要去调整,以上就是歌词滚动的全部代码了,大家也可以在评论区讨论。