feat: 增加背景层转场动画与暗色模式样式优化

* 在 `index.html` 中添加多种背景层转场动画效果,提升视觉体验。
* 更新 `App.vue` 中的图片切换逻辑,支持随机转场动画和慢慢放大效果。
* 增强暗色模式下的输入框和通知样式,确保视觉一致性与可读性。
This commit is contained in:
AdingApkgg
2025-11-20 03:48:56 +08:00
parent 49128d77c1
commit 9d1bc0ecf7
2 changed files with 222 additions and 4 deletions

View File

@@ -214,10 +214,140 @@
background-position: center;
background-repeat: no-repeat;
z-index: -2;
/* 平滑过渡,避免闪白屏 */
transition: background-image 1.2s cubic-bezier(0.4, 0, 0.2, 1);
/* 默认淡入淡出过渡 */
transition: opacity 1.2s cubic-bezier(0.4, 0, 0.2, 1);
/* 持续的慢慢放大动画 */
animation: slowZoom 10s ease-out forwards;
}
/* 持续慢慢放大动画 */
@keyframes slowZoom {
0% {
transform: scale(1);
}
100% {
transform: scale(1.1);
}
}
/* 转场动画类 */
#background-layer.transition-fade {
animation: fadeTransition 1.2s cubic-bezier(0.4, 0, 0.2, 1);
}
#background-layer.transition-zoom {
animation: zoomTransition 1.5s cubic-bezier(0.4, 0, 0.2, 1);
}
#background-layer.transition-slide-left {
animation: slideLeftTransition 1.2s cubic-bezier(0.4, 0, 0.2, 1);
}
#background-layer.transition-slide-right {
animation: slideRightTransition 1.2s cubic-bezier(0.4, 0, 0.2, 1);
}
#background-layer.transition-blur {
animation: blurTransition 1.5s cubic-bezier(0.4, 0, 0.2, 1);
}
#background-layer.transition-rotate {
animation: rotateTransition 1.5s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 淡入淡出动画 */
@keyframes fadeTransition {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* 缩放动画 */
@keyframes zoomTransition {
0% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0;
transform: scale(1.1);
}
100% {
opacity: 1;
transform: scale(1);
}
}
/* 左滑动画 */
@keyframes slideLeftTransition {
0% {
opacity: 1;
transform: translateX(0);
}
50% {
opacity: 0;
transform: translateX(-30px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
/* 右滑动画 */
@keyframes slideRightTransition {
0% {
opacity: 1;
transform: translateX(0);
}
50% {
opacity: 0;
transform: translateX(30px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
/* 模糊动画 */
@keyframes blurTransition {
0% {
opacity: 1;
filter: blur(0px);
}
50% {
opacity: 0.3;
filter: blur(10px);
}
100% {
opacity: 1;
filter: blur(0px);
}
}
/* 旋转动画 */
@keyframes rotateTransition {
0% {
opacity: 1;
transform: scale(1) rotate(0deg);
}
50% {
opacity: 0;
transform: scale(0.95) rotate(5deg);
}
100% {
opacity: 1;
transform: scale(1) rotate(0deg);
}
}
/* 默认背景纹理 - 白天模式 */
#background-layer::before {
content: "";
@@ -262,6 +392,44 @@
background: rgba(15, 23, 42, 0.4);
}
/* 暗色模式强制样式 */
.dark input[type="search"],
.dark input[type="url"],
.dark input[type="text"],
.dark textarea {
background-color: rgba(30, 41, 59, 0.95) !important;
color: rgb(226, 232, 240) !important;
border-color: rgba(71, 85, 105, 0.5) !important;
}
.dark input::placeholder,
.dark textarea::placeholder {
color: rgba(148, 163, 184, 0.7) !important;
}
.dark input:focus,
.dark textarea:focus {
border-color: rgb(139, 92, 246) !important;
}
/* 暗色模式下的卡片和容器 */
.dark .usage-notice {
background-color: rgba(30, 41, 59, 0.9) !important;
color: rgb(203, 213, 225) !important;
}
.dark .usage-notice h2 {
color: rgb(226, 232, 240) !important;
}
.dark .usage-notice strong {
color: rgb(226, 232, 240) !important;
}
.dark .usage-notice a {
color: rgb(147, 197, 253) !important;
}
/* 加载动画 */
@keyframes fadeIn {
from {

View File

@@ -40,8 +40,8 @@ let displayInterval: number | null = null;
const MAX_CACHE_SIZE = 10000; // 最大缓存 10000 张图片
const CLEANUP_BATCH_SIZE = 2000; // 每次清理 2000 张
const FETCH_INTERVAL = 3000; // 3秒获取一次
const DISPLAY_INTERVAL = 5000; // 5秒切换一次
const FETCH_INTERVAL = 5000; // 5秒获取一次
const DISPLAY_INTERVAL = 10000; // 10秒切换一次
const hasBackgroundImage = computed(
() => !!randomImageUrl.value
@@ -202,6 +202,48 @@ async function fetchAndCacheImage() {
}
}
// 转场动画类型
const transitionTypes = [
'transition-fade',
'transition-zoom',
'transition-slide-left',
'transition-slide-right',
'transition-blur',
'transition-rotate'
];
// 随机选择转场动画
function getRandomTransition(): string {
return transitionTypes[Math.floor(Math.random() * transitionTypes.length)];
}
// 应用转场动画
function applyTransition() {
const bgLayer = document.getElementById('background-layer');
if (!bgLayer) return;
const transitionClass = getRandomTransition();
bgLayer.classList.add(transitionClass);
// 动画结束后移除类
setTimeout(() => {
bgLayer.classList.remove(transitionClass);
}, 1500); // 最长动画时间
}
// 重启慢慢放大动画
function restartSlowZoom() {
const bgLayer = document.getElementById('background-layer');
if (!bgLayer) return;
// 移除动画,触发重排
bgLayer.style.animation = 'none';
// 强制重排
void bgLayer.offsetHeight;
// 重新应用动画
bgLayer.style.animation = 'slowZoom 10s ease-out forwards';
}
// 从洗牌队列中取出下一张图片(预加载后再切换)
async function displayNextImage() {
// 如果队列为空,重新洗牌
@@ -232,8 +274,16 @@ async function displayNextImage() {
// 预加载图片,确保加载完成后再切换
const preloadImg = new Image();
preloadImg.onload = () => {
// 应用随机转场动画
applyTransition();
// 图片加载完成,平滑切换
randomImageUrl.value = nextImageUrl;
// 重启慢慢放大动画
setTimeout(() => {
restartSlowZoom();
}, 100); // 等待图片切换完成
};
preloadImg.onerror = () => {
// 加载失败,尝试下一张