Compare commits
5 Commits
ab5f021bf8
...
612d673cbb
Author | SHA1 | Date | |
---|---|---|---|
612d673cbb | |||
1c5ee95086 | |||
6461c0adac | |||
672b2d80d5 | |||
92093ef80d |
|
@ -24,9 +24,9 @@ console.log('[Player] 检查 store 方法:', {
|
||||||
const currentTrack = computed(() => {
|
const currentTrack = computed(() => {
|
||||||
if (playQueueStore.playMode.shuffle && playQueueStore.shuffleList.length > 0) {
|
if (playQueueStore.playMode.shuffle && playQueueStore.shuffleList.length > 0) {
|
||||||
return playQueueStore.list[playQueueStore.shuffleList[playQueueStore.currentIndex]]
|
return playQueueStore.list[playQueueStore.shuffleList[playQueueStore.currentIndex]]
|
||||||
} else {
|
|
||||||
return playQueueStore.list[playQueueStore.currentIndex]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return playQueueStore.list[playQueueStore.currentIndex]
|
||||||
})
|
})
|
||||||
|
|
||||||
// 获取当前歌曲的音频源
|
// 获取当前歌曲的音频源
|
||||||
|
@ -395,7 +395,7 @@ setInterval(syncVolumeFromStorage, 100)
|
||||||
|
|
||||||
<RouterLink to="/playroom">
|
<RouterLink to="/playroom">
|
||||||
<div class="flex items-center w-32 h-9">
|
<div class="flex items-center w-32 h-9">
|
||||||
<span class="truncate">{{ getCurrentTrack()?.song.name }}</span>
|
<span class="truncate text-xs">{{ getCurrentTrack()?.song.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
|
|
||||||
|
|
|
@ -543,8 +543,39 @@ watch(() => props.lrcSrc, async (newSrc) => {
|
||||||
}
|
}
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
|
|
||||||
|
// 页面焦点处理函数变量声明
|
||||||
|
let handleVisibilityChange: (() => void) | null = null
|
||||||
|
|
||||||
|
// 页面焦点处理
|
||||||
|
function setupPageFocusHandlers() {
|
||||||
|
handleVisibilityChange = () => {
|
||||||
|
if (document.hidden) {
|
||||||
|
// 页面失去焦点时暂停动画
|
||||||
|
if (scrollTween) scrollTween.pause()
|
||||||
|
if (highlightTween) highlightTween.pause()
|
||||||
|
} else {
|
||||||
|
// 页面重新获得焦点时恢复并重新同步
|
||||||
|
if (scrollTween && scrollTween.paused()) scrollTween.resume()
|
||||||
|
if (highlightTween && highlightTween.paused()) highlightTween.resume()
|
||||||
|
|
||||||
|
// 重新同步歌词位置
|
||||||
|
nextTick(() => {
|
||||||
|
if (currentLineIndex.value >= 0 && autoScroll.value && !userScrolling.value) {
|
||||||
|
scrollToLine(currentLineIndex.value, false) // 不使用动画,直接定位
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('visibilitychange', handleVisibilityChange)
|
||||||
|
}
|
||||||
|
|
||||||
// 组件挂载时的入场动画
|
// 组件挂载时的入场动画
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 设置页面焦点处理
|
||||||
|
setupPageFocusHandlers()
|
||||||
|
|
||||||
// 控制面板入场动画
|
// 控制面板入场动画
|
||||||
if (controlPanel.value) {
|
if (controlPanel.value) {
|
||||||
gsap.fromTo(controlPanel.value,
|
gsap.fromTo(controlPanel.value,
|
||||||
|
@ -577,6 +608,11 @@ onUnmounted(() => {
|
||||||
if (scrollTween) scrollTween.kill()
|
if (scrollTween) scrollTween.kill()
|
||||||
if (highlightTween) highlightTween.kill()
|
if (highlightTween) highlightTween.kill()
|
||||||
if (userScrollTimeout) clearTimeout(userScrollTimeout)
|
if (userScrollTimeout) clearTimeout(userScrollTimeout)
|
||||||
|
|
||||||
|
// 清理页面焦点事件监听器
|
||||||
|
if (handleVisibilityChange) {
|
||||||
|
document.removeEventListener('visibilitychange', handleVisibilityChange)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 暴露方法给父组件
|
// 暴露方法给父组件
|
||||||
|
|
|
@ -83,6 +83,9 @@ onMounted(async () => {
|
||||||
thumbUpdate()
|
thumbUpdate()
|
||||||
|
|
||||||
setupEntranceAnimations()
|
setupEntranceAnimations()
|
||||||
|
|
||||||
|
// 添加页面焦点事件监听
|
||||||
|
setupPageFocusHandlers()
|
||||||
})
|
})
|
||||||
|
|
||||||
function timeFormatter(time: number) {
|
function timeFormatter(time: number) {
|
||||||
|
@ -90,7 +93,7 @@ function timeFormatter(time: number) {
|
||||||
if (timeInSeconds < 0) { return '-:--' }
|
if (timeInSeconds < 0) { return '-:--' }
|
||||||
const minutes = Math.floor(timeInSeconds / 60)
|
const minutes = Math.floor(timeInSeconds / 60)
|
||||||
const seconds = Math.floor(timeInSeconds % 60)
|
const seconds = Math.floor(timeInSeconds % 60)
|
||||||
if (isNaN(minutes) || isNaN(seconds)) { return '-:--' }
|
if (Number.isNaN(minutes) || Number.isNaN(seconds)) { return '-:--' }
|
||||||
return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`
|
return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +158,7 @@ function createVolumeDraggable() {
|
||||||
// 保存音量到localStorage
|
// 保存音量到localStorage
|
||||||
localStorage.setItem('audioVolume', newVolume.toString())
|
localStorage.setItem('audioVolume', newVolume.toString())
|
||||||
},
|
},
|
||||||
onDragEnd: function () {
|
onDragEnd: () => {
|
||||||
// 拖拽结束时也保存一次
|
// 拖拽结束时也保存一次
|
||||||
localStorage.setItem('audioVolume', volume.value.toString())
|
localStorage.setItem('audioVolume', volume.value.toString())
|
||||||
}
|
}
|
||||||
|
@ -419,9 +422,98 @@ watch(() => [preferences.presentLyrics, getCurrentTrack()?.song.lyricUrl], (newV
|
||||||
}
|
}
|
||||||
}, { immediate: true })
|
}, { immediate: true })
|
||||||
|
|
||||||
|
// 页面焦点处理函数变量声明
|
||||||
|
let handleVisibilityChange: (() => void) | null = null
|
||||||
|
let handlePageFocus: (() => void) | null = null
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
// 清理页面焦点事件监听器
|
||||||
|
if (handleVisibilityChange) {
|
||||||
|
document.removeEventListener('visibilitychange', handleVisibilityChange)
|
||||||
|
}
|
||||||
|
if (handlePageFocus) {
|
||||||
|
window.removeEventListener('focus', handlePageFocus)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 页面焦点处理函数
|
||||||
|
function setupPageFocusHandlers() {
|
||||||
|
handleVisibilityChange = () => {
|
||||||
|
if (document.hidden) {
|
||||||
|
// 页面失去焦点时,暂停所有动画
|
||||||
|
console.log('[Playroom] 页面失去焦点,暂停动画')
|
||||||
|
} else {
|
||||||
|
// 页面重新获得焦点时,重新同步状态
|
||||||
|
console.log('[Playroom] 页面重新获得焦点,同步状态')
|
||||||
|
nextTick(() => {
|
||||||
|
resyncLyricsState()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePageFocus = () => {
|
||||||
|
console.log('[Playroom] 窗口获得焦点,同步状态')
|
||||||
|
nextTick(() => {
|
||||||
|
resyncLyricsState()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听页面可见性变化
|
||||||
|
document.addEventListener('visibilitychange', handleVisibilityChange)
|
||||||
|
window.addEventListener('focus', handlePageFocus)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新同步歌词状态
|
||||||
|
function resyncLyricsState() {
|
||||||
|
const currentTrack = getCurrentTrack()
|
||||||
|
if (!currentTrack) { return }
|
||||||
|
|
||||||
|
console.log('[Playroom] 重新同步歌词状态')
|
||||||
|
|
||||||
|
// 重置动画状态
|
||||||
|
if (controllerRef.value) {
|
||||||
|
gsap.set(controllerRef.value, {
|
||||||
|
marginLeft: '0rem',
|
||||||
|
marginRight: '0rem'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lyricsSection.value) {
|
||||||
|
gsap.set(lyricsSection.value, {
|
||||||
|
opacity: 1,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
scale: 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查当前歌词显示状态应该是什么
|
||||||
|
const shouldShowLyrics = preferences.presentLyrics && currentTrack.song.lyricUrl ? true : false
|
||||||
|
|
||||||
|
if (shouldShowLyrics !== presentLyrics.value) {
|
||||||
|
console.log(`[Playroom] 歌词状态不一致,重新设置: ${presentLyrics.value} -> ${shouldShowLyrics}`)
|
||||||
|
|
||||||
|
// 直接设置状态,不触发动画
|
||||||
|
presentLyrics.value = shouldShowLyrics
|
||||||
|
|
||||||
|
// 如果需要显示歌词,重新执行显示动画
|
||||||
|
if (shouldShowLyrics) {
|
||||||
|
nextTick(() => {
|
||||||
|
const tl = gsap.timeline()
|
||||||
|
tl.from(controllerRef.value, {
|
||||||
|
marginRight: '-40rem',
|
||||||
|
duration: 0.4,
|
||||||
|
ease: "power2.out"
|
||||||
|
}).fromTo(lyricsSection.value,
|
||||||
|
{ opacity: 0, x: 50, scale: 0.95 },
|
||||||
|
{ opacity: 1, x: 0, scale: 1, duration: 0.5, ease: "power2.out" },
|
||||||
|
"-=0.2"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// New: Watch for track changes and animate
|
// New: Watch for track changes and animate
|
||||||
watch(() => playQueueStore.currentIndex, () => {
|
watch(() => playQueueStore.currentIndex, () => {
|
||||||
if (albumCover.value) {
|
if (albumCover.value) {
|
||||||
|
@ -513,9 +605,9 @@ watch(() => playQueueStore.currentIndex, () => {
|
||||||
|
|
||||||
<div class="w-full flex justify-between">
|
<div class="w-full flex justify-between">
|
||||||
<!-- ...existing time display code... -->
|
<!-- ...existing time display code... -->
|
||||||
<div class="font-medium flex-1 text-left relative">
|
<div class="font-medium flex-1 text-left text-xs relative">
|
||||||
<span
|
<span
|
||||||
class="text-black blur-lg absolute top-0">{{ timeFormatter(Math.floor(playQueueStore.currentTime)) }}</span>
|
class="text-black blur-lg absolute top-0 text-xs">{{ timeFormatter(Math.floor(playQueueStore.currentTime)) }}</span>
|
||||||
<span
|
<span
|
||||||
class="text-white/90 absolute top-0">{{ timeFormatter(Math.floor(playQueueStore.currentTime)) }}</span>
|
class="text-white/90 absolute top-0">{{ timeFormatter(Math.floor(playQueueStore.currentTime)) }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -526,7 +618,7 @@ watch(() => playQueueStore.currentIndex, () => {
|
||||||
<div class="flex flex-1">
|
<div class="flex flex-1">
|
||||||
<div class="flex-1" />
|
<div class="flex-1" />
|
||||||
<button
|
<button
|
||||||
class="text-white/90 font-medium text-right relative transition-colors duration-200 hover:text-white"
|
class="text-white/90 text-xs font-medium text-right relative transition-colors duration-200 hover:text-white"
|
||||||
@click="preferences.displayTimeLeft = !preferences.displayTimeLeft">
|
@click="preferences.displayTimeLeft = !preferences.displayTimeLeft">
|
||||||
<span
|
<span
|
||||||
class="text-black blur-lg absolute top-0">{{ `${preferences.displayTimeLeft ? '-' : ''}${timeFormatter(preferences.displayTimeLeft ? Math.floor(playQueueStore.duration) - Math.floor(playQueueStore.currentTime) : playQueueStore.duration)}` }}</span>
|
class="text-black blur-lg absolute top-0">{{ `${preferences.displayTimeLeft ? '-' : ''}${timeFormatter(preferences.displayTimeLeft ? Math.floor(playQueueStore.duration) - Math.floor(playQueueStore.currentTime) : playQueueStore.duration)}` }}</span>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user