JS实现歌词同步滚动效果

实现歌词同步滚动效果,首先要用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 文本域内并隐藏,然后在获取歌词时放入指定位置



    
    id="text" style="overflow: hidden;">

JS实现

首先要把获取到的歌词解析为对象数组,并且放入指定位置,并且溢出隐藏
(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.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++;
      }
    };

    你可能感兴趣的:(前端学习)