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

歌词滚动效果

<!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>

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

相关文章:

  • Docker镜像操作全攻略:从查看、拉取到删除
  • Stable Diffusion WebUI 插件大全:功能详解与下载地址
  • 命令行快速上传文件到SFTP服务器(附参考示例)
  • 配置Spark环境
  • 从规则驱动到深度学习:自然语言生成的进化之路
  • 人机环境体系的自主决策与机器系统的自主决策不同
  • 3337. 字符串转换后的长度 II
  • 微服务商城(1)开篇、服务划分
  • LLM(大语言模型)部署加速方法——PagedAttention
  • 【第六课】ESP32-S3 BLE 与 WiFi 一体化通信示例
  • 从0开始学linux韦东山教程第三章问题小结(4)
  • 内存分配器ptmalloc2、tcmalloc、jemalloc,结构设计、内存分配过程详解
  • fiftyone-数据库配置和config与app_config配置文件
  • 耐压击穿测试的原理、流程及应用领域
  • SymPy | 如何提取指定项的系数
  • LeetCode 820 单词的压缩编码题解
  • 笔记本电脑打开网页很慢,一查ip地址网段不对怎么处理
  • 数学建模初等模型应用
  • 影刀RPA网页自动化总结
  • TCP 三次握手建立连接详解
  • 澎湃·镜相第二届非虚构写作大赛初选入围名单公示
  • 92岁上海交大退休教师捐赠百万元给学校,其父也曾设奖学金
  • 哪种“网红减肥法”比较靠谱?医学专家和运动专家共同解答
  • MSCI中国指数5月调整:新增5只A股、1只港股
  • 经济日报:美国滥施汽车关税损人不利己
  • 金正恩观摩朝鲜人民军各兵种战术综合训练