歌词同步翻滚+高亮代码分享
<style type="text/css">#lrcDiv { width: 300px; height: 43px; overflow: hidden; position: relative; padding: 8px; }
#lrcDiv ul, lrcli { margin: 0; padding: 0;}
#lrcUl { position: absolute; top: 0; }
#lrcUl li { height: 20px; font-size:14px; line-height:20px; color: black; list-style-type: none; }
#myplayer { outline: none; list-style-type: none; }
</style>
<audio id="myplayer" src="http://www.kumeiwp.com/sub/filestores/2021/12/27/db5031ddc52e16860f4aeb70b530099b.mp3" controls="controls"></audio>
<div id="lrcDiv"><ul id="lrcUl"></ul></div>
<script language="javascript">
var lrcAr=[
["00:00.000"," 作词 : 叶世荣"],
["00:01.000"," 作曲 : 黄家驹"],
["00:27.600","从来不知想拥有多少的理想"],
["00:33.599","还离不开种种困忧"],
["00:40.599","勉强去掩饰失意的感觉"],
["00:46.599","再次听到昨日的冷嘲"],
["00:52.599","徘徊於街中恐怕只得孤独"],
["00:58.599","寻回思忆中的碎片"],
["01:05.600","变作了一堆草芥风中散"],
["01:11.600","与你奏过午夜的怨曲"],
["01:16.600","总有挫折打碎我的心"],
["01:19.600","紧抱过去抑压了的手"],
["01:23.600","我与你也彼此一起艰苦过"],
["01:28.600","写上每句冰冷冷的诗"],
["01:31.600","不会放弃高唱这首歌"],
["01:36.600","我与你也彼此真的相识过"],
["01:55.600","从回忆中找不到天真的笑声"],
["02:01.600","曾留不低心中斗争"],
["02:08.600","每次去担当失意的主角"],
["02:14.600","冷笑变作故事的作者"],
["02:19.600","总有挫折打碎我的心"],
["02:22.600","紧抱过去抑压了的手"],
["02:27.600","我与你也彼此一起艰苦过"],
["02:32.600","写上每句冰冷冷的诗"],
["02:35.600","不会放弃高唱这首歌"],
["02:39.600","我与你也彼此真的相识过"],
["03:11.600","啊......啊......障碍能撕破"],
["03:22.600","总有挫折打碎我的心"],
["03:25.600","紧抱过去抑压了的手"],
["03:30.600","我与你也彼此一起艰苦过"],
["03:35.600","写上每句冰冷冷的诗"],
["03:38.600","不会放弃高唱这首歌"],
["03:42.600","我与你也彼此真的相识过"],
["03:47.600","总有挫折打碎我的心"],
["03:51.600","紧抱过去抑压了的手"],
["03:55.600","我与你也彼此一起艰苦过"],
["04:00.600","写上每句冰冷冷的诗"],
["04:03.600","不会放弃高唱这首歌"],
["04:07.600","我与你也彼此真的相识过"],
["04:12.600","总有挫折打碎我的心"],
["04:16.600","紧抱过去抑压了的手"],
["04:20.600","我与你也彼此一起艰苦过"],
["04:25.600","——永远的Beyond"]
];
var myaud = document.getElementById('myplayer'); //播放器标识
var lrcUl = document.getElementById('lrcUl'); //歌词显示元素标识
//处理lrc歌词数组:时间转换成秒、歌词放入li标签
for(j=0; j<lrcAr.length; j++){
lrcAr = toSec(lrcAr);
lrcUl.innerHTML += "<li id='li" + lrcAr + "'>" + lrcAr + "</li>";
}
//lrc时间信息转为秒
function toSec(lrcTime) {
let tmpAr = lrcTime.split(':');
lrcTime = tmpAr * 60 + parseInt(tmpAr);
return lrcTime;
}
//同步高亮、翻滚歌词
myaud.ontimeupdate = function() {
let tt = this.currentTime;
for(j=0; j<lrcAr.length; j++){
if(tt > lrcAr){
if(j > 0){
let idxLast = lrcAr;
document.getElementById("li" + idxLast).style.color = "black";
lrcUl.style.top ="-" + (j * 20 - 20) + "px";
}
let idx = lrcAr;
document.getElementById("li" + idx).style.color = "red";
}
}
}
// 播放结束重置歌词样式
myaud.onended = function() {
document.getElementById("li" + lrcAr).style.color = "black";
lrcUl.style.top = 0;
this.play();
}
</script>
<style type="text/css">
#lrcDiv { width: 300px; height: 43px; overflow: hidden; position: relative; padding: 8px; }
#lrcDiv ul, lrcli { margin: 0; padding: 0;}
#lrcUl { position: absolute; top: 0; }
#lrcUl li { height: 20px; font-size:14px; line-height:20px; color: black; list-style-type: none; }
#myplayer { outline: none; list-style-type: none; }
</style>
<audio id="myplayer" src="http://www.kumeiwp.com/sub/filestores/2021/12/27/db5031ddc52e16860f4aeb70b530099b.mp3" controls="controls"></audio><br><br>
<div id="lrcDiv"><ul id="lrcUl"></ul></div>
<script language="javascript">
var lrcAr=[
["00:00.000"," 作词 : 叶世荣"],
["00:01.000"," 作曲 : 黄家驹"],
["00:27.600","从来不知想拥有多少的理想"],
["00:33.599","还离不开种种困忧"],
["00:40.599","勉强去掩饰失意的感觉"],
["00:46.599","再次听到昨日的冷嘲"],
["00:52.599","徘徊於街中恐怕只得孤独"],
["00:58.599","寻回思忆中的碎片"],
["01:05.600","变作了一堆草芥风中散"],
["01:11.600","与你奏过午夜的怨曲"],
["01:16.600","总有挫折打碎我的心"],
["01:19.600","紧抱过去抑压了的手"],
["01:23.600","我与你也彼此一起艰苦过"],
["01:28.600","写上每句冰冷冷的诗"],
["01:31.600","不会放弃高唱这首歌"],
["01:36.600","我与你也彼此真的相识过"],
["01:55.600","从回忆中找不到天真的笑声"],
["02:01.600","曾留不低心中斗争"],
["02:08.600","每次去担当失意的主角"],
["02:14.600","冷笑变作故事的作者"],
["02:19.600","总有挫折打碎我的心"],
["02:22.600","紧抱过去抑压了的手"],
["02:27.600","我与你也彼此一起艰苦过"],
["02:32.600","写上每句冰冷冷的诗"],
["02:35.600","不会放弃高唱这首歌"],
["02:39.600","我与你也彼此真的相识过"],
["03:11.600","啊......啊......障碍能撕破"],
["03:22.600","总有挫折打碎我的心"],
["03:25.600","紧抱过去抑压了的手"],
["03:30.600","我与你也彼此一起艰苦过"],
["03:35.600","写上每句冰冷冷的诗"],
["03:38.600","不会放弃高唱这首歌"],
["03:42.600","我与你也彼此真的相识过"],
["03:47.600","总有挫折打碎我的心"],
["03:51.600","紧抱过去抑压了的手"],
["03:55.600","我与你也彼此一起艰苦过"],
["04:00.600","写上每句冰冷冷的诗"],
["04:03.600","不会放弃高唱这首歌"],
["04:07.600","我与你也彼此真的相识过"],
["04:12.600","总有挫折打碎我的心"],
["04:16.600","紧抱过去抑压了的手"],
["04:20.600","我与你也彼此一起艰苦过"],
["04:25.600","——永远的Beyond"]
];
var myaud = document.getElementById('myplayer'); //播放器标识
var lrcUl = document.getElementById('lrcUl'); //歌词显示元素标识
//处理lrc歌词数组:时间转换成秒、歌词放入li标签
for(j=0; j<lrcAr.length; j++){
lrcAr = toSec(lrcAr);
lrcUl.innerHTML += "<li id='li" + lrcAr + "'>" + lrcAr + "</li>";
}
//lrc时间信息转为秒
function toSec(lrcTime) {
let tmpAr = lrcTime.split(':');
lrcTime = tmpAr * 60 + parseInt(tmpAr);
return lrcTime;
}
//同步高亮、翻滚歌词
myaud.ontimeupdate = function() {
let tt = this.currentTime;
for(j=0; j<lrcAr.length; j++){
if(tt > lrcAr){
if(j > 0){
let idxLast = lrcAr;
document.getElementById("li" + idxLast).style.color = "black";
lrcUl.style.top ="-" + (j * 20 - 20) + "px";
}
let idx = lrcAr;
document.getElementById("li" + idx).style.color = "red";
}
}
}
// 播放结束重置歌词样式
myaud.onended = function() {
document.getElementById("li" + lrcAr).style.color = "black";
lrcUl.style.top = 0;
this.play();
}
</script>
本帖最后由 马黑黑 于 2022-2-23 15:23 编辑
一些解释:
一、实现思路
所有歌词一次性显示出来太占位,故设为只同时显示三句歌词。为此将 ul 标签置于一个 div 盒子里,令其在该 div 内定时变更 top 值。该 div 相对定位、固定高宽并防止内部内容外溢;ul 绝对定位,ul 及其子元素 li margin、padding 均设置为 0,li 还要固定行高以便在高亮歌词时计算 ul 的 top 值的具体变化。
二、实现细节
与之前的歌词高亮相比,JS代码的增量其实不多,仅两句:
一句在audio播放器的 ontimeupdate 事件里(红色,下同)——
//同步高亮、翻滚歌词
myaud.ontimeupdate = function() {
let tt = this.currentTime;
for(j=0; j<lrcAr.length; j++){
if(tt > lrcAr){
if(j > 0){
let idxLast = lrcAr;
document.getElementById("li" + idxLast).style.color = "black";
lrcUl.style.top ="-" + (j * 20 - 20) + "px";
}
let idx = lrcAr;
document.getElementById("li" + idx).style.color = "red";
}
}
}
for语句中的步进变量 j 依据lrc歌词数组变化步进,它大于0时表示不是第一句歌词,可以翻滚,感觉我这是发挥出了巧夺天工的技能。j 同时是第N+1句歌词(因为JS数组元素从 0 起算),j*20 是乘以 li 的高度,减去 20(- 20)是因为高亮的那句前面有一句要显示。
另一句在 audio播放器的 onended 事件里——
// 播放结束重置歌词样式
myaud.onended = function() {
document.getElementById("li" + lrcAr).style.color = "black";
lrcUl.style.top = 0;
this.play();
}
就是讲 ul 回复到原位。其实这句不要也行,为什么?因为audio播放器的 ontimeupdate 事件总会监听着播放进度,当播放完毕,前面说到的 j 步进变量会将 ul 拉回原位。
老黑新写的教程,好好研究研究。{:4_199:} 加林森 发表于 2022-2-23 17:27
老黑新写的教程,好好研究研究。
都是在之前的基础上加了一些小功能或做些改进 马黑黑 发表于 2022-2-23 19:32
都是在之前的基础上加了一些小功能或做些改进
很好使用的。我准备制作不是大转盘,做个单曲发出来,看效果。 加林森 发表于 2022-2-23 19:40
很好使用的。我准备制作不是大转盘,做个单曲发出来,看效果。
可以可以 马黑黑 发表于 2022-2-23 19:42
可以可以
材料已经选好了,歌词也找到了。准备开工。 可以显示2句么,当前的和后面一句{:4_187:} 红影 发表于 2022-2-23 19:51
可以显示2句么,当前的和后面一句
如此不好,得有第三者插足{:5_117:}
可以的,把那个div的高度调整一下 加林森 发表于 2022-2-23 19:43
材料已经选好了,歌词也找到了。准备开工。
慢慢来不急 马黑黑 发表于 2022-2-23 20:04
慢慢来不急
不急的,我已经制作好了,好像还有点问题。 加林森 发表于 2022-2-23 20:31
不急的,我已经制作好了,好像还有点问题。
急就是酱紫的{:5_106:} 马黑黑 发表于 2022-2-23 20:56
急就是酱紫的
{:4_170:} 马黑黑 发表于 2022-2-23 14:56
#lrcDiv { width: 300px; height: 43px; overflow: hidden; position: relative; padding: 8px; }
#lr ...
这个好,谢谢黑黑分享,我现在去做一个试试 小辣椒 发表于 2022-2-23 21:04
这个好,谢谢黑黑分享,我现在去做一个试试
悠着点
马黑黑 发表于 2022-2-23 19:54
如此不好,得有第三者插足
可以的,把那个div的高度调整一下
哇,真简单就可以啊{:4_199:} 红影 发表于 2022-2-23 22:40
哇,真简单就可以啊
通过这些例子,大家应该慢慢领会一些原理 马黑黑 发表于 2022-2-24 21:37
通过这些例子,大家应该慢慢领会一些原理
嗯嗯,非常好玩{:4_187:} 红影 发表于 2022-2-24 22:23
嗯嗯,非常好玩
{:4_190:}