js 实现歌词滚动

项目目录:

图片[1]-js 实现歌词滚动-智码星河

html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>歌词滚动</title>

  <style>
    * {
      margin: 0;
      padding: 0;
      user-select: none;
    }

    html {
      height: 100%;
    }

    body {
      color: #009ad6;
      text-align: center;
      height: 100%;
      background-image: url(./assets/dengziqi.jpg);
      background-repeat: no-repeat;
      background-size: cover;
      background-position: -400px;
      overflow: hidden;
    }

    .lrc-container {
      height: calc(100vh - 360px);
      overflow: hidden;
      margin-top: 180px;
    }

    ul,
    li {
      padding: 0;
      margin: 0;
      list-style: none;
      transition: 0.6s;
    }

    .play-ico {
      display: block;
      width: 36px;
      height: 36px;
      background-image: url(./assets/mcbg.png);
      background-repeat: no-repeat;
      background-size: 100%;
      position: fixed;
      right: 50px;
      top: 50px;
    }

    audio {
      width: 100%;
      height: 100%;
      opacity: 0;
      display: none;
    }

    .lrc-container ul>li {
      height: 36px;
      line-height: 36px;
      font-size: 18px;
      font-family: '楷体' !important;
      transition: 0.6s;
    }

    .lrc-container ul>li.active {
      color: #fff;
      transform: scale(1.2);
    }

    @-webkit-keyframes rotataZ {
      0% {
        -webkit-transform: rotateZ(0deg);
      }

      100% {
        -webkit-transform: rotateZ(360deg);
      }
    }

    .stop {
      background-position: left bottom;
    }

    .on {
      background-position: 0px 1px;
      animation: rotataZ 1.2s linear infinite;
    }
  </style>
</head>

<body>
  <span class="play-ico">
    <audio src="./assets/taohuanuo.mp3" controls></audio>
  </span>

  <!-- <button id="clickBtn">点击</button> -->
  <div class="lrc-container">
    <ul></ul>
  </div>
  <script src="./js/data.js"></script>
  <script src="./js/lrc.js"></script>
</body>

</html>

js

/**
 * @desc 歌词滚动的整体实现
 */
(function () {
  'use strict';
  /**
   * @desc 处理歌词数据,字符串转化成对象
   * @param { String }  lrc
   * @returns {Array<object>} 返回值为[object,object,object]
   */
  // 解析歌词
  function parseLrcs(lrc) {
    // 创建一个空数组,用于存储解析后的歌词
    const result = [];
    // 将歌词按行分割
    const lines = lrc.split('\n');

    // 遍历每一行歌词
    for (let i = 0; i < lines.length; i++) {
      // 获取当前行歌词
      const line = lines[i];
      // 将当前行歌词按']'分割
      const parseLrc = line.split(']');
      // 创建一个空对象,用于存储当前行歌词的时间和文字
      const lrcObj = {};
      // 解析当前行歌词的时间
      lrcObj.time = parseTime(parseLrc[0].substring(1));
      // 解析当前行歌词的文字
      lrcObj.words = parseLrc[1];

      // 将当前行歌词的对象添加到结果数组中
      result.push(lrcObj);
    }
    // 返回解析后的歌词数组
    return result;
  }

  /**
   * @desc 创建 li标签 插入到元素中形成列表
   */
  // 创建元素函数
  function createElement() {
    // 创建文档片段
    let frag = document.createDocumentFragment();
    // 遍历解析歌词数据
    for (let i = 0, len = parseLrcData.length; i < len; i++) {
      // 创建li元素
      const li = document.createElement('li');
      // 将歌词内容设置为li元素的内容
      li.textContent = parseLrcData[i].words;
      // 将li元素添加到文档片段中
      frag.appendChild(li);
    }
    // 将文档片段添加到ul元素中
    doms.ul.appendChild(frag);
  }

  /**
   * @desc 时间字符串转化成数值
   * @param { String }  字符串
   * @returns { Number } 计算过后的Number
   */
  // 将时间字符串转换为分钟
  function parseTime(time) {
    // 将时间字符串以":"分割成数组
    const timeArr = time.split(':');
    // 将数组中的小时和分钟转换为数字,并相加
    return +timeArr[0] * 60 + +timeArr[1];
  }

  /**
   * @desc 通过对比找到当前时间所在的区间索引
   * @param { Number } currTime 当前播放的时间
   * @returns { Number } 当前时间对应歌词数据的索引位置
   */
  // 遍历歌词数据
  function findCurrentIndex(currTime) {
    for (let i = 0; i < parseLrcData.length; i++) {
      const element = parseLrcData[i];
      // 如果当前时间小于歌词时间,则返回当前索引减一
      if (currTime < element.time) {
        return i - 1;
      }
    }
    // 如果当前时间大于所有歌词时间,则返回歌词数据长度减一
    return parseLrcData.length - 1;
  }

  /**
   * @desc 设置偏移量
   */
  // 设置偏移量
  function setOffset(index) {
    // 计算偏移量
    let offset = index * liHeight + liHeight / 2 - containerHeight / 2;
    // 计算最大偏移量
    let maxOffset = doms.ul.clientHeight - containerHeight;

    // 如果偏移量小于0,则设置偏移量为0
    if (offset < 0) {
      offset = 0;
    }

    // 如果偏移量大于等于最大偏移量,则设置偏移量为最大偏移量
    if (offset >= maxOffset) {
      offset = maxOffset;
    }
    // 设置ul的偏移量
    doms.ul.style.transform = `translateY(-${offset}px)`;

    // 获取当前选中的li
    let li = doms.ul.querySelector('.active');
    // 如果存在,则移除active类
    if (li) {
      li.classList.remove('active');
    }
    // 获取新的li
    li = doms.ul.children[index];
    // 如果存在,则添加active类
    if (li) {
      li.classList.add('active');
    }
  }

  // get need operate domain
  // 获取页面中的元素
  const doms = {
    // 歌词容器
    lrcContainer: document.querySelector('.lrc-container'),
    // 歌词列表
    ul: document.querySelector('.lrc-container ul'),
    // 音频元素
    audio: document.querySelector('audio'),
    // 播放按钮
    clickBtn: document.querySelector('.play-ico'),
  };

  const parseLrcData = parseLrcs(lrc1); // 处理过后的歌词数据

  createElement(); //create element appended to parent node

  // 获取歌词列表项的高度
  const liHeight = doms.ul.children[0].clientHeight;
  // 获取歌词容器的高度
  const containerHeight = doms.lrcContainer.clientHeight;
  // 监听音频播放时间更新事件
  doms.audio.addEventListener('timeupdate', function (event) {
    // 获取当前播放时间
    const currentTime = event.target.currentTime;
    // 查找当前播放歌词的索引
    const currIndex = findCurrentIndex(currentTime);
    // 设置歌词偏移量
    setOffset(currIndex);
  });

  // 为点击按钮添加点击事件监听器
  doms.clickBtn.addEventListener('click', function () {
    // 获取音频是否暂停
    let paused = doms.audio.paused;
    // 如果暂停
    if (paused) {
      // 播放音频
      doms.audio.play();
      // 移除停止按钮样式
      doms.clickBtn.classList.remove('stop');
      // 添加播放按钮样式
      doms.clickBtn.classList.add('on');
    } else {
      // 暂停音频
      doms.audio.pause();
      // 添加停止按钮样式
      doms.clickBtn.classList.add('stop');
      // 移除播放按钮样式
      doms.clickBtn.classList.remove('on');
    }
  });
})();

