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 将目标元素滚动到可视区域,传入的参数包括时间、水平和垂直的偏移。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/703552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

黑马程序员Java面试专题(2)|并发编程篇(1)线程基础

指路&#x1f449; 黑马程序员Java面试专题&#xff08;1&#xff09;|常见集合篇&#xff08;1&#xff09;ArrayList&LinkedList-CSDN博客https://blog.csdn.net/YOYU_/article/details/135932520黑马程序员Java面试专题&#xff08;1&#xff09;|常见集合篇&#xff0…

AI数字人SadTalker实战

1.概述 AI数字人在营销和品牌推广中扮演着至关重要的角色&#xff0c;许多企业和个人正积极利用数字技术来打造属于自己的财富。有没有一种简单而免费的方式来创建自己的数字人呢&#xff1f;本篇博客笔者将为大家介绍如何搭建属于自己的AI数字人。 2.内容 2.1 什么是SadTalker…

MySQL 篇-深入了解 DDL 语言(一)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 MySQL 说明 2.0 DDL 语言 2.1 DDL 语言 - 定义数据库 2.1.1 创建数据库操作 2.1.2 查看数据库操作 2.1.3 使用数据库操作 2.1.4 删除数据库操作 2.2 DDL 语言 …

LeetCode第二题: 两数相加

文章目录 题目描述示例 解题思路 - 迭代法Go语言实现 - 迭代法算法分析 解题思路 - 模拟法Go语言实现 - 模拟法算法分析 解题思路 - 优化模拟法主要方法其他方法的考虑 ‍ 题目描述 给出两个非空的链表用来表示两个非负的整数。其中&#xff0c;它们各自的位数是按照逆序的方…

2024.2.25 模拟实现 RabbitMQ —— 网络通信设计(服务器)

目录 引言 约定应用层的通信协议 自定义应用层协议 Type Length PayLod 实现 Broker Server 类 属性 与 构造 启动 Broker Server 停止 Broker Server 处理客户端连接 读取请求 与 写回响应 根据请求计算响应 清除 channel 引言 生产者 和 消费者 都是客户端&…

Onlyfans 地址错误、无法支付、年龄验证等问题解决方案!!!

很多客户在 Onlyfans 绑卡时&#xff0c;出现了地址错误&#xff0c;年龄验证&#xff0c;无法支付等各种问题。 出现这个问题的原因&#xff1a; 一是用国内邮箱注册了&#xff0c; 二是 ip 有问题&#xff0c;会导致出现年龄验证&#xff0c;或无法支付 Onlyfans 等问题。…

OpenHarmony 分布式开发实战——线上菜单

简介 分布式菜单demo 模拟的是多人聚餐点菜的场景&#xff0c;不需要扫码关注公众号等一系列操作&#xff0c;通过分布式数据库可以方便每个人可及时查看到订单详情&#xff0c;数量&#xff0c;总额等&#xff1b;效果如下 demo效果 工程目录 完整的项目结构目录如下 ├─…

linux系统---httpd

目录 Internet的起源 一、http协议——超文本传输协议 1.http相关概念 二、HTTP请求访问的完整过程 1、 建立连接 2、 接收请求 3、 处理请求 常用请求Method: GET、POST、HEAD、PUT、DELETE、TRACE、OPTIONS 3.1 常见的HTTP方法 3.2 GET和POST比较 4、访问资源 …

【postgresql】数据表id自增与python sqlachemy结合实例

需求&#xff1a; postgresql实现一个建表语句&#xff0c;表名&#xff1a;student,字段id,name,age&#xff0c; 要求&#xff1a;每次添加一个数据id会自动增加1 在PostgreSQL中&#xff0c;您可以使用SERIAL或BIGSERIAL数据类型来自动生成主键ID。以下是一个创建名为stude…

MongoDB之客户端工具与核心概念及基本类型篇

MongoDB之客户端工具与核心概念及基本类型篇 文章目录 MongoDB之客户端工具与核心概念及基本类型篇1. MongoDB是什么?1. 关于MongoDB2. 相关客户端工具1. MongoDB Compass2. Studio 3T3. Navicat for MongoDB4. NoSQL Manager for MongoDB Professional 2.MongoDB相关概念2.1 …

