mirror of
https://github.com/handsomezhuzhu/handsomezhuzhu.github.io.git
synced 2026-02-20 11:50:14 +00:00
多背景轮训+淡入淡出
This commit is contained in:
@@ -66,6 +66,15 @@ export default defineConfig({
|
|||||||
link: 'https://github.com/handsomezhuzhu'
|
link: 'https://github.com/handsomezhuzhu'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
vite: {
|
||||||
|
css: {
|
||||||
|
preprocessorOptions: {
|
||||||
|
scss: {
|
||||||
|
api: 'modern-compiler'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
152
docs/.vitepress/theme/components/BackgroundSlider.vue
Normal file
152
docs/.vitepress/theme/components/BackgroundSlider.vue
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
|
||||||
|
import { useData, useRoute } from 'vitepress'
|
||||||
|
|
||||||
|
const { isDark, frontmatter } = useData()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
// 图片配置
|
||||||
|
const darkImages = [
|
||||||
|
// '/bg.webp',
|
||||||
|
'/bg2.webp',
|
||||||
|
'/bg3.jpeg'
|
||||||
|
]
|
||||||
|
|
||||||
|
const lightImages = [
|
||||||
|
'/bgw.webp',
|
||||||
|
'/bgw2.jpeg'
|
||||||
|
]
|
||||||
|
|
||||||
|
const currentImages = computed(() => isDark.value ? darkImages : lightImages)
|
||||||
|
const currentIndex = ref(0)
|
||||||
|
const nextIndex = ref(1)
|
||||||
|
|
||||||
|
// 控制显示的图片
|
||||||
|
const activeImage = computed(() => currentImages.value[currentIndex.value])
|
||||||
|
// const nextImage = computed(() => currentImages.value[nextIndex.value])
|
||||||
|
|
||||||
|
// 简单的淡入淡出逻辑:
|
||||||
|
// 我们使用 <transition> 包裹一个 div 作为背景
|
||||||
|
// 也可以使用两个 div 叠加,一个 fadeOut 一个 fadeIn
|
||||||
|
// 这里使用 Vue Transition Group 或 Key 切换
|
||||||
|
|
||||||
|
// --- 配置区域 ---
|
||||||
|
const INTERVAL_TIME = 15000 // 轮换间隔:5000ms = 5秒
|
||||||
|
// ----------------
|
||||||
|
|
||||||
|
let timer: any = null
|
||||||
|
|
||||||
|
const startRotation = () => {
|
||||||
|
stopRotation()
|
||||||
|
timer = setInterval(() => {
|
||||||
|
currentIndex.value = (currentIndex.value + 1) % currentImages.value.length
|
||||||
|
}, INTERVAL_TIME)
|
||||||
|
}
|
||||||
|
|
||||||
|
const stopRotation = () => {
|
||||||
|
if (timer) clearInterval(timer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听模式变化,重置索引,防止索引越界
|
||||||
|
watch(isDark, () => {
|
||||||
|
// 切换模式时,重置 index,确保展示对应模式的第一张图
|
||||||
|
currentIndex.value = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const preloadImages = (images: string[]) => {
|
||||||
|
images.forEach(src => {
|
||||||
|
const img = new Image()
|
||||||
|
img.src = src
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 预加载所有图片
|
||||||
|
preloadImages([...darkImages, ...lightImages])
|
||||||
|
startRotation()
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
stopRotation()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 只在首页显示
|
||||||
|
const show = computed(() => frontmatter.value.layout === 'home')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ClientOnly>
|
||||||
|
<div v-show="show" class="bg-slider-container">
|
||||||
|
<transition name="bg-fade">
|
||||||
|
<div
|
||||||
|
:key="activeImage"
|
||||||
|
class="bg-slide-item"
|
||||||
|
:style="{ backgroundImage: `url(${activeImage})` }"
|
||||||
|
></div>
|
||||||
|
</transition>
|
||||||
|
</div>
|
||||||
|
</ClientOnly>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.bg-slider-container {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
z-index: -10; /* 放在最底层 */
|
||||||
|
pointer-events: none;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-slide-item {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
/* 保持与原主题一致的暗度调整,如果需要的话。
|
||||||
|
原主题是在 .VPHome 上盖了一层渐变,所以这里只需要纯图片。
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vue Transition 动画 */
|
||||||
|
.bg-fade-enter-active {
|
||||||
|
transition: opacity 1.5s ease;
|
||||||
|
z-index: 2; /* 新图片在最上面 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-fade-leave-active {
|
||||||
|
/* 旧图片保持显示,直到被新图片覆盖 */
|
||||||
|
transition: opacity 1.5s ease;
|
||||||
|
z-index: 1; /* 旧图片在中间 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-fade-enter-from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-fade-enter-to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-fade-leave-from {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-fade-leave-to {
|
||||||
|
/* 旧图片保持不透明(或者可以设为 0 但在 enter 之后)
|
||||||
|
这里设为 0,因为如果 enter 是 opacity 1,它覆盖在上面。
|
||||||
|
如果设为 1,可能会在 transition 结束后突然消失,如果新图片有透明度的话。
|
||||||
|
但我们的图片是背景图,理论上是不透明的。
|
||||||
|
为了保险,我们让旧图片淡出,但新图片覆盖在上面。
|
||||||
|
如果新图片淡入 (0->1) 同时旧图片淡出 (1->0),中间时刻 (0.5+0.5) 可能会透。
|
||||||
|
所以策略是:旧图片 保持 1 (或极慢淡出),新图片 淡入。
|
||||||
|
*/
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
import BlogTheme from '@sugarat/theme'
|
import BlogTheme from '@sugarat/theme'
|
||||||
|
import { h } from 'vue'
|
||||||
|
import BackgroundSlider from './components/BackgroundSlider.vue'
|
||||||
import { initCursorRainForVitePress } from '../cursor-rain/index.esm.js'
|
import { initCursorRainForVitePress } from '../cursor-rain/index.esm.js'
|
||||||
import { gsap } from 'gsap'
|
import { gsap } from 'gsap'
|
||||||
import { getOptimalConfig, rainPresets } from './cursor-rain-config'
|
import { getOptimalConfig, rainPresets } from './cursor-rain-config'
|
||||||
@@ -12,6 +14,11 @@ import './cursor-rain-styles.css'
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
...BlogTheme,
|
...BlogTheme,
|
||||||
|
Layout: () => {
|
||||||
|
return h(BlogTheme.Layout, null, {
|
||||||
|
'layout-bottom': () => h(BackgroundSlider)
|
||||||
|
})
|
||||||
|
},
|
||||||
enhanceApp({ app, router, siteData }) {
|
enhanceApp({ app, router, siteData }) {
|
||||||
// 调用原主题的 enhanceApp
|
// 调用原主题的 enhanceApp
|
||||||
if (BlogTheme.enhanceApp) {
|
if (BlogTheme.enhanceApp) {
|
||||||
|
|||||||
@@ -6,16 +6,17 @@
|
|||||||
|
|
||||||
// 自定义首页背景图
|
// 自定义首页背景图
|
||||||
&::before {
|
&::before {
|
||||||
background-size: cover;
|
display: none;
|
||||||
// 默认是暗色模式的背景
|
// background-size: cover;
|
||||||
background-image: url(/bg.webp);
|
// // 默认是暗色模式的背景
|
||||||
|
// background-image: url(/bg.webp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 亮色模式下切换背景
|
// 亮色模式下切换背景
|
||||||
html:not(.dark) .VPHome::before {
|
// html:not(.dark) .VPHome::before {
|
||||||
background-image: url(/bgw.webp);
|
// background-image: url(/bgw.webp);
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
BIN
docs/public/bg2.webp
Normal file
BIN
docs/public/bg2.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 277 KiB |
BIN
docs/public/bg3.jpeg
Normal file
BIN
docs/public/bg3.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 133 KiB |
BIN
docs/public/bgw2.jpeg
Normal file
BIN
docs/public/bgw2.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
Reference in New Issue
Block a user