数据js文件

var lrc = `[00:01.06]难念的经
[00:03.95]演唱:周华健
[00:06.78]
[00:30.96]笑你我枉花光心计
[00:34.15]爱竞逐镜花那美丽
[00:36.75]怕幸运会转眼远逝
[00:39.32]为贪嗔喜恶怒着迷
[00:41.99]责你我太贪功恋势
[00:44.48]怪大地众生太美丽
[00:47.00]悔旧日太执信约誓
[00:49.66]为悲欢哀怨妒着迷
[00:52.56]啊 舍不得璀灿俗世
[00:57.66]啊 躲不开痴恋的欣慰
[01:02.86]啊 找不到色相代替
[01:08.09]啊 参一生参不透这条难题
[01:13.15]吞风吻雨葬落日未曾彷徨
[01:15.73]欺山赶海践雪径也未绝望
[01:18.23]拈花把酒偏折煞世人情狂
[01:20.90]凭这两眼与百臂或千手不能防
[01:23.76]天阔阔雪漫漫共谁同航
[01:26.09]这沙滚滚水皱皱笑着浪荡
[01:28.68]贪欢一刻偏教那女儿情长埋葬
[01:32.38]
[01:34.09]吞风吻雨葬落日未曾彷徨
[01:36.50]欺山赶海践雪径也未绝望
[01:39.07]拈花把酒偏折煞世人情狂
[01:41.69]凭这两眼与百臂或千手不能防
[01:44.68]天阔阔雪漫漫共谁同航
[01:46.93]这沙滚滚水皱皱笑着浪荡
[01:49.54]贪欢一刻偏教那女儿情长埋葬
[01:53.41]
[02:15.45]笑你我枉花光心计
[02:18.53]爱竞逐镜花那美丽
[02:21.14]怕幸运会转眼远逝
[02:23.76]为贪嗔喜恶怒着迷
[02:26.43]责你我太贪功恋势
[02:28.98]怪大地众生太美丽
[02:31.60]悔旧日太执信约誓
[02:34.26]为悲欢哀怨妒着迷
[02:36.90]啊 舍不得璀灿俗世
[02:42.04]啊 躲不开痴恋的欣慰
[02:47.34]啊 找不到色相代替
[02:52.52]啊 参一生参不透这条难题
[02:57.47]吞风吻雨葬落日未曾彷徨
[03:00.05]欺山赶海践雪径也未绝望
[03:02.64]拈花把酒偏折煞世人情狂
[03:05.27]凭这两眼与百臂或千手不能防
[03:08.22]天阔阔雪漫漫共谁同航
[03:10.49]这沙滚滚水皱皱笑着浪荡
[03:13.06]贪欢一刻偏教那女儿情长埋葬
[03:18.45]吞风吻雨葬落日未曾彷徨
[03:20.90]欺山赶海践雪径也未绝望
[03:23.54]拈花把酒偏折煞世人情狂
[03:26.21]凭这两眼与百臂或千手不能防
[03:29.07]天阔阔雪漫漫共谁同航
[03:31.32]这沙滚滚水皱皱笑着浪荡
[03:33.92]贪欢一刻偏教那女儿情长埋葬
[03:39.32]吞风吻雨葬落日未曾彷徨
[03:41.84]欺山赶海践雪径也未绝望
[03:44.38]拈花把酒偏折煞世人情狂
[03:47.04]凭这两眼与百臂或千手不能防
[03:49.99]天阔阔雪漫漫共谁同航
[03:52.20]这沙滚滚水皱皱笑着浪荡
[03:54.89]贪欢一刻偏教那女儿情长埋葬
[04:00.28]吞风吻雨葬落日未曾彷徨
[04:02.68]欺山赶海践雪径也未绝望
[04:05.25]拈花把酒偏折煞世人情狂
[04:07.90]凭这两眼与百臂或千手不能防
[04:10.85]天阔阔雪漫漫共谁同航
[04:13.08]这沙滚滚水皱皱笑着浪荡
[04:15.75]贪欢一刻偏教那女儿情长埋葬
[04:19.48]`;

