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())

④:测试

相关推荐
糕冷小美n1 天前
elementuivue2表格不覆盖整个表格添加固定属性
前端·javascript·elementui
小哥不太逍遥1 天前
Technical Report 2024
java·服务器·前端
沐墨染1 天前
黑词分析与可疑对话挖掘组件的设计与实现
前端·elementui·数据挖掘·数据分析·vue·visual studio code
anOnion1 天前
构建无障碍组件之Disclosure Pattern
前端·html·交互设计
threerocks1 天前
前端将死,Agent 永生
前端·人工智能·ai编程
问道飞鱼1 天前
【前端知识】Vite用法从入门到实战
前端·vite·项目构建
爱上妖精的尾巴1 天前
8-10 WPS JSA 正则表达式:贪婪匹配
服务器·前端·javascript·正则表达式·wps·jsa
Aliex_git1 天前
浏览器 API 兼容性解决方案
前端·笔记·学习
独泪了无痕1 天前
useStorage:本地数据持久化利器
前端·vue.js
程序员林北北1 天前
【前端进阶之旅】JavaScript 一些常用的简写技巧
开发语言·前端·javascript