React实现歌词滚动效果(跟随音乐播放时间滚动)
作者:点点关注不迷路
这篇文章主要为大家详细介绍了React实现歌词滚动效果(跟随音乐播放使劲按滚动),文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
首先给audio绑定更新时间事件
const updateTime = e => { console.log(e.target.currentTime) setCurrentTime(e.target.currentTime); }; <audio src={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实现歌词滚动效果(跟随音乐播放时间滚动)的详细内容,更多关于React歌词滚动的资料请关注脚本之家其它相关文章!