JS实现歌词同步滚动效果

匿名 (未验证) 提交于 2019-12-03 00:38:01

实现歌词同步滚动效果,首先要用audio标签引入音频

<div id="h_center1">         <span>当前播放:</span>         <span>大鱼海棠</span>         <audio id="now_music" src="双笙 - 大鱼.mp3"></audio>         <img src="picture/former.jpg"/>         <img src="picture/stop.jpg" class="clickToStop" width="21" height="58"/>         <img src="picture/next.jpg"/>     </div>

并且也要将歌词文件写入textarea 文本域内并隐藏,然后在获取歌词时放入指定位置

<textarea id="lrc_content" name="textfield" cols="70" rows="10" style="display:none;">         [ti:大鱼]         [ar:王若伊]         [al:大鱼]         [ly:尹约]         [mu:钱雷]         [ma:]         [pu:]         [by:ttpod]         [total:278752]         [offset:0]         [00:00.410]大鱼 - 王若伊         [00:01.410]作词:尹约         [00:02.310]作曲:钱雷         [00:03.161]         [00:44.447]海浪无声将夜幕深深淹没         [00:51.200]漫过天空尽头的角落         [00:57.995]大鱼在梦境的缝隙里游过         [01:04.848]凝望你沉睡的轮廓         [01:10.898]看海天一色 听风起雨落         [01:17.705]执子手吹散苍茫茫烟波         [01:24.506]大鱼的翅膀 已经太辽阔         [01:32.112]我松开时间的绳索         [01:38.017]怕你飞远去         [01:41.620]怕你离我而去         [01:45.173]更怕你永远停留在这里         [01:51.876]每一滴泪水         [01:55.428]都向你流淌去         [01:59.623]倒流进天空的海底         [02:05.201]         [02:20.568]海浪无声将夜幕深深淹没         [02:27.118]漫过天空尽头的角落         [02:34.029]大鱼在梦境的缝隙里游过         [02:40.733]凝望你沉睡的轮廓         [02:47.051]看海天一色 听风起雨落         [02:53.654]执子手吹散苍茫茫烟波         [03:00.637]大鱼的翅膀 已经太辽阔         [03:08.087]我松开时间的绳索         [03:14.187]看你飞远去 看你离我而去         [03:21.039]原来你生来就属于天际         [03:27.889]每一滴泪水 都向你流淌去         [03:35.540]倒流回最初的相遇     </textarea>      <ul id="text" style="overflow: hidden;">      </ul>

首先要把获取到的歌词解析为对象数组,并且放入指定位置,并且溢出隐藏
(t.split(“:”)[0] * 60 + parseFloat(t.split(“:”)[1])).toFixed(3)这里是要把原来的mm:ss的时间格式改为秒

var medisArray = new Array();   // 定义一个新的数组 function createLrc () {   var medis = document.getElementById('lrc_content').innerText;   var medises = medis.split("\n");    // 用换行符拆分获取到的歌词    $.each(medises, function (i, item) {    // 遍历medises,并且将时间和文字拆分开,并push进自己定义的数组,形成一个对象数组     var t = item.substring(item.indexOf("[") + 1, item.indexOf("]"));     medisArray.push({        t: (t.split(":")[0] * 60 + parseFloat(t.split(":")[1])).toFixed(3),       c: item.substring(item.indexOf("]") + 1, item.length)     });   });   var ul = $("#text");   // 遍历medisArray,并且生成li标签,将数组内的文字放入li标签   $.each(medisArray, function (i, item) {     var li = $("<li style='list-style: none;'>");     li.html(item.c);     ul.append(li);   }); } createLrc();

实现文字高亮滚动

var fraction = 0.5; var topNum = 0; function lineHeight(lineno){   var ul = $("#text");   var $ul = document.getElementById('text');  // 令正在唱的那一行高亮显示   if (lineno > 0) {     $(ul.find("li").get(topNum + lineno - 1)).removeClass("lineheight");   }   var nowline = ul.find("li").get(topNum + lineno);   $(nowline).addClass("lineheight");      // 实现文字滚动   var _scrollTop;   $ul.scrollTop = 0;   if ($ul.clientHeight * fraction > nowline.offsetTop) {     _scrollTop = 0;   } else if (nowline.offsetTop > ($ul.scrollHeight - $ul.clientHeight * (1 - fraction))) {     _scrollTop = $ul.scrollHeight - $ul.clientHeight;   } else {     _scrollTop = nowline.offsetTop - $ul.clientHeight * fraction;   }    //以下声明歌词高亮行固定的基准线位置成为 “A”   if ((nowline.offsetTop - $ul.scrollTop) >= $ul.clientHeight * fraction) {     //如果高亮显示的歌词在A下面,那就将滚动条向下滚动,滚动距离为 当前高亮行距离顶部的距离-滚动条已经卷起的高度-A到可视窗口的距离     $ul.scrollTop += Math.ceil(nowline.offsetTop - $ul.scrollTop - $ul.clientHeight * fraction);    } else if ((nowline.offsetTop - $ul.scrollTop) < $ul.clientHeight * fraction && _scrollTop != 0) {     //如果高亮显示的歌词在A上面,那就将滚动条向上滚动,滚动距离为 A到可视窗口的距离-当前高亮行距离顶部的距离-滚动条已经卷起的高度     $ul.scrollTop -= Math.ceil($ul.clientHeight * fraction - (nowline.offsetTop - $ul.scrollTop));    } else if (_scrollTop == 0) {     $ul.scrollTop = 0;   } else {     $ul.scrollTop += $(ul.find('li').get(0)).height();   } }

监听audiotimeupdate 事件,实现文字与音频的同步
如果medisArray[lineNo].t <=T && T<= medisArray[lineNo + 1].t,那么行号为lineNo的这行歌词就需要高亮

var lineNo = 10; audio.ontimeupdate = function () {   if (lineNo == medisArray.length - 1 && audio.currentTime.toFixed(3) >= parseFloat(medisArray[lineNo].t)) {     lineHeight(lineNo);   }   if (parseFloat(medisArray[lineNo].t) <= audio.currentTime.toFixed(3) &&     audio.currentTime.toFixed(3) <= parseFloat(medisArray[lineNo + 1].t)) {     lineHeight(lineNo);     lineNo++;   } };
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!