简单的歌词滚动效果

2,919 阅读1分钟

需求

跟随浏览器音频控制条的歌词滚动效果

效果图

功能点

  1. 歌词高亮
  2. 歌词滚动
  3. 进度条滑动-->歌词滚动

准备工作

数据

简单地,使用网易云音乐开发api,获取歌词以及mp3 developer.music.163.com/st/develope… 建立data.js将歌词放进去

页面结构html

  1. 把mp3放进去 <audio>
  2. 歌词容器 <div class="container">
  3. 歌词列表 <ul>
<audio controls src="./assets/song.mp3"></audio>
  <div class="container">
    <ul>
    </ul>
  </div>

页面基本css

  1. 页面背景(不重要)
  2. 取消列表的默认样式list-style
  3. 容器宽高边框,边距,文字,颜色

样式css

歌词滚动

  1. ul内根据歌词生成li
  2. 各li给定高度,全部歌词显示会越界,如下图
  3. 歌词滚动本质上是ul容器的上下移动,为.container容器设置overflow: hidden;,为ul设置过渡,上下移动时顺滑不卡顿transition: 0.5s

高亮样式

  1. 颜色改变
  2. 字体放大
  3. 过渡效果
.container ul li {
  width: 100%;
  height: 30px;
  color: #666;
  line-height: 30px;
  transition: all 0.5s;
}
.container ul li.active {
  color: #fff;
  transform: scale(1.2);
}

实现逻辑

  1. 获取将要使用的dom元素
var doms = {
  audio: document.querySelector("audio"),
  ul: document.querySelector("ul"),
  container: document.querySelector(".container"),
};
  1. 根据歌词生成li,并插入ul节点
function generateLrc() {
  const lrcArr = parseLrc(Lrc); // 歌词格式处理
  var frag = document.createDocumentFragment();
  for (let i = 0; i < lrcArr.length; i++) {
    var li = document.createElement("li");
    li.textContent = lrcArr[i].words;
    frag.appendChild(li);
  }
  doms.ul.appendChild(frag);
  return lrcArr;
}
const lrcArr = generateLrc(); // eg: [{times: 2, words: "第一句歌词"}]
  1. 根据控制条时间,找到高亮的li序号
function findIndex() {
  var currentTime = doms.audio.currentTime;
  var index = lrcArr.findIndex((e) => e.times > currentTime);
  if (index === -1) {
    index = lrcArr.length;
  }
  return index - 1;
  1. 计算容器高度,ul的最大偏移量
// 容器高度
var containerHeight = doms.container.clientHeight;
var liHeight = doms.ul.children[0].clientHeight;
// 最大偏移量
var maxOffset = doms.ul.clientHeight - containerHeight;
  1. 设置高亮以及ul偏移
function setOffset() {
  var index = findIndex();
  var offset = liHeight * index + liHeight / 2 - containerHeight / 2;
  if (offset < 0) {  // 已播放歌词较短,无需移动
    offset = 0;
  } else if (offset > maxOffset) { // 歌词末尾,不再移动
    offset = maxOffset;
  }
  doms.ul.style.transform = `translateY(-${offset}px)`;
  // 去掉前行歌词高亮
  var li = document.querySelector(".active");
  if (li) {
    li.classList.remove("active");
  }
  doms.ul.children[index]?.classList.add("active");
}

github地址:github.com/gmx-white/L… 下一步实现,歌曲频率的波动条。。。。