当前位置: 首页 > ai >正文

歌词滚动效果

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><!-- 设置标签页图标 --><link rel="shortcut icon" href="./favicon.ico" type="image/x-icon"><title>Document</title><style>html {background: #000;color: aliceblue;width: 100%;height: 100%;}body {display: flex;flex-direction: column;width: 100%;height: 100%;overflow: hidden;}ul, li {margin: 0;padding: 0;}.head {flex: none;display: flex;justify-content: center;align-items: center;padding: 30px 0;}img {width: 100px;height: 100px;border-radius: 50%;margin-right: 20px;}.right {display: flex;flex-direction: column;justify-content: center;}.des {margin: 6px;padding-left: 7px;}audio {width: 600px;height: 60px;}.content {flex: 1;overflow: hidden;margin: 0;}#list {list-style: none;transition: .5s ease;}.lyric {text-align: center;height: 40px;line-height: 40px;transition:  0.2s;}.active {/* font-size: 20px; // 过渡会引起回流,推荐使用tranform */transform: scale(1.2);color: aquamarine;}</style>
</head>
<body><div class="head"><img src="http://p3fx.kgimg.com/uploadpic/softhead/120/20241213/20241213201306973919.jpg" /><div class="right"><p class="des">江语晨-最后一页</p><!-- 加controls这个属性才能看到audio标签 --><audio controls autoplay src = "https://sharefs.tx.kugou.com/202505141511/3fdf7e70100a2d282f80b08266c04d5d/v3/653e2f76f69079273c79f65fecf58aea/yp/full/ap1000_us0_pi409_s2981929298.mp3"></div></div><div class="content"><ul id="list"></ul></div><script>    const lyr = "[00:00.00]滴滴音乐网 www.dda5.com\n[00:00.20]\n[00:00.56]雨停滞天空之间\n[00:04.07]像泪在眼眶盘旋\n[00:07.90]这也许是最后一次见面\n[00:15.43]沿途经过的从前\n[00:19.14]还来不及再重演\n[00:23.86]拥抱早已悄悄冷却\n[00:30.84]海潮声 淹没了离别时的黄昏\n[00:38.36]只留下不舍的体温\n[00:45.70]星空下 拥抱着快凋零的温存\n[00:52.96]爱只能在回忆里完整\n[01:03.92]想把你抱进身体里面\n[01:09.45]不敢让你看见\n[01:13.09]嘴角那颗没落下的泪\n[01:19.73]如果这是最后的一页\n[01:24.34]在你离开之前\n[01:28.08]能否让我把故事重写\n[02:38.01]雨停滞天空之间\n[02:41.62]像泪在眼眶盘旋\n[02:45.45]这也许是最后一次见面\n[02:53.00]沿途经过的从前\n[02:56.70]还来不及再重演\n[03:01.47]拥抱早已悄悄冷却\n[03:08.49]海潮声 淹没了离别时的黄昏\n[03:15.89]只留下不舍的体温\n[03:23.26]星空下 拥抱着快凋零的温存\n[03:30.52]爱只能在回忆里完整\n[03:37.83]想把你抱进身体里面\n[03:43.08]不敢让你看见\n[03:46.85]嘴角那颗没落下的泪\n[03:52.90]如果这是最后的一页\n[03:58.10]在你离开之前\n[04:01.81]能否让我把故事重写\n[04:08.04]想把你抱进身体里面\n[04:13.23]不敢让你看见\n[04:16.83]嘴角那颗没落下的泪\n[04:22.88]如果这是最后的一页\n[04:28.12]在你离开之前\n[04:31.83]能否让我把故事重写\n";const avatar = "http://p3fx.kgimg.com/uploadpic/softhead/120/20241213/20241213201306973919.jpg";const src = "https://sharefs.tx.kugou.com/202505141511/3fdf7e70100a2d282f80b08266c04d5d/v3/653e2f76f69079273c79f65fecf58aea/yp/full/ap1000_us0_pi409_s2981929298.mp3";const audio = document.querySelector('audio');audio.src = src;const lyrics = lyr.split('\n').filter(v => v).map((item) => {// const matchs = item.match(/\[(\S+)\](\S*)/);const [_, time, sentence] = item.split(/[\[\]]/); // 根据[或]符号分割const [minute, second] = time.split(':');  // 00:30.84const fTime = +minute * 60 + +second;return { time: fTime, sentence };});console.log('lyrics', lyrics);const content = document.querySelector('.content');const list = document.querySelector('#list');// 创建一个文档片段,把所有dom的操作先应用在这个片段上,之后将片段加入文档,就可以做到将多次dom操作合并成一次,提高效率。const frag = document.createDocumentFragment();lyrics.forEach(({ sentence }) => {const li = document.createElement('div');//innerText和textContent的区别;attributes和property的区别li.innerText = sentence;// add remove toggleli.classList.add('lyric');// 操作dom树次数过多,需要优化frag.appendChild(li);});list.appendChild(frag);// console.dir(list);audio.play();// 监听歌曲进度,设置歌词偏移量const contentHeight = content.clientHeight;const listHeight = list.clientHeight;const lyricHeight = list.children[0].clientHeight;const minOffset = 0;const maxOffset = listHeight - contentHeight;const scrollSentence = () => {const currentTime = audio.currentTime;const index = lyrics.findIndex(({ time }) => time > currentTime);const currentIndex = index < 0 ? lyrics.length - 1 : index - 1;let offset = currentIndex * lyricHeight + lyricHeight / 2 - contentHeight / 2;if (offset < 0) {offset = 0;}if (offset > maxOffset) {offset = maxOffset;}list.style.transform = `translateY(-${offset}px)`;const activeLi =  list.querySelector('.active');if (activeLi) {activeLi.classList.remove('active');}const li = list.children[currentIndex];if (li) {li.classList.add('active');}}audio.ontimeupdate = (e) => {scrollSentence();};</script>
</body>
</html>

效果:
在这里插入图片描述

http://www.xdnf.cn/news/6023.html

相关文章:

  • MFC 调用海康相机进行软触发
  • 在Electron中实现文件下载、保存和执行功能的完整教程
  • C++类和对象:运行符重载、取地址运算符重载、const 修饰的类如何作为参数
  • SpringBoot Vue MySQL酒店民宿预订系统源码(支付宝沙箱支付)+代码讲解视频
  • 2025年PMP 学习十三 第9章 项目资源管理(9.1,9.2)
  • Jenkins里构建一个简单流水线
  • Web 架构之会话保持深度解析
  • 关于 js:9. Node.js 后端相关
  • 移动网页调试工具实战:从 Chrome 到 WebDebugX 的效率演进
  • 数据结构 栈和队列
  • Pytorch的Dataloader使用详解
  • 技术中台-核心技术介绍(微服务、云原生、DevOps等)
  • 计算机视觉最不卷的方向:三维重建学习路线梳理
  • 安装npm:npm未随Node.js一起安装
  • NeurIPS Paper Checklist中文翻译
  • ubuntu20.04系统搭建k8s1.28集群-docker作为容器运行时
  • 视网膜屏幕:重新定义数字显示的革命性技术
  • Go 语言 net/http 包使用:HTTP 服务器、客户端与中间件
  • 游戏引擎学习第278天:将实体存储移入世界区块
  • RabbitMq消息阻塞,立即解决方案
  • 使用Thrust库实现异步操作与回调函数
  • spark数据清洗
  • 代码随想录训练营第二十三天| 572.另一颗树的子树 104.二叉树的最大深度 559.N叉树的最大深度 111.二叉树的最小深度
  • 编程日志5.5
  • 第8章-9 优化技巧2
  • 2025年Flutter项目管理技能要求
  • 数据库系统概论(八)SQL单表查询语言超详细讲解(附带例题表格对比带你一步步掌握)
  • 智能体制作学习笔记1——智能体
  • 【前端】:单 HTML 去除 Word 批注
  • 实战案例:采集 51job 企业招聘信息