var lrc1 = `[00:00.000] 作词 : 张赢
[00:00.500] 作曲 : 罗锟
[00:01.000] 编曲 : 罗锟/陈雪燃
[00:01.500] 制作人 : 张赢/陈雪燃
[00:02.00]制作人(美国):Xueran Chen
[00:02.36]制作人(中国):张赢
[00:02.72]人声录音师:姚海毅
[00:03.05]和音:赵贝尔
[00:03.27]管弦乐团:Hungarian symphonic orchestras
[00:03.56]吉他:Jacob Boyd
[00:03.74]中国笛:Chris Bleth
[00:03.96]大提琴:Ro Rowan
[00:04.17]缩混工程师:NEM Studios
[00:04.46]母带工程师:Randy Merrill
[00:04.75]监制:宋鹏飞
[00:04.97]音乐出品发行公司:听见时代传媒
[00:05.80]
[00:19.71]初见若缱绻 誓言 风吹云舒卷
[00:26.17]
[00:26.98]岁月间 问今夕又何年
[00:32.00]
[00:33.44]心有犀但愿 执念 轮回过经年
[00:39.93]
[00:40.81]弹指间 繁花开落多少遍
[00:45.39]
[00:47.17]这一世牵绊 纠结 触动了心弦
[00:53.49]
[00:54.43]下一世 不知可否再见
[00:59.52]
[01:00.95]留一片桃花 纪念 了却浮生缘
[01:07.47]
[01:08.22]眉目间 还有我的思念
[01:13.01]
[01:15.02]一寸土 一年木 一花一树一贪图
[01:20.86]
[01:21.81]情是种 爱偏开在迷途
[01:27.16]
[01:28.68]忘前路 忘旧物 忘心忘你忘最初
[01:34.79]
[01:35.44]花斑斑 留在爱你的路
[01:41.15]
[01:55.85]这一世牵绊 纠结 触动了心弦
[02:02.19]
[02:02.91]下一世 不知可否再见
[02:08.08]
[02:09.37]留一片桃花 纪念 了却浮生缘
[02:16.02]
[02:16.60]眉目间 还有我的思念
[02:21.71]
[02:23.57]一寸土 一年木 一花一树一贪图
[02:29.52]
[02:30.32]情是种 爱偏开在迷途
[02:35.58]
[02:37.17]忘前路 忘旧物 忘心忘你忘最初
[02:43.30]
[02:43.94]花斑斑 留在爱你的路
[02:48.92]
[02:50.53]虔诚夙愿 来世路
[02:53.59]
[02:54.30]一念桃花因果渡
[02:56.99]
[02:57.65]那一念 几阙时光在重复
[03:03.46]
[03:04.67]听雨书 望天湖 人间寥寥情难诉
[03:11.37]回忆斑斑 留在爱你的路`;

mp3文件

tips:如果需要自行下载

图片文件

tips:如果需要去自行下载

本站代码模板仅供学习交流使用请勿商业运营,严禁从事违法,侵权等任何非法活动,否则后果自负!
文章版权声明 1 本网站名称: 智码星河
2 本站永久网址:https://wx234.cn
© 版权声明 文章版权归作者所有,未经允许请勿转载。

WX234.CN
喜欢就支持一下吧
点赞9 分享打赏
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

夸夸
夸夸
还有吗!没看够!
取消
昵称表情代码图片

    暂无评论内容