基本上仿写了这个,但是上面那个实现的效果里没有实现快进和后退的功能,我在上面的基础上,增加了快进和后退
不多说,直接上代码
样式部分
<style>
* {
margin: 0;
padding: 0;
}
.lrc_content {
display: none;
}
.box {
height: 300px;
background: url(banner.png) no-repeat;
background-size: 100%;
}
.cover {
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .5);
text-align: center;
color: #fff;
overflow: hidden;
position: relative;
font-family: "楷体";
}
ul {
width: 100%;
position: absolute;
top: 0;
left: 0;
list-style: none;
}
.cover li {
width: 100%;
height: 30px;
line-height: 30px;
text-align: center;
}
.active {
color: greenyellow;
font-weight: bold;
font-size: 20px;
text-align: center;
}
</style>
HTML部分,歌词的数据是从lrc(歌词文件)中提取出来的,后续可能还有一个案例是从json提取数据显示歌词,主要是这些数据是带有时间轴的啊
<div class="lrc_content">
<p>[ti:沙漠骆驼]</p>
<p>[ar:展展与罗罗]</p>
<p>[al:沙漠骆驼]</p>
<p>[by:0]</p>
<p>[offset:0]</p>
<p>[00:00.59]沙漠骆驼 - 展展与罗罗</p>
<p>[00:02.97]词:展展与罗罗</p>
<p>[00:04.46]曲:展展与罗罗</p>
<p>[00:26.45]我要穿越这片沙漠</p>
<p>[00:28.51]找寻真的自我</p>
<p>[00:30.50]身边只有一匹骆驼陪我</p>
<p>[00:34.96]这片风儿吹过</p>
<p>[00:37.15]那片云儿飘过</p>
<p>[00:39.26]突然之间出现爱的小河</p>
<p>[00:43.63]我跨上沙漠之舟</p>
<p>[00:45.71]背上烟斗和沙漏</p>
<p>[00:47.92]手里还握着一壶烈酒</p>
<p>[00:52.35]漫长古道悠悠</p>
<p>[00:54.51]说不尽喜怒哀愁</p>
<p>[00:56.56]只有那骆驼奔忙依旧</p>
<p>[01:01.08][02:23.81][04:13.30]什么鬼魅传说</p>
<p>[01:03.12][02:25.94][04:15.20]什么魑魅魍魉妖魔</p>
<p>[01:05.43][02:28.30][04:17.47]只有那鹭鹰在幽幽的高歌</p>
<p>[01:09.81][02:32.61][04:21.83]漫天黄沙掠过</p>
<p>[01:11.90][02:35.04][04:23.90]走遍每个角落</p>
<p>[01:14.05][02:36.99][04:26.20]行走在无尽的苍茫星河</p>
<p>[01:18.69][02:41.50][04:30.60]白天黑夜交错</p>
<p>[01:20.80][02:43.56][04:32.65]如此妖娆婀娜</p>
<p>[01:22.85][02:45.85][04:35.01]蹉跎着岁月又蹉跎了自我</p>
<p>[01:27.20][02:50.16][04:39.25]前方迷途太多</p>
<p>[01:29.32][02:52.33][04:41.39]坚持才能洒脱</p>
<p>[01:31.56][02:54.46][04:43.58]走出黑暗就能逍遥又快活</p>
<p>[01:38.54]</p>
<p>[01:49.43]我寻找沙漠绿洲</p>
<p>[01:51.34]出现海市蜃楼</p>
<p>[01:53.44]我仿佛看到她在那里等候</p>
<p>[01:57.80]想起了她的温柔</p>
<p>[01:59.91]滚烫着我的胸口</p>
<p>[02:02.19]迷失在昨夜的那壶老酒</p>
<p>[02:06.42]我穿上大头皮鞋</p>
<p>[02:08.75]跨过凛冽荒野</p>
<p>[02:10.75]我仿佛穿越到另一个世界</p>
<p>[02:15.20]阿拉丁神灯要倾斜</p>
<p>[02:17.33]天堂地狱已然重叠</p>
<p>[02:19.51]突然之间飞来一只蝴蝶</p>
<p>[03:01.04]</p>
<p>[03:47.15]我已坠入在这神奇的国度</p>
<p>[03:51.28]驼铃相伴走向圣堂之路</p>
<p>[03:55.64]原谅我曾经恍惚陷入迷途</p>
<p>[03:59.80]遮住了眼眸</p>
<p>[04:01.80]湮没了意图</p>
<p>[04:04.02]怎能被这样征服</p>
<p>[04:48.19]梦里回到最初</p>
<p>[04:50.08]浪潮起起伏伏</p>
<p>[04:52.29]彷徨着未来又彷徨着孤独</p>
<p>[04:56.74]漫长人生旅途</p>
<p>[04:58.87]花开花落无数</p>
<p>[05:01.03]沸腾的时光怎能被荒芜</p>
<p>[05:05.76]清晨又到日暮</p>
<p>[05:07.48]天边飞鸟群逐</p>
<p>[05:09.79]摇曳着苍穹又描摹着黄土</p>
<p>[05:14.26]东方鱼肚白出</p>
<p>[05:16.53]烈日绽放吐露</p>
<p>[05:18.47]放下尘浮我已踏上归途</p>
</div>
<div class="box">
<div class="cover"></div>
</div>
<audio src="展展与罗罗 - 沙漠骆驼.mp3" controls></audio>
下面是js部分,还要引一下jQuery文件
<script>
$(function () {
// 解析歌词文件,分割时间和歌词
var $p = $(".lrc_content p");
var audio = document.querySelector('audio');
// 歌词对象
var oLrc = {
ti: "", //歌名
ar: "", //作者
al: "", //专辑名
ms: [] //歌词数组 {t:时间,content:歌词}
};
// 解析界面上的lrc数据
for (var i = 0; i < $p.length; i++) {
var txt = $p.eq(i).text().trim();
var subTxt = txt.substring(txt.indexOf("[") + 1, txt.indexOf("]"));
var subTxtArr = subTxt.split(":");
if (isNaN(parseInt(subTxtArr[0]))) {
oLrc[subTxtArr[0]] = subTxtArr[1];
} else {
var times = txt.match(/\[(\d+:.+?)\]/g); // 匹配字符串中的日期,返回一个数组
for (var j = 0; j < times.length; j++) {
var one = times[j].substring(1, times[j].indexOf("]")).split(":");
oLrc.ms.push({
t: (parseInt(one[0]) * 60 + parseFloat(one[1])).toFixed(3),
c: txt.substr(txt.lastIndexOf("]") + 1)
});
}
}
}
oLrc.ms.sort(function (a, b) {
return a.t - b.t;
})
// 把生成的数据显示到界面上去
var $ul = $("<ul></ul>");
for (var i = 0; i < oLrc.ms.length; i++) {
var $li = $("<li></li>").text(oLrc.ms[i].c);
$ul.append($li);
}
$(".cover").append($ul);
var lineNo = 0; // 当前行歌词
var preLine = 6; // 当播放6行后开始滚动歌词
var lineHeight = -30; // 每次滚动的距离
// 让字幕跟最歌曲播放
// 歌词高亮 增加类名active
function highLight() {
var $li = $("li");
$li.eq(lineNo).addClass("active").siblings().removeClass("active");
if (lineNo > preLine) {
$ul.stop(true, true).animate({ top: (lineNo - preLine) * lineHeight });
}
}
highLight();
audio.addEventListener("timeupdate", function () {
if (lineNo == oLrc.ms.length) return;
var curT = audio.currentTime;
var x = getLineNo(curT);
// if (curT >= parseFloat(oLrc.ms[lineNo].t)) {
// 因为后退和前进的判断在getlineNo里已经进行了判断,所以这里直接就赋值
lineNo = x;
highLight();
lineNo++;
// }
});
// 当快进或者倒退的时候,找到最近的后面那个oLrc.ms[i].t
function getLineNo(ct) {
if (ct >= parseFloat(oLrc.ms[lineNo].t)) {
// 快进
for (var i = oLrc.ms.length - 1; i >= lineNo; i--) {
// 倒着查找比curT时间小的第一个值
if (ct >= parseFloat(oLrc.ms[i].t)) {
return i;
}
}
} else {
// 后退
for (var i = 0; i <= lineNo; i++) {
if (ct <= parseFloat(oLrc.ms[i].t)) {
// i-1 不然会导致字幕快一条
return i -1 ;
}
}
}
}
function goBack() {
lineNo = 0;
$ul.animate({ top: 0 });
highLight();
}
audio.addEventListener("ended", function () {
goBack();
});
});
</script>
快进倒退思路:
快进后,我从后往前找,找到一个比当前值(audio提供的一个属性,数值类型)小的,说明我差不多正好快进到了那个位置,然后把对应的下标值返回,这个就是我们需要高亮显示的那一行了,接下来就是自己播放++就行。
倒退后,我从头开始找,找到比当前值大的,说明,我差不多倒退到了那个位置,返回这个下标值-1才行,不然歌词会比音乐快一行,接下来的一样就是自动播放就行。
思路就是这样的,别的说明,可以参考文章开头的博客,一些样式自行修改,可能会有一些bug,欢迎提出来。