React實現(xiàn)歌詞滾動效果(跟隨音樂播放時間滾動)

首先給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>當歌曲播放時間改變的時候會觸發(fā)updateTime事件,如下所示

歌詞json格式
[
{
"time": 2,
"content": "采樣曲:願い~あの頃のキミへ~",
"contents": [
"采樣曲:願い~あの頃のキミへ~"
]
},
{
"time": 12,
"content": "中文填詞:一只然",
"contents": [
"中文填詞:一只然"
]
},
{
"time": 15,
"content": "OP(原屬詞曲版權公司):テレビ東京ミュージック 東京電視臺音樂",
"contents": [
"OP(原屬詞曲版權公司):テレビ東京ミュージック 東京電視臺音樂"
]
},
{
"time": 19,
"content": "本作品經(jīng)過原詞曲作者以及版權公司授權",
"contents": [
"本作品經(jīng)過原詞曲作者以及版權公司授權"
]
},
......
]接下來就是根據(jù)當前的播放時間顯示歌詞高亮,給歌詞綁定高亮放大樣式
.highlight {
color: $theme-color;
font-weight: $font-weight-bold;
font-size: 16px !important;
}// 使用Redux的useSelector獲取當前播放時間
const currentTime = useSelector(state => state.musicReducer.currentTime);
// 使用React的useMemo優(yōu)化性能,只有當currentTime變化時,才會重新計算time的值
const time= useMemo(() => {
return currentTime;
},[currentTime]);
// updateTime函數(shù)用于更新當前歌詞的索引
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變化時,調(diào)用updateTime函數(shù),更新當前歌詞的索引
useEffect(() => {
updateTime()
}, [time]);當time發(fā)生變化時,調(diào)用updateTime函數(shù)來更新當前歌詞的索引currentLyricIndex。確保在歌曲播放過程中,歌詞隨著時間的推移而更新。

最后,實現(xiàn)歌詞滾動的效果
創(chuàng)建 scrollRef:
const scrollRef = useRef();
使用 useRef 創(chuàng)建了一個 scrollRef,用于引用 Scroll 組件的實例。
使用 useEffect 進行歌詞滾動:
useEffect(() => {
// 模擬異步加載歌詞
// 假設你要滾動到的歌詞元素有一個特定的類名 ".lyric-item.highlight"
const selector = '.lyric-item.highlight';
// 調(diào)用 Scroll 組件的 scrollToElement 方法
if (scrollRef.current) {
scrollRef.current.scrollToElement(selector, 500); // 第二個參數(shù)是滾動時間,可以根據(jù)需要調(diào)整
}
}, [currentLyricIndex]);當 currentLyricIndex 發(fā)生變化時,useEffect 會被觸發(fā)。在該效果中,它模擬異步加載歌詞,然后通過 scrollRef.current.scrollToElement 方法滾動到指定的歌詞元素,滾動時間為500毫秒。這樣,每次歌詞發(fā)生變化時都會滾動到當前高亮的歌詞位置。
Scroll 組件的 scrollToElement 方法實現(xiàn):
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 組件內(nèi)部的 scrollToElement 方法的實現(xiàn)。首先,通過 document.querySelector(selector) 獲取到目標元素(具有指定類名的高亮歌詞元素)。然后,計算目標元素相對于滾動容器的偏移,最后使用 bScroll.scrollToElement 將目標元素滾動到可視區(qū)域,傳入的參數(shù)包括時間、水平和垂直的偏移。
以上就是React實現(xiàn)歌詞滾動效果(跟隨音樂播放時間滾動)的詳細內(nèi)容,更多關于React歌詞滾動的資料請關注腳本之家其它相關文章!
相關文章
React實現(xiàn)錨點跳轉組件附帶吸頂效果的示例代碼
這篇文章主要為大家詳細介紹了React如何實現(xiàn)移動端錨點跳轉組件附帶吸頂效果,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起了解一下2023-01-01
react-native組件中NavigatorIOS和ListView結合使用的方法
這篇文章主要給大家介紹了關于react-native組件中NavigatorIOS和ListView結合使用的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起看看吧。2017-09-09
深入理解React Native核心原理(React Native的橋接(Bridge)
這篇文章主要介紹了深入理解React Native核心原理(React Native的橋接(Bridge),本文重點給大家介紹React Native的基礎知識及實現(xiàn)原理,需要的朋友可以參考下2021-04-04

