mirror of
https://git.fightbot.fun/hxuanyu/BingPaper.git
synced 2026-02-15 13:09:33 +08:00
大图查看页面优化:新增图片切换淡入淡出动画,并通过预加载提升切换速度
This commit is contained in:
@@ -1,18 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="fixed inset-0 bg-black z-50 overflow-hidden">
|
<div class="fixed inset-0 bg-black z-50 overflow-hidden">
|
||||||
<!-- 加载状态 -->
|
<!-- 加载状态(动画过渡中不显示) -->
|
||||||
<div v-if="loading" class="absolute inset-0 flex items-center justify-center">
|
<div v-if="loading && !imageTransitioning" class="absolute inset-0 flex items-center justify-center">
|
||||||
<div class="w-16 h-16 border-4 border-white/20 border-t-white rounded-full animate-spin"></div>
|
<div class="w-16 h-16 border-4 border-white/20 border-t-white rounded-full animate-spin"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 主要内容 -->
|
<!-- 主要内容 -->
|
||||||
<div v-else-if="image" class="relative h-full w-full">
|
<div v-else-if="image || imageTransitioning" class="relative h-full w-full">
|
||||||
<!-- 全屏图片 -->
|
<!-- 全屏图片 -->
|
||||||
<div class="absolute inset-0 flex items-center justify-center">
|
<div class="absolute inset-0 flex items-center justify-center">
|
||||||
<img
|
<img
|
||||||
:src="getFullImageUrl()"
|
:src="getFullImageUrl()"
|
||||||
:alt="image.title || 'Bing Image'"
|
:alt="image.title || 'Bing Image'"
|
||||||
class="max-w-full max-h-full object-contain"
|
class="max-w-full max-h-full object-contain transition-opacity duration-500 ease-in-out"
|
||||||
|
:style="{ opacity: imageOpacity }"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -204,6 +205,8 @@ const currentDate = ref(route.params.date as string)
|
|||||||
const showInfo = ref(true)
|
const showInfo = ref(true)
|
||||||
const showCalendar = ref(getInitialCalendarState())
|
const showCalendar = ref(getInitialCalendarState())
|
||||||
const navigating = ref(false)
|
const navigating = ref(false)
|
||||||
|
const imageOpacity = ref(1)
|
||||||
|
const imageTransitioning = ref(false)
|
||||||
|
|
||||||
// 前后日期可用性
|
// 前后日期可用性
|
||||||
const hasPreviousDay = ref(true)
|
const hasPreviousDay = ref(true)
|
||||||
@@ -415,6 +418,63 @@ const getFullImageUrl = () => {
|
|||||||
return bingPaperApi.getImageUrlByDate(currentDate.value, 'UHD', 'jpg')
|
return bingPaperApi.getImageUrlByDate(currentDate.value, 'UHD', 'jpg')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预加载图片
|
||||||
|
const preloadImage = (url: string): Promise<void> => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const img = new Image()
|
||||||
|
img.onload = () => resolve()
|
||||||
|
img.onerror = () => reject(new Error('Failed to load image'))
|
||||||
|
img.src = url
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预加载图片和数据
|
||||||
|
const preloadImageAndData = async (date: string): Promise<void> => {
|
||||||
|
try {
|
||||||
|
// 并行预加载图片和数据
|
||||||
|
const imageUrl = bingPaperApi.getImageUrlByDate(date, 'UHD', 'jpg')
|
||||||
|
await Promise.all([
|
||||||
|
preloadImage(imageUrl),
|
||||||
|
bingPaperApi.getImageMetaByDate(date)
|
||||||
|
])
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Failed to preload image or data:', error)
|
||||||
|
// 即使预加载失败也继续
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换日期并带动画
|
||||||
|
const switchToDate = async (newDate: string) => {
|
||||||
|
if (imageTransitioning.value) return
|
||||||
|
|
||||||
|
imageTransitioning.value = true
|
||||||
|
|
||||||
|
// 1. 淡出当前图片的同时预加载新图片和数据
|
||||||
|
imageOpacity.value = 0
|
||||||
|
const preloadPromise = preloadImageAndData(newDate)
|
||||||
|
|
||||||
|
// 2. 等待淡出动画完成(500ms)
|
||||||
|
await Promise.all([
|
||||||
|
new Promise(resolve => setTimeout(resolve, 500)),
|
||||||
|
preloadPromise
|
||||||
|
])
|
||||||
|
|
||||||
|
// 3. 更新日期(此时图片和数据已经预加载完成)
|
||||||
|
currentDate.value = newDate
|
||||||
|
router.replace(`/image/${newDate}`)
|
||||||
|
|
||||||
|
// 4. 等待一个微任务,确保 DOM 更新
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 50))
|
||||||
|
|
||||||
|
// 5. 淡入新图片
|
||||||
|
imageOpacity.value = 1
|
||||||
|
|
||||||
|
// 6. 等待淡入完成
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 500))
|
||||||
|
|
||||||
|
imageTransitioning.value = false
|
||||||
|
}
|
||||||
|
|
||||||
// copyrightlink 现在是完整的 URL,无需额外处理
|
// copyrightlink 现在是完整的 URL,无需额外处理
|
||||||
|
|
||||||
// 返回首页
|
// 返回首页
|
||||||
@@ -423,37 +483,31 @@ const goBack = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 前一天
|
// 前一天
|
||||||
const previousDay = () => {
|
const previousDay = async () => {
|
||||||
if (navigating.value || !hasPreviousDay.value) return
|
if (navigating.value || !hasPreviousDay.value || imageTransitioning.value) return
|
||||||
|
|
||||||
navigating.value = true
|
navigating.value = true
|
||||||
const date = new Date(currentDate.value)
|
const date = new Date(currentDate.value)
|
||||||
date.setDate(date.getDate() - 1)
|
date.setDate(date.getDate() - 1)
|
||||||
const newDate = date.toISOString().split('T')[0]
|
const newDate = date.toISOString().split('T')[0]
|
||||||
|
|
||||||
currentDate.value = newDate
|
await switchToDate(newDate)
|
||||||
router.replace(`/image/${newDate}`)
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
navigating.value = false
|
navigating.value = false
|
||||||
}, 500)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 后一天
|
// 后一天
|
||||||
const nextDay = () => {
|
const nextDay = async () => {
|
||||||
if (navigating.value || !hasNextDay.value) return
|
if (navigating.value || !hasNextDay.value || imageTransitioning.value) return
|
||||||
|
|
||||||
navigating.value = true
|
navigating.value = true
|
||||||
const date = new Date(currentDate.value)
|
const date = new Date(currentDate.value)
|
||||||
date.setDate(date.getDate() + 1)
|
date.setDate(date.getDate() + 1)
|
||||||
const newDate = date.toISOString().split('T')[0]
|
const newDate = date.toISOString().split('T')[0]
|
||||||
|
|
||||||
currentDate.value = newDate
|
await switchToDate(newDate)
|
||||||
router.replace(`/image/${newDate}`)
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
navigating.value = false
|
navigating.value = false
|
||||||
}, 500)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换日历状态(watch会自动保存)
|
// 切换日历状态(watch会自动保存)
|
||||||
|
|||||||
Reference in New Issue
Block a user