js歌词滚动效果

目录

效果图展示:

一.素材准备:

1.歌词数据data.js:借鉴了网上copy下来的歌词模板

2.图片准备: 设置title效果

3.音频文件准备:

二.html块:

拓展 标签属性:

三.设置scss样式:

四.逻辑js块:

拓展:使用到的audio的事件:

效果图展示:

一.素材准备:

1.歌词数据data.js:借鉴了网上copy下来的歌词模板

const lrc = `
[00:00.000] 作词 : 黄家驹\n
[00:01.000] 作曲 : 黄家驹\n
[00:02.000] 编曲 : Beyond/梁邦彦\n
[00:03.000] 制作人 : Beyond/梁邦彦\n
[00:18.466]今天我 寒夜里看雪飘过\n
[00:25.110]怀着冷却了的心窝漂远方\n
[00:30.950]风雨里追赶 雾里分不清影踪\n
[00:37.229]天空海阔你与我\n
[00:40.291]可会变 (谁没在变)\n
[00:43.440]多少次 迎着冷眼与嘲笑\n
[00:50.050]从没有放弃过心中的理想\n
[00:55.907]一刹那恍惚 若有所失的感觉\n
[01:02.133]不知不觉已变淡\n
[01:05.243]心里爱 (谁明白我)\n
[01:08.801]原谅我这一生不羁放纵爱自由\n
[01:15.799]也会怕有一天会跌倒\n
[01:22.008]背弃了理想 谁人都可以\n
[01:28.276]哪会怕有一天只你共我\n
[01:34.102]\n
[01:42.695]今天我 寒夜里看雪飘过\n
[01:49.284]怀着冷却了的心窝漂远方\n
[01:55.189]风雨里追赶 雾里分不清影踪\n
[02:01.405]天空海阔你与我\n
[02:04.535]可会变 (谁没在变)\n
[02:08.014]原谅我这一生不羁放纵爱自由\n
[02:15.040]也会怕有一天会跌倒\n
[02:21.279]背弃了理想 谁人都可以\n
[02:27.531]哪会怕有一天只你共我\n
[02:33.633]\n
[03:08.454]仍然自由自我 永远高唱我歌\n
[03:15.064]走遍千里\n
[03:19.739]原谅我这一生不羁放纵爱自由\n
[03:26.734]也会怕有一天会跌倒\n
[03:33.005]背弃了理想 谁人都可以\n
[03:39.257]哪会怕有一天只你共我\n
[03:45.496]背弃了理想 谁人都可以\n
[03:51.756]哪会怕有一天只你共我\n
[03:57.201]原谅我这一生不羁放纵爱自由\n
[04:04.204]也会怕有一天会跌倒\n
[04:10.456]背弃了理想 谁人都可以\n
[04:16.647]哪会怕有一天只你共我\n
[04:22.828]\n
[04:31.852] 录音 : Shunichi Yokoi\n
[04:40.876] 混音 : Shunichi Yokoi\n
[04:49.900] 录音室 : Greenbird St./Tokyu Fun St./West Side St.(Tokyo/From Jan/to Apr./1993)\n
[04:58.924] 母带工程师 : Setsu Hisai at Tokyu Fun St.\n[05:07.948] 弦乐 : 桑野圣乐团 (Kuwano Strings)\n
[05:16.972] OP : Amuse Inc. & Fun House Inc.\n[05:25.996] SP : Amuse H.K. Ltd.`

2.图片准备: 设置title效果

3.音频文件准备:

二.html块:

拓展 <audio> 标签属性:

  • src:音乐的URL
  • preload:预加载
  • autoplay:自动播放
  • loop:循环播放
  • controls:浏览器自带的控制条
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    // 设置title
    <link rel="shortcut icon" href="./bitbug_favicon.ico" type="image/x-icon">
    // 引入css样式文件
    <link rel="stylesheet" href="./index.min.css">
</head>
<body>
    <audio src="./海阔天空.mp3" controls></audio>

    <div class="box">
        <ul class="lrc-list">
        </ul>
    </div>
</body>
// 引入歌词文件
<script src="./data.js"></script>
<script src="./index.js"></script>
</html>

三.设置scss样式:

*{

    margin: 0;
    padding: 0;
}
body{
    background: #000;
    color: #999;
    text-align: center;
}

audio{
    width: 80%;
    margin: 30px 0;
}

.box{
    height: 420px;
    border: 1px solid #fff;
    overflow: hidden;
    .lrc-list{
        list-style: none;
        transform: translateY(-0px);
        transition: 0.2s;
        li{
            line-height: 30px;
            transition: 0.2s;
        }
        .active{
            color: #fff;
            transform: scale(1.5);
        }
    }
}

四.逻辑js块:

const doms = {
    audio: document.querySelector('audio'),
    box: document.querySelector('.box'),
    lrcEl: document.querySelector('.lrc-list'),
    lis:document.querySelectorAll('.lrc-list li')
}

/**
 * 解析歌词字符串
 * 得到歌词字符串数组
 * {time:时间,words:歌词内容}
 */
function parseLrc() {
    const lines = lrc.split('\n')
    const result = lines.map(item => {
        const newItem = item.split(']')
        return {
            time: parseTime(newItem[0].slice(1)),
            words: newItem[1].trim(),
        }
    })
    return result
}
const lrcData = parseLrc()
console.log(lrcData);

/**
 * 将一个时间字符串解析为数字(秒)
 * @param {*} timeStr 
 * @returns 
 */
function parseTime(timeStr) {
    var part = timeStr.split(':')
    // console.log(part);
    return +part[0] * 60 + +part[1]
}

/**
 * 计算出,当前播放器播放的第几秒,lrcData数组中应该高亮的歌词下标
 */
function findIndex() {
    const currentTime = doms.audio.currentTime
    // console.log('currentTime', currentTime);
    for (var index = 0; index < lrcData.length; index++) {
        if (currentTime < lrcData[index].time) {
            return index - 1
        }
    }
    return lrcData.length - 1
}

// 渲染界面
function createLrcEl() {
    for (let index = 0; index < lrcData.length; index++) {
        const lis = document.createElement('li')
        lis.innerText = lrcData[index].words
        doms.lrcEl.appendChild(lis)
    }
}
createLrcEl()

// 盒子的高度
const boxHeight = doms.box.clientHeight
// 每个li的高度
const liHeight = doms.lrcEl.children[0].clientHeight
// 最大的高度
const maxHeight = doms.lrcEl.clientHeight - liHeight

function setOffset() {
    // 定位当前高亮歌词下标
    const lrcIndex = findIndex()
    // 计算需要移动的距离
    var moveHeight = liHeight * lrcIndex - (liHeight / 2) - (boxHeight / 2)
    if (moveHeight < 0) {
        moveHeight = 0
    }
    if (moveHeight > maxHeight) {
        moveHeight = maxHeight
    }
    doms.lrcEl.style.transform = `translateY(-${moveHeight}px)`

    // 添加高亮的样式
    const oldLi = doms.lrcEl.querySelector('.active')
    if(oldLi){
        oldLi.classList.remove('active')
    }
    const li = doms.lrcEl.children[lrcIndex]
    if (li) {
        li.classList.add('active')
    }
}

doms.audio.addEventListener('timeupdate', setOffset)

拓展:使用到的audio的事件:

audio.addEventListener("timeupdate", callback);
// 播放时间改变时触发

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值