React歌词滚动效果(跟随音乐播放时间滚动)

首先给audio绑定更新时间事件
const updateTime = e => {console.log(e.target.currentTime)setCurrentTime(e.target.currentTime);};<audiosrc={currentSong.url}ref={audio}onCanPlay={ready}onEnded={end}onTimeUpdate={updateTime}></audio>
当歌曲播放时间改变的时候会触发updateTime事件,如下所示
歌词json格式
[{"time": 2,"content": "采样曲:願い~あの頃のキミへ~","contents": ["采样曲:願い~あの頃のキミへ~"]},{"time": 12,"content": "中文填词:一只然","contents": ["中文填词:一只然"]},{"time": 15,"content": "OP(原属词曲版权公司):テレビ東京ミュージック 东京电视台音乐","contents": ["OP(原属词曲版权公司):テレビ東京ミュージック 东京电视台音乐"]},{"time": 19,"content": "本作品经过原词曲作者以及版权公司授权","contents": ["本作品经过原词曲作者以及版权公司授权"]},......]
接下来就是根据当前的播放时间显示歌词高亮,给歌词绑定高亮放大样式
.highlight {
color: $theme-color;
font-weight: $font-weight-bold;
font-size: 16px !important;
}
// 使用Redux的useSelector获取当前播放时间
const currentTime = useSelector(state => state.musicReducer.currentTime);// 使用React的useMemo优化性能,只有当currentTime变化时,才会重新计算time的值
const time= useMemo(() => {return currentTime;
},[currentTime]);// updateTime函数用于更新当前歌词的索引
const updateTime = e => {// 在所有歌词中找到第一个时间大于当前播放时间的歌词,其前一个歌词就是当前应该显示的歌词const currentLyricIndex = lyric.findIndex((lyricItem, index) => {// 判断是否是最后一项歌词,如果是,下一项歌词的时间设为无穷大const isLastItem = index === lyric.length - 1;const nextLyricTime = isLastItem ? Infinity : lyric[index + 1].time;// 如果当前播放时间在当前歌词和下一条歌词的时间之间,说明当前歌词应该被显示return time >= lyricItem.time && time < nextLyricTime;});// 更新当前歌词的索引setCurrentLyricIndex(currentLyricIndex);
};// 使用React的useEffect在time变化时,调用updateTime函数,更新当前歌词的索引
useEffect(() => {updateTime()
}, [time]);
当time发生变化时,调用updateTime函数来更新当前歌词的索引currentLyricIndex。确保在歌曲播放过程中,歌词随着时间的推移而更新。

