歌词滚动效果

需求

实现歌词滚动效果,类似网易云音乐播放界面。

实现

1.准备数据

后台一般会返回这样一个歌词数据,每个时间都对应当前这个歌词。

因为是字符串不方便直接使用,我们把他转化为对象格式。封装一个utils工具传入歌词把lyric转化为对象。

ini 复制代码
// 处理后端返回歌词
export const HandleLyric = (lyric) => {
    function convertToSeconds(timeArray) {
        // 获取分钟和秒(包括毫秒)  
        const minutes = parseFloat(timeArray[0]); // 使用parseFloat来确保即使分钟有小数部分也能正确处理  
        const secondsWithMilliseconds = parseFloat(timeArray[1]);
        // 计算总秒数  
        const totalSeconds = minutes * 60 + secondsWithMilliseconds;
        return totalSeconds;
    }
    let line = lyric.split('\n')
    let value1 = []
    for (let i = 0; i < line.length; i++) {
        let str = line[i]
        // 把字符串分割为数组
        let part = str.split(']')
        let timestr = part[0].substring(1)
        let parts = timestr.split(':')
        let obj = {
            time: convertToSeconds(parts),
            word: part[1]
        }
        value1.push(obj)
    }
    return value1
}
2.计算偏移量

准备audio标签

xml 复制代码
  <div class="audio">
      <el-button>立即播放/暂停</el-button>
      <audio :src="audio_info['url']" ref="audio" class="audio-sty">11</audio>
  </div>

调用audio标签的currentTime 可以获取当前歌曲播放到第几秒,遍历歌词的时间和当前时间(currentTime)比较,返回的i就是当前歌词的在第几行。

javascript 复制代码
const changeplay = () => {
    let audio = document.querySelector('.audio-sty')
     // 找到当前这一句歌词的索引
        function FindIndex() {
            let currentTime = audio.currentTime
            for (var i = 0; i < store.lyicWords.length; i++) {
                if (currentTime < store.lyicWords[i].time) {
                    return i - 1
                }
            }
            return store.lyicWords.length - 1
        } 
}

计算偏移量

ini 复制代码
        // 计算偏移量 
        /**
         * 偏移量
         * @containerHeight //容器高度
         * @PHeight   //单个歌词高度
         */
        function Setoffset() {
            var index = FindIndex()
            var offset = index * store.PHeight + store.PHeight / 2 - store.containerHeight / 2
            if (offset < 0) {
                offset = 0
            }
            store.index = index
            store.Offset = offset
        }

用当前歌词所偏移的大小加上单个歌词Height1/2的大小,就可以实现歌词偏移,如果想让每次高亮的歌词在中间,需要再减去container盒子自身Height的一半。


调用audio的timeupadte时间触发计算偏移函数

less 复制代码
  // audio 时间变化事件
audio.addEventListener('timeupdate', Setoffset)
3.添加样式
xml 复制代码
<div class="center" ref="center">
            <h1>歌词</h1>
<el-card class="box-center">
      <div class="center-ci" style="overflow: auto;" ref="lyricHeight">
      <p v-for="(item, index) in  songList['txt']" v-if="songList['txt'].length != 0"
                        :class="[index == store.index ? 'active' : '']">{{item }}</p>
       <p v-else>纯音乐,无歌词</p>
       </div>
</el-card>
</div>

使用transform: translateY(-50px);控制偏移

使用transform: scale(1.2);控制文字大小

css 复制代码
     .center-ci {
                transform: translateY(-50px);
                display: block;
                height: 100%;
                width: 100%;

                p {
                    transition: 0.2s;
                    font-size: 20px;
                    text-align: center;
                }

                .active {
                    transform: scale(1.2);
                    color: goldenrod;
                }
            }

给歌词容器设置transform就可以实现歌词偏移了

ini 复制代码
// 根据偏移量滚动歌词 
lyricHeight.value.style.transform = `translateY(-${store.Offset}px)`
4.效果

~谢谢观看

相关推荐
不一样的少年_17 小时前
明明做了很多事,为什么简历看起来还是没含金量?
前端·后端·招聘
mashang12345678917 小时前
mac安装SnailGitLite并配置Beyond Compare
前端·macos
雪芽蓝域zzs17 小时前
第三十四节:用户新增编辑弹窗增加 el‑tree‑select 部门选择器
前端·javascript·vue.js
程序员老赵18 小时前
Docker 部署 go2rtc:轻松搭建摄像头多协议流媒体平台
前端·docker·直播
巴勒个啦18 小时前
如何设计一个高可复用的前端组件库:从API设计到文档自动化
javascript
酷酷的逗逗乐18 小时前
前端转 Agent 开发 · 第三节:LangChain 提示词模板
前端
Cache技术分享18 小时前
516. Java 方法句柄 - 转换(进阶篇·下)
前端·后端
妙码生花18 小时前
全网 8k star 的 BuildAdmin 正式发布 Golang 版本,这次我们在CRUD赛道杀死了比赛。
前端·后端·ai编程
写代码像蔡徐抻18 小时前
三年了,AI为何还没有抢走程序员饭碗?
前端·后端·面试
梦曦i18 小时前
unix-router v0.1.0 首发:uni-app x 的 vue-router 风格路由库
前端·uni-app