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

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。确保在歌曲播放过程中,歌词随着时间的推移而更新。

最后,实现歌词滚动的效果

  1. 创建 scrollRef

    const scrollRef = useRef();

    使用 useRef 创建了一个 scrollRef,用于引用 Scroll 组件的实例。

  2. 使用 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毫秒。这样,每次歌词发生变化时都会滚动到当前高亮的歌词位置。

  3. 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&#xff1f; ORM&#xff08;Object/Relational Mapping&#xff09;即对象关系映射&#xff0c;是一种数据持久化技术。它在对象模型和关系型数据库直接建立起对应关系&#xff0c;并且提供一种机制&#xff0c;通过JavaBean对象去操作数据库表的数据。 MyBatis通过…...

Java的编程之旅19——使用idea对面相对象编程项目的创建

在介绍面向对象编程之前先说一下我们在idea中如何创建项目文件 使用快捷键CtrlshiftaltS新建一个模块&#xff0c;点击“”&#xff0c;再点New Module 点击Next 我这里给Module起名叫OOP,就是面向对象编程的英文缩写&#xff0c;再点击下面的Finish 点Apply或OK均可 右键src…...

docker build基本命令

背景 我们经常会构建属于我们应用自己的镜像&#xff0c;这种情况下编写dockerfile文件不可避免&#xff0c;本文就来看一下常用的dockerfile的指令 常用的dockerfile的指令 首先我们看一下docker build的执行过程 ENV指令&#xff1a; env指令用于设置shell的环境变量&am…...

nginx高级配置详解

目录 一、网页的状态页 1、状态页的基本配置 2、搭配验证模块使用 3、结合白名单使用 二、nginx 第三方模块 1、echo模块 1.1 编译安装echo模块 1.2 配置echo模块 三、nginx变量 1、内置变量 2、自定义变量 四、自定义图标 五、自定义访问日志 1、自定义日志格式…...

小程序--分包加载

分包加载是优化小程序加载速度的一种手段。 一、为什么进行分包 小程序限制单个包体积不超过2M&#xff1b; 分包可以优化小程序页面的加载速度。 二、启用/使用分包语法subPackages subPackages&#xff1a;下载app.json文件中 root&#xff1a;分包所在的目录 pages&#x…...

R语言【base】——writeLines()

Package base version 4.2.0 Description 向连接写入文本行。 Usage writeLines(text, con stdout(), sep "\n", useBytes FALSE) Arguments 参数【text】&#xff1a;一个字符向量。 参数【con】&#xff1a;一个 connection 对象 或 一个字符串。 参数【se…...

微信小程序-人脸检测

微信小程序的人脸检测功能&#xff0c;配合蓝牙&#xff0c;配合ESP32 可以实现一些有趣的玩具 本文先只说微信小程序的人脸检测功能 1、人脸检测使用了摄像头&#xff0c;就必须在用户隐私权限里面声明。 修改用户隐私声明后&#xff0c;还需要等待审核&#xff0c;大概一天 …...

微信小程序自制动态导航栏

写在前面 关于微信小程序导航栏的问题以及解决办法我已经在先前的文章中有提到&#xff0c;点击下面的链接即可跳转~ &#x1f90f;微信小程序自定义的导航栏&#x1f90f; 在这篇文章中我们需要做一个这样的导航栏&#xff01;先上效果图 &#x1f447;&#x1f447;&#x1f…...

金融知识分享系列之:五日线

金融知识分享系列之&#xff1a;五日线 一、股票均线二、五日线三、五日线加量能三、五日线案例四、五日线案例五、五日线案例六、五日线案例七、五日线案例八、五日线案例 一、股票均线 股票均线是一种用于平滑股票价格的指标。它是根据一段时间内的股票价格计算得出的平均值…...

回归测试详解

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 关注公众号&#xff1a;互联网杂货铺&#xff0c;回复1 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 什么是回归测试 回归测试&#xff08;Regression testi…...

渲染效果图有哪几种分类?效果图为什么用云渲染更快

云渲染利用了集群化的云端服务器资源&#xff0c;通过并行计算充分发挥了高性能硬件的优势&#xff0c;显著提升了渲染的速度。这一技术特别适用于处理规模庞大或细节丰富的渲染任务&#xff0c;在缩短项目完成时间方面表现卓越。无论是用于为建筑提供精确的可视化效果图&#…...

Docker镜像加速

前言 众所周知&#xff0c;我们常用的一些工具或系统的下载源都是国外的&#xff0c;这就会导致我们在下载一些东西时&#xff0c;会导致下载巨慢或者下载失败的情况&#xff0c;下面便是docker换下载源的教程 镜像加速 下面是几个常用的国内的镜像 科大镜像&#xff1a;ht…...

吴恩达deeplearning.ai:sigmoid函数的替代方案以及激活函数的选择

以下内容有任何不理解可以翻看我之前的博客哦&#xff1a;吴恩达deeplearning.ai专栏 文章目录 引入——改进下需求预测模型ReLU函数(整流线性单元 rectified linear unit&#xff09;线性激活函数(linear activation function)激活函数的选择实现方式为什么需要激活函数 到现在…...

Alias许可分析中的数据可视化

Alias许可分析中的数据可视化&#xff1a;引领企业洞察合规之道的明灯 在信息化时代&#xff0c;数据可视化已成为各行各业的重要工具&#xff0c;能够帮助用户直观地理解和分析复杂的数据。在Alias许可分析中&#xff0c;数据可视化同样发挥着至关重要的作用&#xff0c;为企…...

【计算机网络】数据链路层--以太网/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 处地点&#xff0c;在这些地点之间连有 m 条道路。 其中…...

JAVA算法和数据结构

一、Arrays类 1.1 Arrays基本使用 我们先认识一下Arrays是干什么用的&#xff0c;Arrays是操作数组的工具类&#xff0c;它可以很方便的对数组中的元素进行遍历、拷贝、排序等操作。 下面我们用代码来演示一下&#xff1a;遍历、拷贝、排序等操作。需要用到的方法如下 public…...

每日五道java面试题之spring篇(七)

目录&#xff1a; 第一题. 什么是Spring beans&#xff1f;第二题. 一个 Spring Bean 定义 包含什么&#xff1f;第三题. 如何给Spring 容器提供配置元数据&#xff1f;Spring有几种配置方式?第四题. Spring基于xml注入bean的几种方式?第五题&#xff1a;你怎样定义类的作用域…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...