最后,实现歌词滚动的效果
-
创建
scrollRef:const scrollRef = useRef();使用
useRef创建了一个scrollRef,用于引用 Scroll 组件的实例。 -
使用
useEffect进行歌词滚动:useEffect(() => {// 模拟异步加载歌词// 假设你要滚动到的歌词元素有一个特定的类名 ".lyric-item.highlight"const selector = '.lyric-item.highlight';// 调用 Scroll 组件的 scrollToElement 方法if (scrollRef.current) {scrollRef.current.scrollToElement(selector, 500); // 第二个参数是滚动时间,可以根据需要调整}}, [currentLyricIndex]);当
currentLyricIndex发生变化时,useEffect会被触发。在该效果中,它模拟异步加载歌词,然后通过scrollRef.current.scrollToElement方法滚动到指定的歌词元素,滚动时间为500毫秒。这样,每次歌词发生变化时都会滚动到当前高亮的歌词位置。 -
Scroll 组件的 scrollToElement 方法实现:
scrollToElement(selector, time = 0) {if (bScroll) {const targetElement = document.querySelector(selector);if (targetElement) {const containerHeight = scrollContainerRef.current.clientHeight;const targetHeight = targetElement.clientHeight;const offsetTop = (containerHeight - targetHeight) / 2;bScroll.scrollToElement(targetElement, time, 0, -offsetTop);}}}这是 Scroll 组件内部的
scrollToElement方法的实现。首先,通过document.querySelector(selector)获取到目标元素(具有指定类名的高亮歌词元素)。然后,计算目标元素相对于滚动容器的偏移,最后使用bScroll.scrollToElement将目标元素滚动到可视区域,传入的参数包括时间、水平和垂直的偏移。
相关文章:
React歌词滚动效果(跟随音乐播放时间滚动)
首先给audio绑定更新时间事件 const updateTime e > {console.log(e.target.currentTime)setCurrentTime(e.target.currentTime);};<audiosrc{currentSong.url}ref{audio}onCanPlay{ready}onEnded{end}onTimeUpdate{updateTime}></audio>当歌曲播放时间改变的时…...
java面试题之mybatis篇
什么是ORM? ORM(Object/Relational Mapping)即对象关系映射,是一种数据持久化技术。它在对象模型和关系型数据库直接建立起对应关系,并且提供一种机制,通过JavaBean对象去操作数据库表的数据。 MyBatis通过…...
Java的编程之旅19——使用idea对面相对象编程项目的创建
在介绍面向对象编程之前先说一下我们在idea中如何创建项目文件 使用快捷键CtrlshiftaltS新建一个模块,点击“”,再点New Module 点击Next 我这里给Module起名叫OOP,就是面向对象编程的英文缩写,再点击下面的Finish 点Apply或OK均可 右键src…...
docker build基本命令
背景 我们经常会构建属于我们应用自己的镜像,这种情况下编写dockerfile文件不可避免,本文就来看一下常用的dockerfile的指令 常用的dockerfile的指令 首先我们看一下docker build的执行过程 ENV指令: env指令用于设置shell的环境变量&am…...
nginx高级配置详解
目录 一、网页的状态页 1、状态页的基本配置 2、搭配验证模块使用 3、结合白名单使用 二、nginx 第三方模块 1、echo模块 1.1 编译安装echo模块 1.2 配置echo模块 三、nginx变量 1、内置变量 2、自定义变量 四、自定义图标 五、自定义访问日志 1、自定义日志格式…...
小程序--分包加载
分包加载是优化小程序加载速度的一种手段。 一、为什么进行分包 小程序限制单个包体积不超过2M; 分包可以优化小程序页面的加载速度。 二、启用/使用分包语法subPackages subPackages:下载app.json文件中 root:分包所在的目录 pages&#x…...
R语言【base】——writeLines()
Package base version 4.2.0 Description 向连接写入文本行。 Usage writeLines(text, con stdout(), sep "\n", useBytes FALSE) Arguments 参数【text】:一个字符向量。 参数【con】:一个 connection 对象 或 一个字符串。 参数【se…...
微信小程序-人脸检测
微信小程序的人脸检测功能,配合蓝牙,配合ESP32 可以实现一些有趣的玩具 本文先只说微信小程序的人脸检测功能 1、人脸检测使用了摄像头,就必须在用户隐私权限里面声明。 修改用户隐私声明后,还需要等待审核,大概一天 …...
微信小程序自制动态导航栏
写在前面 关于微信小程序导航栏的问题以及解决办法我已经在先前的文章中有提到,点击下面的链接即可跳转~ 🤏微信小程序自定义的导航栏🤏 在这篇文章中我们需要做一个这样的导航栏!先上效果图 👇👇…...
金融知识分享系列之:五日线
金融知识分享系列之:五日线 一、股票均线二、五日线三、五日线加量能三、五日线案例四、五日线案例五、五日线案例六、五日线案例七、五日线案例八、五日线案例 一、股票均线 股票均线是一种用于平滑股票价格的指标。它是根据一段时间内的股票价格计算得出的平均值…...
回归测试详解
🍅 视频学习:文末有免费的配套视频可观看 🍅 关注公众号:互联网杂货铺,回复1 ,免费获取软件测试全套资料,资料在手,涨薪更快 什么是回归测试 回归测试(Regression testi…...
渲染效果图有哪几种分类?效果图为什么用云渲染更快
云渲染利用了集群化的云端服务器资源,通过并行计算充分发挥了高性能硬件的优势,显著提升了渲染的速度。这一技术特别适用于处理规模庞大或细节丰富的渲染任务,在缩短项目完成时间方面表现卓越。无论是用于为建筑提供精确的可视化效果图&#…...
Docker镜像加速
前言 众所周知,我们常用的一些工具或系统的下载源都是国外的,这就会导致我们在下载一些东西时,会导致下载巨慢或者下载失败的情况,下面便是docker换下载源的教程 镜像加速 下面是几个常用的国内的镜像 科大镜像:ht…...
吴恩达deeplearning.ai:sigmoid函数的替代方案以及激活函数的选择
以下内容有任何不理解可以翻看我之前的博客哦:吴恩达deeplearning.ai专栏 文章目录 引入——改进下需求预测模型ReLU函数(整流线性单元 rectified linear unit)线性激活函数(linear activation function)激活函数的选择实现方式为什么需要激活函数 到现在…...
Alias许可分析中的数据可视化
Alias许可分析中的数据可视化:引领企业洞察合规之道的明灯 在信息化时代,数据可视化已成为各行各业的重要工具,能够帮助用户直观地理解和分析复杂的数据。在Alias许可分析中,数据可视化同样发挥着至关重要的作用,为企…...
【计算机网络】数据链路层--以太网/MTU/ARP/RARP协议
文章目录 一、以太网1.以太网帧格式2.MAC地址3.局域网的转发原理 二、MTU1.什么是MTU2.MTU对IP协议的影响3.MTU对UDP影响4.MTU对于TCP协议的影响 三、ARP协议1.ARP协议的作用2.ARP数据报的格式3.ARP协议的工作流程 一、以太网 “以太网” 不是一种具体的网络, 而是一种技术标准…...
typescript使用解构传参
看下面这个函数 interface Student {id: number;name: string;class: string;sex: string;}function matriculation(student: Student) {//...}我们要调用它,就需要传递一个实现了Student约束的对象进去 interface Student {id: number;name: string;class: string;sex: string…...
CSP-J 2023 复赛第4题:旅游巴士
【题目来源】https://www.luogu.com.cn/problem/P9751https://www.acwing.com/problem/content/description/5313/【题目描述】 小 Z 打算在国庆假期期间搭乘旅游巴士去一处他向往已久的景点旅游。 旅游景点的地图共有 n 处地点,在这些地点之间连有 m 条道路。 其中…...
JAVA算法和数据结构
一、Arrays类 1.1 Arrays基本使用 我们先认识一下Arrays是干什么用的,Arrays是操作数组的工具类,它可以很方便的对数组中的元素进行遍历、拷贝、排序等操作。 下面我们用代码来演示一下:遍历、拷贝、排序等操作。需要用到的方法如下 public…...
每日五道java面试题之spring篇(七)
目录: 第一题. 什么是Spring beans?第二题. 一个 Spring Bean 定义 包含什么?第三题. 如何给Spring 容器提供配置元数据?Spring有几种配置方式?第四题. Spring基于xml注入bean的几种方式?第五题:你怎样定义类的作用域…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
