feat: 全面优化加载动画视觉效果
- 重新设计骨架屏布局:卡片式设计,包含缩略图、头像、标题、文本和标签 - 添加光影流动效果(shimmer)增强视觉吸引力 - 优化旋转器设计:双环结构 + 弹跳点动画 - 改进文字提示:更友好的加载文案 - 增强动画效果:缩放 + 位移的入场动画 - 完善响应式设计:适配平板和手机屏幕 - 优化夜间模式:更深的背景和更柔和的阴影 - 提升整体视觉层次感和现代感
This commit is contained in:
@@ -3210,14 +3210,42 @@ function showLoadingOverlay() {
|
||||
el.id = 'article-loading-overlay';
|
||||
el.innerHTML = `
|
||||
<div class="overlay-content">
|
||||
<div class="overlay-thumb skeleton"></div>
|
||||
<div class="overlay-card">
|
||||
<div class="overlay-thumb skeleton">
|
||||
<div class="overlay-thumb-shimmer"></div>
|
||||
</div>
|
||||
<div class="overlay-body">
|
||||
<div class="overlay-meta">
|
||||
<div class="overlay-avatar skeleton"></div>
|
||||
<div class="overlay-meta-text">
|
||||
<div class="overlay-meta-line skeleton" style="width: 120px"></div>
|
||||
<div class="overlay-meta-line skeleton" style="width: 80px"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overlay-title skeleton"></div>
|
||||
<div class="overlay-row skeleton" style="width: 90%"></div>
|
||||
<div class="overlay-row skeleton" style="width: 75%"></div>
|
||||
<div class="overlay-row skeleton" style="width: 85%"></div>
|
||||
<div class="center-spinner">
|
||||
<div class="loading-spinner"></div>
|
||||
<span style="color: var(--color-font-sub); font-size: 14px;">加载中...</span>
|
||||
<div class="overlay-text">
|
||||
<div class="overlay-row skeleton" style="width: 95%"></div>
|
||||
<div class="overlay-row skeleton" style="width: 88%"></div>
|
||||
<div class="overlay-row skeleton" style="width: 92%"></div>
|
||||
<div class="overlay-row skeleton" style="width: 78%"></div>
|
||||
</div>
|
||||
<div class="overlay-tags">
|
||||
<div class="overlay-tag skeleton"></div>
|
||||
<div class="overlay-tag skeleton"></div>
|
||||
<div class="overlay-tag skeleton"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overlay-spinner">
|
||||
<div class="spinner-ring">
|
||||
<div class="spinner-ring-inner"></div>
|
||||
</div>
|
||||
<div class="spinner-text">正在加载精彩内容</div>
|
||||
<div class="spinner-dots">
|
||||
<span class="dot"></span>
|
||||
<span class="dot"></span>
|
||||
<span class="dot"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
289
style.css
289
style.css
@@ -16971,10 +16971,10 @@ article.post.card .post-thumbnail {
|
||||
#rightbar .card:nth-child(3) { animation-delay: 200ms; }
|
||||
|
||||
/* 5. 页面过渡和浮动按钮动<E992AE>?*/
|
||||
#primary.pjax-loading { opacity: 0.6; transform: translateY(10px); pointer-events: none; }
|
||||
#primary { transition: opacity var(--animation-normal) var(--ease-standard), transform var(--animation-normal) var(--ease-standard); }
|
||||
@keyframes modernContentFadeIn { from { opacity: 0; transform: translateY(15px); } to { opacity: 1; transform: translateY(0); } }
|
||||
article.post.post-full:not(.no-animation) { animation: modernContentFadeIn var(--animation-slow) var(--ease-emphasized-decelerate); }
|
||||
#primary.pjax-loading { opacity: 0.6; transform: translate3d(0, 10px, 0); pointer-events: none; }
|
||||
#primary { transition: opacity var(--animation-normal) var(--ease-standard), transform var(--animation-normal) var(--ease-standard); will-change: opacity, transform; }
|
||||
@keyframes modernContentFadeIn { from { opacity: 0; transform: translate3d(0, 16px, 0); } to { opacity: 1; transform: translate3d(0, 0, 0); } }
|
||||
article.post.post-full:not(.no-animation) { animation: modernContentFadeIn var(--animation-slow) var(--ease-emphasized-decelerate) both; will-change: opacity, transform; }
|
||||
article.post.post-full { transform-origin: center top; }
|
||||
|
||||
#float_action_buttons { transition: transform var(--animation-normal) var(--ease-back), opacity var(--animation-normal) var(--ease-standard); }
|
||||
@@ -17047,10 +17047,291 @@ article img.loaded, .post-thumbnail img.loaded, article img:not([loading="lazy"]
|
||||
/* 11. 骨架屏和加载动画 */
|
||||
@keyframes modernSkeletonPulse { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } }
|
||||
.skeleton { background: linear-gradient(90deg, var(--color-border-on-foreground) 25%, var(--color-border-on-foreground-deeper) 50%, var(--color-border-on-foreground) 75%); background-size: 200% 100%; animation: modernSkeletonPulse 1.5s ease-in-out infinite; border-radius: var(--card-radius); }
|
||||
/* ---------- 加载动画 ---------- */
|
||||
@keyframes modernSpinnerRotate { to { transform: rotate(360deg); } }
|
||||
.loading-spinner { width: 24px; height: 24px; border: 2px solid var(--color-border); border-top-color: var(--themecolor); border-radius: 50%; animation: modernSpinnerRotate 0.8s linear infinite; }
|
||||
#page-loading-bar { position: fixed; top: 0; left: 0; height: 3px; background: var(--themecolor-gradient); z-index: 9999; transition: width var(--animation-fast) var(--ease-out-expo); box-shadow: 0 0 10px rgba(var(--themecolor-rgbstr), 0.5); }
|
||||
|
||||
/* 加载遮罩层 */
|
||||
#article-loading-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 9998;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transition: opacity var(--animation-normal) var(--ease-standard), visibility 0s linear var(--animation-normal);
|
||||
-webkit-backdrop-filter: blur(var(--card-blur, 20px)) saturate(var(--card-saturate, 180%));
|
||||
backdrop-filter: blur(var(--card-blur, 20px)) saturate(var(--card-saturate, 180%));
|
||||
}
|
||||
html.darkmode #article-loading-overlay {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
#article-loading-overlay.is-visible {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
transition: opacity var(--animation-normal) var(--ease-standard), visibility 0s;
|
||||
}
|
||||
#article-loading-overlay.is-hiding {
|
||||
opacity: 0;
|
||||
visibility: visible;
|
||||
pointer-events: none;
|
||||
transition: opacity var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
|
||||
/* 加载内容容器 */
|
||||
#article-loading-overlay .overlay-content {
|
||||
width: min(720px, 90vw);
|
||||
opacity: 0;
|
||||
transform: translate3d(0, 12px, 0) scale(0.98);
|
||||
transition: opacity var(--animation-normal) var(--ease-standard), transform var(--animation-normal) var(--ease-emphasized-decelerate);
|
||||
}
|
||||
#article-loading-overlay.is-visible .overlay-content {
|
||||
opacity: 1;
|
||||
transform: translate3d(0, 0, 0) scale(1);
|
||||
}
|
||||
|
||||
/* 卡片容器 */
|
||||
#article-loading-overlay .overlay-card {
|
||||
background: var(--color-foreground);
|
||||
border-radius: var(--card-radius);
|
||||
overflow: hidden;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
html.darkmode #article-loading-overlay .overlay-card {
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* 缩略图 */
|
||||
#article-loading-overlay .overlay-thumb {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 240px;
|
||||
overflow: hidden;
|
||||
}
|
||||
#article-loading-overlay .overlay-thumb-shimmer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent);
|
||||
animation: shimmer 2s infinite;
|
||||
}
|
||||
html.darkmode #article-loading-overlay .overlay-thumb-shimmer {
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
|
||||
}
|
||||
@keyframes shimmer {
|
||||
to { left: 100%; }
|
||||
}
|
||||
|
||||
/* 卡片主体 */
|
||||
#article-loading-overlay .overlay-body {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
/* 元信息区域 */
|
||||
#article-loading-overlay .overlay-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
#article-loading-overlay .overlay-avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
#article-loading-overlay .overlay-meta-text {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
#article-loading-overlay .overlay-meta-line {
|
||||
height: 12px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
/* 标题 */
|
||||
#article-loading-overlay .overlay-title {
|
||||
height: 28px;
|
||||
margin-bottom: 16px;
|
||||
border-radius: 14px;
|
||||
width: 85%;
|
||||
}
|
||||
|
||||
/* 文本行 */
|
||||
#article-loading-overlay .overlay-text {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
#article-loading-overlay .overlay-row {
|
||||
height: 14px;
|
||||
margin: 8px 0;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
/* 标签 */
|
||||
#article-loading-overlay .overlay-tags {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
#article-loading-overlay .overlay-tag {
|
||||
width: 60px;
|
||||
height: 24px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
/* 骨架屏动画 */
|
||||
#article-loading-overlay .skeleton {
|
||||
background: linear-gradient(90deg, var(--color-border-on-foreground) 25%, var(--color-border-on-foreground-deeper) 50%, var(--color-border-on-foreground) 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: modernSkeletonPulse 1.8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* 加载旋转器 */
|
||||
#article-loading-overlay .overlay-spinner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 20px;
|
||||
}
|
||||
#article-loading-overlay .spinner-ring {
|
||||
position: relative;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
}
|
||||
#article-loading-overlay .spinner-ring::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 50%;
|
||||
border: 3px solid var(--color-border);
|
||||
opacity: 0.2;
|
||||
}
|
||||
#article-loading-overlay .spinner-ring-inner {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 50%;
|
||||
border: 3px solid transparent;
|
||||
border-top-color: var(--themecolor);
|
||||
border-right-color: var(--themecolor);
|
||||
animation: spinnerRotate 1s cubic-bezier(0.68, -0.55, 0.265, 1.55) infinite;
|
||||
}
|
||||
@keyframes spinnerRotate {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 加载文字 */
|
||||
#article-loading-overlay .spinner-text {
|
||||
color: var(--color-font);
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.3px;
|
||||
}
|
||||
|
||||
/* 加载点动画 */
|
||||
#article-loading-overlay .spinner-dots {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
}
|
||||
#article-loading-overlay .spinner-dots .dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--themecolor);
|
||||
animation: dotBounce 1.4s infinite ease-in-out both;
|
||||
}
|
||||
#article-loading-overlay .spinner-dots .dot:nth-child(1) {
|
||||
animation-delay: -0.32s;
|
||||
}
|
||||
#article-loading-overlay .spinner-dots .dot:nth-child(2) {
|
||||
animation-delay: -0.16s;
|
||||
}
|
||||
@keyframes dotBounce {
|
||||
0%, 80%, 100% {
|
||||
transform: scale(0.6);
|
||||
opacity: 0.5;
|
||||
}
|
||||
40% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式适配 */
|
||||
@media (max-width: 768px) {
|
||||
#article-loading-overlay .overlay-thumb {
|
||||
height: 180px;
|
||||
}
|
||||
#article-loading-overlay .overlay-body {
|
||||
padding: 20px;
|
||||
}
|
||||
#article-loading-overlay .overlay-title {
|
||||
height: 24px;
|
||||
width: 90%;
|
||||
}
|
||||
#article-loading-overlay .spinner-ring {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
#article-loading-overlay .spinner-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
#article-loading-overlay .overlay-content {
|
||||
width: 95vw;
|
||||
}
|
||||
#article-loading-overlay .overlay-thumb {
|
||||
height: 160px;
|
||||
}
|
||||
#article-loading-overlay .overlay-body {
|
||||
padding: 16px;
|
||||
}
|
||||
#article-loading-overlay .overlay-meta {
|
||||
gap: 10px;
|
||||
}
|
||||
#article-loading-overlay .overlay-avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 页面过渡内容容器 */
|
||||
.page-transition-content {
|
||||
will-change: opacity, transform;
|
||||
transition: opacity var(--animation-normal) var(--ease-standard), transform var(--animation-normal) var(--ease-emphasized-decelerate);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
html.page-transition-enter .page-transition-content {
|
||||
opacity: 0;
|
||||
transform: translate3d(0, 8px, 0);
|
||||
}
|
||||
html.page-transition-enter.page-transition-active .page-transition-content {
|
||||
opacity: 1;
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.page-transition-content,
|
||||
#article-loading-overlay,
|
||||
#article-loading-overlay .overlay-content {
|
||||
transition: none !important;
|
||||
animation: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 12. 模态框和下拉菜单动<E58D95>?*/
|
||||
.modal { transition: opacity var(--animation-normal) var(--ease-standard); }
|
||||
.modal.show { opacity: 1; }
|
||||
|
||||
Reference in New Issue
Block a user