歌词滚动显示
- 环境准备
- html
- data.js歌词
- css
- 解析歌词为对象数组
- 查找指定时间点的歌词
- 创建歌词元素li
- 计算偏移量
- 监听播放时间执行偏移计算
模仿音乐软件实现歌词随播放时间滚动显示
环境准备
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="./12.css">
</head>
<body>
<audio src="https://lx-sycdn.kuwo.cn/7d4355bcb05cd643e29c2a9da660f643/659c95da/resource/n1/29/63/1116273328.mp3?from=vip" controls ></audio>
<div class ="container">
<ul class="lrc">
</ul>
</div>
</body>
<script src="./data.js"></script>
<script src="./12.js"></script>
</html>
data.js歌词
const data = `
[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]天阔阔雪漫漫共谁同航
`
css
*{
margin: 0;
padding: 0;
}
body{
background-color: #000;
color: #666;
/*居中*/
text-align: center;
}
audio{
width: 450px;
margin: 30px 0;
}
.container{
height: 420px;
overflow: hidden;
border: 2px solid #fff;
}
.container ul{
border: 2px solid #fff;
transition: 0.2s;
list-style: none;
}
.container li{
height: 30px;
/*border: 1px solid #fff;*/
line-height: 30px;
/*动画*/
transition: 0.5s;
}
.container li.active{
color: #fff;
/*使文字放大1.5倍*/
transform: scale(1.5);
}
解析歌词为对象数组
function parseData(data){
var result = [];
var lines = data.split('\n');
for (let i = 1; i < lines.length-1; i++) {
var line = lines[i];
var str = line.split("]");
var time = str[0].substring(1);
var obj ={
time: parseTime(time),
words: str[1]
}
result.push(obj);
}
return result;
}
/**
* 解析时间字符串为数字(秒)
* @param time
* @returns {number}
*/
function parseTime(time){
var parts = time.split(":");
return parts[0] *60 + +parts[1];
}
查找指定时间点的歌词
var doms = {
audio: document.querySelector('audio'),
ul: document.querySelector('.lrc'),
container: document.querySelector('.container'),
}
function findIndex(){
//播放器当前时间
let cuTime = doms.audio.currentTime;
console.log(cuTime)
for (let i = 0; i < lrcData.length; i++) {
if(lrcData[i].time > cuTime){
return i - 1;
}
if(lrcData.length - 1 === i){
//最后一条歌词下标
return lrcData.length - 1;
}
}
}
创建歌词元素li
function createLrcElements(){
//文档片段
var frag = document.createDocumentFragment();
for (let i = 0; i < lrcData.length; i++) {
var li = document.createElement('li');
li.textContent = lrcData[i].words;
frag.appendChild(li);
}
doms.ul.appendChild(frag);
}
createLrcElements();
计算偏移量
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)';
//去除之前的active样式
let activeLi = doms.ul.querySelector('.active');
if(activeLi){
activeLi.classList.remove('active');
}
let li = doms.ul.children[index];
if(li){
li.classList.add('active');
}
console.log(offset)
}
监听播放时间执行偏移计算
doms.audio.addEventListener('timeupdate', setOffset);