4.测试教程 - 用例篇

文章目录 1.测试用例的基本要素2.测试用例的给我们带来的好处3.测试用例的设计方法3.1基于需求进行测试用例的设计3.1.1功能需求测试分析3.1.2非功能需求测试分析 3.2具体的设计方法3.2.1等价类3.2.2边界值3.2.3错误猜测法3.2.4判定表3.2.5场景设计法3.2.6因果图3.2.7因果图的需…

Python 鼠标模拟

鼠标模拟即&#xff1a;通过python 进行模拟鼠标操作 引入类库 示例如下&#xff1a; import win32api import win32con import time 设置鼠标位置 设置鼠标位置为窗口中的回收站。 示例如下&#xff1a; # 设置鼠标的位置 win32api.SetCursorPos([30, 40]) 双击图标 设置…

springboot+vue前后端分离适配cas认证的跨域问题

0. cas服务搭建参考:CAS 5.3服务器搭建_cas-overlay-CSDN博客 1. 参照springsecurity适配cas的方式, 一直失败, 无奈关闭springssecurity认证 2. 后端服务适配cas: 参考前后端分离项目(springbootvue)接入单点登录cas_前后端分离做cas单点登录-CSDN博客 1) 引入maven依赖 …

如何系统地自学 Python

设定学习目标 确定自己学习 Python 的目的和用途&#xff0c;这一步很重要&#xff0c;比如是为了编写脚本、开发网站、进行数据分析等。设定清晰的学习目标&#xff0c;把目标拆分为一个个阶段的小目标&#xff0c;通过完成一个个小目标&#xff0c;得到正反馈&#xff0c;激…

SD-WAN解决企业组网中网络卡顿问题

网络卡顿已成为企业组网中一大难题&#xff0c;特别是随着办公应用系统的内网服务器或云端部署&#xff0c;员工对网络的依赖日益增加。面对网络卡顿问题&#xff0c;我们不得不深入思考如何提升工作效率并改善员工体验。本文将深入探讨企业组网中的网络问题&#xff0c;并介绍…

DeepMind基础世界模型Genie:一张草图即为一个世界,通用AI智能体要来了?

一张草图即为一个世界&#xff01;Google DeepMind 推出了首个以无监督方式从未经标注的互联网视频中训练而来的生成交互环境模型——Genie。该模型可以通过文本、合成图像、照片甚至草图来生成无数种可玩&#xff08;动作可控&#xff09;的虚拟世界。 据介绍&#xff0c;Geni…

使用管道和system V进行进程间通信

进程通信的目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#xff1a;多个进程之间共享同样的资源。通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它&#xff08;它们&#xff09;发生了某种事件&#xff08;如进程…

投资生涯的核心密码:构建交易逻辑体系

首先&#xff0c;我们需要明确一点&#xff0c;交易中究竟有没有确定性&#xff1f; 确定性是指在某一种形式、或有若干条件时&#xff0c;价格必然会上涨或下跌&#xff0c;也可以决定上涨或下跌的程度。 我认为&#xff0c;没有。迄今为止还没有一个理论能发现即使确定的东西…

python图像处理初步

文章目录 处理流程灰度分布图 处理流程 在Python中&#xff0c;通过【plt】和【numpy】可以实现图像处理的最简单的流程&#xff0c;即读取图片->处理图片->显示结果->保存结果。 import matplotlib.pyplot as plt import numpy as nppath lena.jpg img plt.imrea…

春节医美热,爱美客、昊海生科谁更赚钱?

在颜值经济赛道上&#xff0c;医美项目逐渐成为消费主流。随着春节假期的到来&#xff0c;医美消费又将迎来高峰期。 “医美三剑客”中&#xff0c;爱美客(300896.SZ)、昊海生科(688366.SH)近日相继公布了2023年的业绩报告&#xff1a;2023年&#xff0c;爱美客预计实现净利润…