2.gif
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
background-color: #000;
color: #666;
text-align: center;
}
audio {
width: 500px;
margin-bottom: 50px;
}
.container {
/* li的高度的倍數(shù)邪驮,避免文字處于container邊框上粗截,展示一半文字 */
height: 300px;
background-color: yellowgreen;
overflow-y: hidden;
}
ul {
list-style: none;
padding: 0;
margin: 0;
transition: all 0.3s;
}
ul > li {
height: 30px;
line-height: 30px;
transition: all 0.2s;
}
ul > li.active {
color: #fff;
transform: scale(1.3);
}
</style>
</head>
<body>
<audio controls></audio>
<div class="container">
<ul></ul>
</div>
<script>
(async function () {
const lyricData = [
"[00:01.06]難念的經(jīng)",
"[00:03.95]演唱:周華健",
"[00:06.78]",
"[00:30.96]笑你我枉花光心計",
"[00:34.15]愛竟逐鏡花那美麗",
"[00:36.75]怕幸運(yùn)會轉(zhuǎn)眼遠(yuǎn)逝",
"[00:39.32]為貪癡喜惡怒著迷",
"[00:41.99]責(zé)你我太貪功戀",
"[00:44.48]怪大地宗生太美麗",
"[00:47.00]悔舊日太執(zhí)信約誓",
"[00:49.66]為悲歡哀怨妒著迷",
"[00:52.56]啊 舍不得璀璨俗世",
"[00:57.66]啊 躲不開癡戀的欣慰",
];
const sizeData = {
liHeight: 30,
containerHeight: 300,
};
const ul = document.querySelector("ul");
const audio = document.querySelector("audio");
let lyricList = [];
function init() {
lyricList = lyricData.map((it) => {
const parts = it.split("]");
const timeParts = parts[0].replace("[", "").split(":");
return {
time: +timeParts[0] * 60 + +timeParts[1],
words: parts[1],
};
});
ul.innerHTML = lyricList
.map((it) => {
return `<li>${it.words}</li>`;
})
.join("");
}
await init();
audio.addEventListener("timeupdate", function () {
setStatus(this.currentTime);
});
function setStatus(time) {
// 清除之前高亮的li谬返;
const activeLi = document.querySelector(".active");
activeLi && activeLi.classList.remove("active");
// 提前一點(diǎn)時間讓li高亮豹悬,否則同時高亮且加上動畫時間會覺得有延遲;
time += 0.3;
// 根據(jù)當(dāng)前播放的時間找到對應(yīng)的li兄世,設(shè)置高亮壳快;
const index =
lyricList.findIndex((it) => {
return it.time > time;
}) - 1;
if (index < 0) return;
ul.children[index].classList.add("active");
// 滾動距離等于當(dāng)前l(fā)i的高度乘以當(dāng)前l(fā)i的個數(shù)燕侠,再加一個li高度的一半,就是當(dāng)前l(fā)i的中間位置孵构;
let top =
sizeData.liHeight * index +
sizeData.liHeight / 2 -
sizeData.containerHeight / 2;
// 沿Y軸向上負(fù)數(shù)滾動屁商;
top = -top;
if (top > 0) top = 0;
ul.style.transform = `translateY(${top}px)`;
}
setTimeout(() => {
setStatus(37);
}, 1000);
setTimeout(() => {
setStatus(40);
}, 2000);
setTimeout(() => {
setStatus(42);
}, 3000);
setTimeout(() => {
setStatus(0);
}, 4000);
})();
</script>
</body>
</html>
第一個li為top0,默認(rèn)在container第一個位置颈墅;只需求出紅色的高度