03_歌词滚动效果

03_歌词滚动效果


文章目录


效果

一、数据准备

①:歌词

js 复制代码
var lrc = `[00:00.95]夜微凉 - 徐珊
[00:01.9]词:周敏君/徐珊
[00:02.85]曲:秦天
[00:03.8]编曲:秦天
[00:04.75]制作人:秦天
[00:05.7]配唱制作人:孙依哲/李少成
[00:06.65]制作统筹:宋双喜
[00:07.6]财务及行政协力:周美军/赵杨
[00:08.55]监制:吕军/张斌/柴奇/古国远
[00:09.5]出品人:侯俊/张健
[00:10.45]出品监制:秦朗
[00:11.4]艺人经纪:徐真真
[00:12.35]封面设计:LDG
[00:13.35]夜微凉
[00:15.72]灯微暗
[00:18.12]远处的你
[00:19.62]却如此温暖
[00:22.92]如果再没有什么
[00:25.29]结果是我相信你
[00:27.99]会使
[00:29.22]我更加心安
[00:34.59]拥抱世界美丽
[00:37.02]此刻我想拥抱你
[00:39.42]如果再没有什么
[00:41.46]结果是我相信你
[00:44.22]会使我心
[00:45.54]更安静
[00:47.22]遇到烦心
[00:48.99]放于时间里慢慢说给你听
[00:57.42]会让你走出凹凸地 平线
[01:00.99]因为这自信
[01:02.85]让我更加情愿
[01:06.99]道路总是走走停停
[01:10.86]只是你还心有不安
[01:15.45]遇到烦心
[01:17.01]因为我不想让你看到
[01:20.22]看到我忧伤的表情
[01:24.99]放于时间里
[01:27.39]慢慢的说给你听
[01:30.09]稀释忧愁
[01:31.89]面对不安
[01:36.990005]拥抱世界美丽
[01:39.42]此刻我想拥抱你
[01:41.85]如果再没有什么
[01:43.86]结果是我相信你
[01:46.619995]会使我心
[01:47.94]更安静
[01:49.65]遇到烦心
[01:51.39]放于时间里慢慢说给你
[01:57.509995]夜微凉
[01:58.92]灯微暗
[02:01.29]远处的你
[02:02.79]却如此温暖
[02:06.06]如果再没有什么
[02:08.46]结果是我相信你
[02:11.22]会使
[02:12.42]我更加心安
[02:15.45]遇到烦心
[02:17.01]因为我不想让你看到
[02:20.22]看到我忧伤的表情
[02:24.95999]放于时间里
[02:27.39]慢慢的说给你听
[02:30.06]稀释忧愁
[02:31.89]面对不安
[02:34.59]拥抱世界美丽
[02:36.99]此刻我想拥抱你
[02:39.45]如果再没有什么
[02:41.45999]结果是我相信你
[02:44.22]会使我心
[02:45.54001]更安静
[02:47.22]遇到烦心
[02:48.99]放于时间里慢慢说给你听`

②:音频等

  • 资源在文章的顶部绑定

二、代码实现

①:首页

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>歌词滚动效果</title>
    <link rel="shortcut icon" href="./assets/favicon.ico" type="image/x-icon">
    <link rel="stylesheet" href="./css/index.css">
</head>
<body>
<audio controls src="./assets/夜微凉.mp3"></audio>
<div class="container">
    <ul class="lrc-list">
    </ul>
</div>
<script src="./js/data.js"></script>
<script src="./js/index.js"></script>

</body>
</html>

②:样式

css 复制代码
* {
    padding: 0;
    margin: 0;
}
body{
    background-color: black;
    color: #666;
    text-align: center;
}
audio{
    width: 450px;
    height: 50px;
    margin: 30px 0;
}
.container{
    height: 420px;
    overflow: hidden;
}
.container ul{
    transition: 0.5s;
    list-style: none;
}
.container li{
    height: 30px;
    line-height: 30px;
    transition: 0.2s;
}
.container .lrc-list .active{
    color: #fff;
    transform: scale(1.3);
}

③:js逻辑

js 复制代码
/**
 * 解析歌词字符串 得到每个歌词的对象
 * {time: 开始时间, words: 歌词内容}
 */
var lrcArray = [];

function parseLrc() {
    let lines = lrc.split("\n");
    lines.forEach(item => {
        let parts = item.split("]");
        var timeStr = parts[0].substr(1);
        let time = parseTime(timeStr);
        var obj = {
            time: time,
            words: parts[1]
        }
        lrcArray.push(obj);
    })
    return lrcArray;
}

/**
 * 获取需要的dom
 */
var dom = {
    audio: document.querySelector("audio"),
    ul: document.querySelector('.container ul'),
    container: document.querySelector('.container'),
}

/**
 * 将字符串转成时间数字 01:02.85 ==> 1*60 + 2.85(秒)
 * @param timeStr 时间字符串
 */
function parseTime(timeStr) {
    let split = timeStr.split(":");
    return +split[0] * 60 + +split[1]
}

/**
 * 计算出,在当前播放器播放到几秒的情况下
 * lrcArray 数组中 应该高亮显示的歌词下标
 * -1 没有任何一句歌词需要显示
 */
function findIndex() {
    // 播放器当前时间
    let time = dom.audio.currentTime;
    for (let i = 0; i < lrcArray.length; i++) {
        if (lrcArray[i].time > time) {
            return i - 1
        }
    }
    // 如果大于最后一句歌词时间 显示最后一句歌词
    return lrcArray.length - 1
}

console.log(parseLrc());


/**
 * 创建歌词元素 li
 */
function createLrcElements(){
    lrcArray.forEach(item =>{
        var li = document.createElement("li");
        li.textContent = item.words
        dom.ul.appendChild(li)
    })
}
createLrcElements()

// 容器的高度
let containerHeight = dom.container.clientHeight;
// 每一个li的高度
let liHeight = dom.ul.children[0].clientHeight;
// 最大便宜量
let max = dom.ul.clientHeight - containerHeight;

/**
 * 设置ul的偏移量
 */
function setOffset() {
    let index = findIndex();
    let h1 = liHeight * index + liHeight / 2 - containerHeight / 2
    if (h1 < 0){
        h1 = 0
    }
    if (h1 > max){
        h1 = max
    }
    // 去掉之前的 active 样式
    let li = dom.ul.querySelector('.active');
    if (li){
        li.classList.remove('active')
    }

    dom.ul.style.transform = `translateY(-${h1}px)`
    li = dom.ul.children[index];
    if (li){
        li.classList.add('active')
    }
}
dom.audio.addEventListener('timeupdate', () => setOffset())

④:测试

相关推荐
y先森32 分钟前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy32 分钟前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu108301891135 分钟前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿2 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡3 小时前
commitlint校验git提交信息
前端
虾球xz3 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇3 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒3 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员4 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐4 小时前
前端图像处理(一)
前端