refactor: 合并现代化动画增强到主文件
- 将 modern-enhancements.css 内容合并到 style.css 末尾 - 将 modern-enhancements.js 内容合并到 argontheme.js 末尾 - 删除独立的 modern-enhancements.css 和 modern-enhancements.js 文件 - 移除 header.php 中对独立文件的引用
This commit is contained in:
144
argontheme.js
144
argontheme.js
@@ -3603,3 +3603,147 @@ setInterval(function(){
|
||||
!function(){
|
||||
void 0;
|
||||
}();
|
||||
|
||||
/* ========== Modern UI Enhancements - 现代化交互动画增强 ========== */
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// 1. 触摸涟漪效果
|
||||
function createRipple(event, element) {
|
||||
if (window.matchMedia('(hover: hover)').matches) return;
|
||||
var rect = element.getBoundingClientRect();
|
||||
var ripple = document.createElement('span');
|
||||
var size = Math.max(rect.width, rect.height);
|
||||
ripple.style.width = ripple.style.height = size + 'px';
|
||||
ripple.style.left = ((event.clientX || event.touches[0].clientX) - rect.left - size / 2) + 'px';
|
||||
ripple.style.top = ((event.clientY || event.touches[0].clientY) - rect.top - size / 2) + 'px';
|
||||
ripple.className = 'touch-ripple';
|
||||
var oldRipple = element.querySelector('.touch-ripple');
|
||||
if (oldRipple) oldRipple.remove();
|
||||
element.style.position = 'relative';
|
||||
element.style.overflow = 'hidden';
|
||||
element.appendChild(ripple);
|
||||
setTimeout(function() { ripple.remove(); }, 600);
|
||||
}
|
||||
|
||||
function initRippleEffect() {
|
||||
var rippleElements = document.querySelectorAll('.btn, .card, .nav-link, .dropdown-item, .page-link, .leftbar-mobile-menu-item > a, .leftbar-mobile-action, .fabtn, .comment-reply, .tag, .badge');
|
||||
rippleElements.forEach(function(el) {
|
||||
if (el.dataset.rippleInit) return;
|
||||
el.dataset.rippleInit = 'true';
|
||||
el.addEventListener('touchstart', function(e) { createRipple(e, this); }, { passive: true });
|
||||
});
|
||||
}
|
||||
|
||||
// 2. 图片加载动画
|
||||
function initImageLoadAnimation() {
|
||||
var images = document.querySelectorAll('article img[loading="lazy"], .post-thumbnail img');
|
||||
images.forEach(function(img) {
|
||||
if (img.dataset.loadAnimInit) return;
|
||||
img.dataset.loadAnimInit = 'true';
|
||||
if (img.complete) { img.classList.add('loaded'); }
|
||||
else { img.addEventListener('load', function() { this.classList.add('loaded'); }); }
|
||||
});
|
||||
}
|
||||
|
||||
// 3. 滚动入场动画
|
||||
function initScrollAnimations() {
|
||||
if (!('IntersectionObserver' in window)) return;
|
||||
var animatedElements = document.querySelectorAll('.article-list article.post, .comment-item, .timeline-item, .friend-link-item, #leftbar .card, #rightbar .card');
|
||||
var observer = new IntersectionObserver(function(entries) {
|
||||
entries.forEach(function(entry) {
|
||||
if (entry.isIntersecting) { entry.target.classList.add('animate-in'); observer.unobserve(entry.target); }
|
||||
});
|
||||
}, { threshold: 0.1, rootMargin: '0px 0px -50px 0px' });
|
||||
animatedElements.forEach(function(el) { if (!el.classList.contains('animate-in')) observer.observe(el); });
|
||||
}
|
||||
|
||||
// 4. 平滑滚动
|
||||
function initSmoothScroll() {
|
||||
document.querySelectorAll('a[href^="#"]').forEach(function(anchor) {
|
||||
if (anchor.dataset.smoothScrollInit) return;
|
||||
anchor.dataset.smoothScrollInit = 'true';
|
||||
anchor.addEventListener('click', function(e) {
|
||||
var targetId = this.getAttribute('href');
|
||||
if (targetId === '#') return;
|
||||
var target = document.querySelector(targetId);
|
||||
if (target) { e.preventDefault(); target.scrollIntoView({ behavior: 'smooth', block: 'start' }); }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 5. 页面加载进度条
|
||||
function initLoadingBar() {
|
||||
if (document.getElementById('page-loading-bar')) return;
|
||||
var bar = document.createElement('div');
|
||||
bar.id = 'page-loading-bar';
|
||||
bar.style.width = '0%';
|
||||
document.body.appendChild(bar);
|
||||
var progress = 0;
|
||||
var interval = setInterval(function() {
|
||||
progress += Math.random() * 10;
|
||||
if (progress >= 90) { clearInterval(interval); progress = 90; }
|
||||
bar.style.width = progress + '%';
|
||||
}, 100);
|
||||
window.addEventListener('load', function() {
|
||||
clearInterval(interval);
|
||||
bar.style.width = '100%';
|
||||
setTimeout(function() { bar.style.opacity = '0'; setTimeout(function() { bar.remove(); }, 300); }, 200);
|
||||
});
|
||||
}
|
||||
|
||||
// 6. PJAX 加载动画
|
||||
function initPjaxAnimations() {
|
||||
if (typeof jQuery === 'undefined') return;
|
||||
jQuery(document).on('pjax:start', function() {
|
||||
jQuery('#primary').addClass('pjax-loading');
|
||||
var bar = document.getElementById('page-loading-bar');
|
||||
if (!bar) { bar = document.createElement('div'); bar.id = 'page-loading-bar'; document.body.appendChild(bar); }
|
||||
bar.style.opacity = '1'; bar.style.width = '30%';
|
||||
setTimeout(function() { bar.style.width = '60%'; }, 200);
|
||||
});
|
||||
jQuery(document).on('pjax:end', function() {
|
||||
jQuery('#primary').removeClass('pjax-loading');
|
||||
var bar = document.getElementById('page-loading-bar');
|
||||
if (bar) { bar.style.width = '100%'; setTimeout(function() { bar.style.opacity = '0'; setTimeout(function() { bar.remove(); }, 300); }, 200); }
|
||||
setTimeout(function() { initRippleEffect(); initImageLoadAnimation(); initScrollAnimations(); initSmoothScroll(); }, 100);
|
||||
});
|
||||
}
|
||||
|
||||
// 7. 主题切换动画
|
||||
function initThemeTransition() {
|
||||
var observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.attributeName === 'class') {
|
||||
var html = document.documentElement;
|
||||
html.classList.add('theme-transitioning');
|
||||
setTimeout(function() { html.classList.remove('theme-transitioning'); }, 300);
|
||||
}
|
||||
});
|
||||
});
|
||||
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class'] });
|
||||
}
|
||||
|
||||
// 8. 减少动画偏好检测
|
||||
function checkReducedMotion() {
|
||||
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||
document.documentElement.classList.add('reduced-motion');
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
function init() {
|
||||
checkReducedMotion();
|
||||
initRippleEffect();
|
||||
initImageLoadAnimation();
|
||||
initScrollAnimations();
|
||||
initSmoothScroll();
|
||||
initPjaxAnimations();
|
||||
initThemeTransition();
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); }
|
||||
else { init(); }
|
||||
if (document.readyState !== 'complete') { initLoadingBar(); }
|
||||
})();
|
||||
/* ========== End of Modern UI Enhancements ========== */
|
||||
@@ -272,9 +272,6 @@
|
||||
wp_enqueue_style("argon_css_merged", $GLOBALS['assets_path'] . "/assets/argon_css_merged.css", array(), $assets_version, 'all');
|
||||
wp_enqueue_style("style", $GLOBALS['assets_path'] . "/style.css", array('argon_css_merged'), $assets_version, 'all');
|
||||
|
||||
// 现代化布局和动画增强
|
||||
wp_enqueue_style("modern_enhancements", $GLOBALS['assets_path'] . "/modern-enhancements.css", array('style'), $assets_version, 'all');
|
||||
|
||||
// 集成外部资源备用机制
|
||||
wp_enqueue_script("resource_loader", $GLOBALS['assets_path'] . "/assets/vendor/external/resource-loader.js", array(), $assets_version, false);
|
||||
|
||||
@@ -291,9 +288,6 @@
|
||||
|
||||
// 加载 argon_js_merged(包含 jQuery 和其他库)- 在头部同步加载以确保后续脚本可用
|
||||
wp_enqueue_script("argon_js_merged", $GLOBALS['assets_path'] . "/assets/argon_js_merged.js", array(), $assets_version, false);
|
||||
|
||||
// 现代化交互动画增强 - 在页面底部加载
|
||||
wp_enqueue_script("modern_enhancements", $GLOBALS['assets_path'] . "/modern-enhancements.js", array('argon_js_merged'), $assets_version, true);
|
||||
?>
|
||||
|
||||
<?php wp_head(); ?>
|
||||
|
||||
@@ -1,903 +0,0 @@
|
||||
/**
|
||||
* Argon Theme - Modern UI Enhancements
|
||||
* 现代化布局和动画优化
|
||||
*
|
||||
* 特性:
|
||||
* - Material Design 3 动画系统
|
||||
* - 桌面端悬停效果增强
|
||||
* - 移动端触摸反馈优化
|
||||
* - 滚动驱动动画
|
||||
* - 页面过渡效果
|
||||
*/
|
||||
|
||||
/* ========== 1. 增强动画变量 ========== */
|
||||
:root {
|
||||
/* 微交互时长 */
|
||||
--micro-duration: 80ms;
|
||||
|
||||
/* 高级缓动函数 */
|
||||
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
|
||||
--ease-in-out-expo: cubic-bezier(0.87, 0, 0.13, 1);
|
||||
--ease-elastic: cubic-bezier(0.68, -0.6, 0.32, 1.6);
|
||||
--ease-back: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
|
||||
/* 阴影层级 - Material 3 */
|
||||
--shadow-1: 0 1px 2px rgba(0, 0, 0, 0.05), 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
--shadow-2: 0 2px 4px rgba(0, 0, 0, 0.05), 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
--shadow-3: 0 4px 8px rgba(0, 0, 0, 0.05), 0 8px 16px rgba(0, 0, 0, 0.1);
|
||||
--shadow-4: 0 8px 16px rgba(0, 0, 0, 0.08), 0 16px 32px rgba(0, 0, 0, 0.12);
|
||||
--shadow-5: 0 12px 24px rgba(0, 0, 0, 0.1), 0 24px 48px rgba(0, 0, 0, 0.15);
|
||||
|
||||
/* 悬停阴影 - 带主题色光晕 */
|
||||
--shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.1),
|
||||
0 4px 10px rgba(var(--themecolor-rgbstr), 0.08);
|
||||
--shadow-active: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
html.darkmode {
|
||||
--shadow-1: 0 1px 2px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
--shadow-2: 0 2px 4px rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||
--shadow-3: 0 4px 8px rgba(0, 0, 0, 0.2), 0 8px 16px rgba(0, 0, 0, 0.3);
|
||||
--shadow-4: 0 8px 16px rgba(0, 0, 0, 0.25), 0 16px 32px rgba(0, 0, 0, 0.35);
|
||||
--shadow-5: 0 12px 24px rgba(0, 0, 0, 0.3), 0 24px 48px rgba(0, 0, 0, 0.4);
|
||||
|
||||
--shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.35),
|
||||
0 4px 10px rgba(var(--themecolor-rgbstr), 0.15);
|
||||
}
|
||||
|
||||
/* ========== 2. 桌面端卡片悬停效果增强 ========== */
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
/* 文章卡片 - 高级悬停效果 */
|
||||
article.post.card {
|
||||
transition: transform var(--animation-normal) var(--ease-out-expo),
|
||||
box-shadow var(--animation-normal) var(--ease-standard);
|
||||
will-change: transform, box-shadow;
|
||||
}
|
||||
|
||||
article.post.card:hover {
|
||||
transform: translateY(-6px) scale(1.005);
|
||||
box-shadow: var(--shadow-hover);
|
||||
}
|
||||
|
||||
article.post.card:active {
|
||||
transform: translateY(-2px) scale(0.995);
|
||||
box-shadow: var(--shadow-active);
|
||||
transition-duration: var(--micro-duration);
|
||||
}
|
||||
|
||||
/* 缩略图悬停缩放 */
|
||||
article.post.card .post-thumbnail {
|
||||
transition: transform var(--animation-slow) var(--ease-out-expo);
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
article.post.card:hover .post-thumbnail {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* 通用卡片悬停 */
|
||||
.card:not(article):not(.no-hover-effect) {
|
||||
transition: transform var(--animation-normal) var(--ease-standard),
|
||||
box-shadow var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
|
||||
.card:not(article):not(.no-hover-effect):hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--shadow-3);
|
||||
}
|
||||
|
||||
/* 侧边栏卡片悬停 */
|
||||
#leftbar .card,
|
||||
#rightbar .card {
|
||||
transition: transform var(--animation-normal) var(--ease-standard),
|
||||
box-shadow var(--animation-normal) var(--ease-standard),
|
||||
border-color var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
#leftbar .card:hover,
|
||||
#rightbar .card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-2);
|
||||
border-color: rgba(var(--themecolor-rgbstr), 0.15);
|
||||
}
|
||||
|
||||
/* 按钮悬停效果增强 */
|
||||
.btn {
|
||||
transition: all var(--animation-fast) var(--ease-standard);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.btn::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(180deg, rgba(255,255,255,0.15) 0%, transparent 100%);
|
||||
opacity: 0;
|
||||
transition: opacity var(--animation-fast) var(--ease-standard);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.btn:hover::after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: translateY(0) scale(0.98);
|
||||
transition-duration: var(--micro-duration);
|
||||
}
|
||||
|
||||
/* 链接下划线动画 */
|
||||
article .post-content a:not([class*="button"]):not(.no-underline) {
|
||||
background-image: linear-gradient(var(--themecolor), var(--themecolor));
|
||||
background-size: 0% 2px;
|
||||
background-position: 0 100%;
|
||||
background-repeat: no-repeat;
|
||||
transition: background-size var(--animation-normal) var(--ease-out-expo);
|
||||
}
|
||||
|
||||
article .post-content a:not([class*="button"]):not(.no-underline):hover {
|
||||
background-size: 100% 2px;
|
||||
}
|
||||
|
||||
/* 导航菜单项悬停 */
|
||||
.navbar-nav .nav-link {
|
||||
position: relative;
|
||||
transition: color var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
.navbar-nav .nav-link::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 2px;
|
||||
background: currentColor;
|
||||
transition: width var(--animation-normal) var(--ease-out-expo),
|
||||
left var(--animation-normal) var(--ease-out-expo);
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.navbar-nav .nav-link:hover::before {
|
||||
width: 100%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
/* 评论卡片悬停 */
|
||||
.comment-item {
|
||||
transition: transform var(--animation-normal) var(--ease-standard),
|
||||
box-shadow var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
|
||||
.comment-item:hover {
|
||||
transform: translateX(4px);
|
||||
box-shadow: -4px 0 0 var(--themecolor);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== 3. 滚动入场动画 ========== */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInScale {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInLeft {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(-20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInRight {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateX(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 文章列表入场动画 */
|
||||
.article-list article.post {
|
||||
animation: fadeInUp var(--animation-slow) var(--ease-emphasized-decelerate) both;
|
||||
}
|
||||
|
||||
.article-list article.post:nth-child(1) { animation-delay: 0ms; }
|
||||
.article-list article.post:nth-child(2) { animation-delay: 50ms; }
|
||||
.article-list article.post:nth-child(3) { animation-delay: 100ms; }
|
||||
.article-list article.post:nth-child(4) { animation-delay: 150ms; }
|
||||
.article-list article.post:nth-child(5) { animation-delay: 200ms; }
|
||||
.article-list article.post:nth-child(6) { animation-delay: 250ms; }
|
||||
.article-list article.post:nth-child(7) { animation-delay: 300ms; }
|
||||
.article-list article.post:nth-child(8) { animation-delay: 350ms; }
|
||||
.article-list article.post:nth-child(n+9) { animation-delay: 400ms; }
|
||||
|
||||
/* 侧边栏入场动画 */
|
||||
#leftbar .card {
|
||||
animation: slideInLeft var(--animation-slow) var(--ease-emphasized-decelerate) both;
|
||||
}
|
||||
|
||||
#leftbar .card:nth-child(1) { animation-delay: 100ms; }
|
||||
#leftbar .card:nth-child(2) { animation-delay: 150ms; }
|
||||
#leftbar .card:nth-child(3) { animation-delay: 200ms; }
|
||||
#leftbar .card:nth-child(4) { animation-delay: 250ms; }
|
||||
#leftbar .card:nth-child(5) { animation-delay: 300ms; }
|
||||
|
||||
#rightbar .card {
|
||||
animation: slideInRight var(--animation-slow) var(--ease-emphasized-decelerate) both;
|
||||
}
|
||||
|
||||
#rightbar .card:nth-child(1) { animation-delay: 100ms; }
|
||||
#rightbar .card:nth-child(2) { animation-delay: 150ms; }
|
||||
#rightbar .card:nth-child(3) { animation-delay: 200ms; }
|
||||
|
||||
/* ========== 4. 页面过渡效果 ========== */
|
||||
/* PJAX 页面切换动画 */
|
||||
#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 contentFadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(15px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
article.post.post-full {
|
||||
animation: contentFadeIn var(--animation-slow) var(--ease-emphasized-decelerate);
|
||||
}
|
||||
|
||||
/* ========== 5. 浮动按钮动画优化 ========== */
|
||||
#float_action_buttons {
|
||||
transition: transform var(--animation-normal) var(--ease-back),
|
||||
opacity var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
|
||||
#float_action_buttons .fabtn {
|
||||
transition: transform var(--animation-fast) var(--ease-spring),
|
||||
background var(--animation-fast) var(--ease-standard),
|
||||
box-shadow var(--animation-fast) var(--ease-standard),
|
||||
opacity var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
#float_action_buttons .fabtn:hover {
|
||||
transform: scale(1.1);
|
||||
box-shadow: var(--shadow-3);
|
||||
}
|
||||
}
|
||||
|
||||
#float_action_buttons .fabtn:active {
|
||||
transform: scale(0.9);
|
||||
transition-duration: var(--micro-duration);
|
||||
}
|
||||
|
||||
/* 浮动按钮入场动画 */
|
||||
@keyframes fabtnBounceIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.3);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
70% {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
#float_action_buttons:not(.fabtns-unloaded) .fabtn:not(.fabtn-hidden) {
|
||||
animation: fabtnBounceIn var(--animation-slow) var(--ease-spring) both;
|
||||
}
|
||||
|
||||
#float_action_buttons .fabtn:nth-child(1) { animation-delay: 0ms; }
|
||||
#float_action_buttons .fabtn:nth-child(2) { animation-delay: 50ms; }
|
||||
#float_action_buttons .fabtn:nth-child(3) { animation-delay: 100ms; }
|
||||
#float_action_buttons .fabtn:nth-child(4) { animation-delay: 150ms; }
|
||||
#float_action_buttons .fabtn:nth-child(5) { animation-delay: 200ms; }
|
||||
|
||||
/* ========== 6. 顶栏动画优化 ========== */
|
||||
#navbar-main {
|
||||
transition: background-color var(--animation-normal) var(--ease-standard),
|
||||
padding var(--animation-normal) var(--ease-standard),
|
||||
box-shadow var(--animation-normal) var(--ease-standard),
|
||||
transform var(--animation-normal) var(--ease-standard),
|
||||
backdrop-filter var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
|
||||
/* 顶栏滚动效果 */
|
||||
#navbar-main:not(.navbar-ontop) {
|
||||
box-shadow: var(--shadow-2);
|
||||
}
|
||||
|
||||
/* 搜索框展开动画 */
|
||||
#navbar_search_input_container .input-group {
|
||||
transition: width var(--animation-normal) var(--ease-out-expo),
|
||||
background var(--animation-fast) var(--ease-standard),
|
||||
box-shadow var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
#navbar_search_input_container.open .input-group {
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* ========== 7. 评论区动画 ========== */
|
||||
.comment-item {
|
||||
animation: fadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) both;
|
||||
}
|
||||
|
||||
/* 评论交错入场 */
|
||||
.comment-item:nth-child(1) { animation-delay: 0ms; }
|
||||
.comment-item:nth-child(2) { animation-delay: 30ms; }
|
||||
.comment-item:nth-child(3) { animation-delay: 60ms; }
|
||||
.comment-item:nth-child(4) { animation-delay: 90ms; }
|
||||
.comment-item:nth-child(5) { animation-delay: 120ms; }
|
||||
.comment-item:nth-child(n+6) { animation-delay: 150ms; }
|
||||
|
||||
/* 评论发送成功动画 */
|
||||
@keyframes commentSuccess {
|
||||
0% {
|
||||
transform: scale(0.8);
|
||||
opacity: 0;
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.comment-item.new-comment {
|
||||
animation: commentSuccess var(--animation-slow) var(--ease-spring);
|
||||
}
|
||||
|
||||
/* ========== 8. 图片加载动画 ========== */
|
||||
article img,
|
||||
.post-thumbnail img {
|
||||
transition: opacity var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
|
||||
article img[loading="lazy"],
|
||||
.post-thumbnail img[loading="lazy"] {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
article img.loaded,
|
||||
.post-thumbnail img.loaded,
|
||||
article img:not([loading="lazy"]),
|
||||
.post-thumbnail img:not([loading="lazy"]) {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* ========== 9. 表单元素动画 ========== */
|
||||
.form-control {
|
||||
transition: border-color var(--animation-fast) var(--ease-standard),
|
||||
box-shadow var(--animation-fast) var(--ease-standard),
|
||||
background-color var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
box-shadow: 0 0 0 3px rgba(var(--themecolor-rgbstr), 0.15);
|
||||
border-color: var(--themecolor);
|
||||
}
|
||||
|
||||
/* 输入框标签浮动效果 */
|
||||
.form-group.floating-label {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.form-group.floating-label label {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
transition: all var(--animation-fast) var(--ease-standard);
|
||||
pointer-events: none;
|
||||
color: #999;
|
||||
background: var(--color-foreground);
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.form-group.floating-label .form-control:focus ~ label,
|
||||
.form-group.floating-label .form-control:not(:placeholder-shown) ~ label {
|
||||
top: 0;
|
||||
font-size: 12px;
|
||||
color: var(--themecolor);
|
||||
}
|
||||
|
||||
/* ========== 10. 滚动条美化 ========== */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(var(--themecolor-rgbstr), 0.3);
|
||||
border-radius: 4px;
|
||||
border: 2px solid transparent;
|
||||
background-clip: content-box;
|
||||
transition: background var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(var(--themecolor-rgbstr), 0.5);
|
||||
background-clip: content-box;
|
||||
}
|
||||
|
||||
/* Firefox 滚动条 */
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(var(--themecolor-rgbstr), 0.3) transparent;
|
||||
}
|
||||
|
||||
|
||||
/* ========== 11. 移动端触摸优化 ========== */
|
||||
@media (hover: none) and (pointer: coarse) {
|
||||
/* 移动端禁用悬停效果,优化触摸反馈 */
|
||||
article.post.card:hover {
|
||||
transform: none;
|
||||
box-shadow: var(--shadow-1);
|
||||
}
|
||||
|
||||
/* 触摸反馈 - 按下效果 */
|
||||
article.post.card:active {
|
||||
transform: scale(0.98);
|
||||
transition-duration: var(--micro-duration);
|
||||
}
|
||||
|
||||
.card:active {
|
||||
transform: scale(0.99);
|
||||
transition-duration: var(--micro-duration);
|
||||
}
|
||||
|
||||
/* 按钮触摸反馈 */
|
||||
.btn:active {
|
||||
transform: scale(0.95);
|
||||
transition-duration: var(--micro-duration);
|
||||
}
|
||||
|
||||
/* 链接触摸反馈 */
|
||||
a:active {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/* 移动端点击高亮禁用 */
|
||||
* {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
/* 触摸涟漪效果基础样式 */
|
||||
.touch-ripple {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background: rgba(var(--themecolor-rgbstr), 0.25);
|
||||
transform: scale(0);
|
||||
animation: touchRipple 0.6s var(--ease-out-expo) forwards;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@keyframes touchRipple {
|
||||
to {
|
||||
transform: scale(4);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== 12. 移动端侧边栏动画增强 ========== */
|
||||
@media screen and (max-width: 900px) {
|
||||
/* 侧边栏滑入动画 */
|
||||
#leftbar {
|
||||
transition: transform var(--animation-normal) var(--ease-out-expo),
|
||||
box-shadow var(--animation-normal) var(--ease-standard);
|
||||
transform: translateX(-100%);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
html.leftbar-opened #leftbar {
|
||||
transform: translateX(0);
|
||||
box-shadow: 4px 0 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* 遮罩层动画 */
|
||||
#leftbar_backdrop {
|
||||
transition: opacity var(--animation-normal) var(--ease-standard),
|
||||
visibility var(--animation-normal);
|
||||
}
|
||||
|
||||
/* 侧边栏内容入场动画 */
|
||||
html.leftbar-opened .leftbar-mobile-profile {
|
||||
animation: slideInDown var(--animation-normal) var(--ease-emphasized-decelerate) 0.1s both;
|
||||
}
|
||||
|
||||
html.leftbar-opened .leftbar-mobile-search {
|
||||
animation: fadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) 0.15s both;
|
||||
}
|
||||
|
||||
html.leftbar-opened .leftbar-mobile-menu-section {
|
||||
animation: fadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) 0.2s both;
|
||||
}
|
||||
|
||||
html.leftbar-opened .leftbar-mobile-footer {
|
||||
animation: fadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) 0.25s both;
|
||||
}
|
||||
|
||||
@keyframes slideInDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-15px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 移动端菜单项触摸反馈 */
|
||||
.leftbar-mobile-menu-item > a {
|
||||
transition: background var(--animation-fast) var(--ease-standard),
|
||||
transform var(--micro-duration) var(--ease-standard);
|
||||
}
|
||||
|
||||
.leftbar-mobile-menu-item > a:active {
|
||||
background: rgba(var(--themecolor-rgbstr), 0.12);
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
/* 移动端底部导航栏(如果有) */
|
||||
.mobile-bottom-nav {
|
||||
transition: transform var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
|
||||
.mobile-bottom-nav.hidden {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
/* 移动端文章卡片优化 */
|
||||
article.post.card {
|
||||
transition: transform var(--micro-duration) var(--ease-standard),
|
||||
box-shadow var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
article.post.card:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
/* 移动端顶栏优化 */
|
||||
#navbar-main {
|
||||
transition: transform var(--animation-normal) var(--ease-standard),
|
||||
background-color var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
/* 移动端搜索框展开 */
|
||||
#navbar_search_input_container {
|
||||
transition: width var(--animation-normal) var(--ease-out-expo);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== 13. 骨架屏加载动画 ========== */
|
||||
@keyframes skeletonPulse {
|
||||
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: skeletonPulse 1.5s ease-in-out infinite;
|
||||
border-radius: var(--card-radius);
|
||||
}
|
||||
|
||||
/* ========== 14. 加载指示器 ========== */
|
||||
@keyframes spinnerRotate {
|
||||
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: spinnerRotate 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);
|
||||
}
|
||||
|
||||
/* ========== 15. 模态框/弹窗动画 ========== */
|
||||
.modal {
|
||||
transition: opacity var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
|
||||
.modal.show {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
transition: transform var(--animation-normal) var(--ease-emphasized-decelerate),
|
||||
opacity var(--animation-normal) var(--ease-standard);
|
||||
transform: scale(0.9) translateY(-20px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.modal.show .modal-dialog {
|
||||
transform: scale(1) translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 底部弹出式模态框(移动端) */
|
||||
@media screen and (max-width: 900px) {
|
||||
.modal-dialog.modal-bottom {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
transform: translateY(100%);
|
||||
border-radius: 20px 20px 0 0;
|
||||
}
|
||||
|
||||
.modal.show .modal-dialog.modal-bottom {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== 16. 下拉菜单动画 ========== */
|
||||
.dropdown-menu {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px) scale(0.95);
|
||||
transform-origin: top center;
|
||||
transition: opacity var(--animation-fast) var(--ease-standard),
|
||||
transform var(--animation-fast) var(--ease-emphasized-decelerate),
|
||||
visibility var(--animation-fast);
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.dropdown-menu.show {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
transition: background var(--animation-fast) var(--ease-standard),
|
||||
color var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
/* ========== 17. 工具提示动画 ========== */
|
||||
.tooltip {
|
||||
opacity: 0;
|
||||
transform: translateY(5px);
|
||||
transition: opacity var(--animation-fast) var(--ease-standard),
|
||||
transform var(--animation-fast) var(--ease-emphasized-decelerate);
|
||||
}
|
||||
|
||||
.tooltip.show {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* ========== 18. 标签和徽章动画 ========== */
|
||||
.badge,
|
||||
.tag {
|
||||
transition: transform var(--animation-fast) var(--ease-spring),
|
||||
background var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.badge:hover,
|
||||
.tag:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
}
|
||||
|
||||
.badge:active,
|
||||
.tag:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* ========== 19. 分页动画 ========== */
|
||||
.pagination .page-link {
|
||||
transition: all var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.pagination .page-link:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-2);
|
||||
}
|
||||
}
|
||||
|
||||
.pagination .page-link:active {
|
||||
transform: translateY(0) scale(0.95);
|
||||
}
|
||||
|
||||
/* ========== 20. 目录导航动画 ========== */
|
||||
.index-link {
|
||||
transition: all var(--animation-fast) var(--ease-standard);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.index-link::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%) scaleY(0);
|
||||
width: 3px;
|
||||
height: 60%;
|
||||
background: var(--themecolor);
|
||||
border-radius: 2px;
|
||||
transition: transform var(--animation-normal) var(--ease-spring);
|
||||
}
|
||||
|
||||
.index-item.current > .index-link::before {
|
||||
transform: translateY(-50%) scaleY(1);
|
||||
}
|
||||
|
||||
/* ========== 21. 时间线动画 ========== */
|
||||
.timeline-item {
|
||||
opacity: 0;
|
||||
transform: translateX(-20px);
|
||||
animation: timelineSlideIn var(--animation-slow) var(--ease-emphasized-decelerate) forwards;
|
||||
}
|
||||
|
||||
@keyframes timelineSlideIn {
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-item:nth-child(1) { animation-delay: 0ms; }
|
||||
.timeline-item:nth-child(2) { animation-delay: 100ms; }
|
||||
.timeline-item:nth-child(3) { animation-delay: 200ms; }
|
||||
.timeline-item:nth-child(4) { animation-delay: 300ms; }
|
||||
.timeline-item:nth-child(5) { animation-delay: 400ms; }
|
||||
.timeline-item:nth-child(n+6) { animation-delay: 500ms; }
|
||||
|
||||
/* ========== 22. 友链卡片动画 ========== */
|
||||
.friend-link-item {
|
||||
transition: transform var(--animation-normal) var(--ease-spring),
|
||||
box-shadow var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.friend-link-item:hover {
|
||||
transform: translateY(-5px) rotate(1deg);
|
||||
box-shadow: var(--shadow-4);
|
||||
}
|
||||
|
||||
.friend-link-item:hover .friend-link-avatar {
|
||||
transform: scale(1.1) rotate(-5deg);
|
||||
}
|
||||
}
|
||||
|
||||
.friend-link-avatar {
|
||||
transition: transform var(--animation-normal) var(--ease-spring);
|
||||
}
|
||||
|
||||
/* ========== 23. 代码块动画 ========== */
|
||||
.hljs-codeblock {
|
||||
transition: box-shadow var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.hljs-codeblock:hover {
|
||||
box-shadow: var(--shadow-3);
|
||||
}
|
||||
}
|
||||
|
||||
/* 代码复制按钮 */
|
||||
.code-copy-btn {
|
||||
opacity: 0;
|
||||
transform: translateY(-5px);
|
||||
transition: opacity var(--animation-fast) var(--ease-standard),
|
||||
transform var(--animation-fast) var(--ease-standard),
|
||||
background var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
|
||||
.hljs-codeblock:hover .code-copy-btn {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* ========== 24. 减少动画偏好支持 ========== */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
|
||||
/* 保留必要的过渡 */
|
||||
.card,
|
||||
.btn,
|
||||
a {
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== 25. 打印样式优化 ========== */
|
||||
@media print {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation: none !important;
|
||||
transition: none !important;
|
||||
}
|
||||
}
|
||||
@@ -1,318 +0,0 @@
|
||||
/**
|
||||
* Argon Theme - Modern UI Enhancements JavaScript
|
||||
* 现代化交互动画增强
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// ========== 1. 触摸涟漪效果 ==========
|
||||
function createRipple(event, element) {
|
||||
// 只在移动端或触摸设备上启用
|
||||
if (window.matchMedia('(hover: hover)').matches) return;
|
||||
|
||||
const rect = element.getBoundingClientRect();
|
||||
const ripple = document.createElement('span');
|
||||
const size = Math.max(rect.width, rect.height);
|
||||
|
||||
ripple.style.width = ripple.style.height = size + 'px';
|
||||
ripple.style.left = (event.clientX || event.touches[0].clientX) - rect.left - size / 2 + 'px';
|
||||
ripple.style.top = (event.clientY || event.touches[0].clientY) - rect.top - size / 2 + 'px';
|
||||
ripple.className = 'touch-ripple';
|
||||
|
||||
// 移除旧的涟漪
|
||||
const oldRipple = element.querySelector('.touch-ripple');
|
||||
if (oldRipple) oldRipple.remove();
|
||||
|
||||
element.style.position = 'relative';
|
||||
element.style.overflow = 'hidden';
|
||||
element.appendChild(ripple);
|
||||
|
||||
// 动画结束后移除
|
||||
setTimeout(() => ripple.remove(), 600);
|
||||
}
|
||||
|
||||
// 为可点击元素添加涟漪效果
|
||||
function initRippleEffect() {
|
||||
const rippleElements = document.querySelectorAll(
|
||||
'.btn, .card, .nav-link, .dropdown-item, .page-link, ' +
|
||||
'.leftbar-mobile-menu-item > a, .leftbar-mobile-action, ' +
|
||||
'.fabtn, .comment-reply, .tag, .badge'
|
||||
);
|
||||
|
||||
rippleElements.forEach(el => {
|
||||
if (el.dataset.rippleInit) return;
|
||||
el.dataset.rippleInit = 'true';
|
||||
|
||||
el.addEventListener('touchstart', function(e) {
|
||||
createRipple(e, this);
|
||||
}, { passive: true });
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 2. 图片加载动画 ==========
|
||||
function initImageLoadAnimation() {
|
||||
const images = document.querySelectorAll('article img[loading="lazy"], .post-thumbnail img');
|
||||
|
||||
images.forEach(img => {
|
||||
if (img.dataset.loadAnimInit) return;
|
||||
img.dataset.loadAnimInit = 'true';
|
||||
|
||||
if (img.complete) {
|
||||
img.classList.add('loaded');
|
||||
} else {
|
||||
img.addEventListener('load', function() {
|
||||
this.classList.add('loaded');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 3. 滚动入场动画 (Intersection Observer) ==========
|
||||
function initScrollAnimations() {
|
||||
if (!('IntersectionObserver' in window)) return;
|
||||
|
||||
const animatedElements = document.querySelectorAll(
|
||||
'.article-list article.post, .comment-item, .timeline-item, ' +
|
||||
'.friend-link-item, #leftbar .card, #rightbar .card'
|
||||
);
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('animate-in');
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
threshold: 0.1,
|
||||
rootMargin: '0px 0px -50px 0px'
|
||||
});
|
||||
|
||||
animatedElements.forEach(el => {
|
||||
if (!el.classList.contains('animate-in')) {
|
||||
observer.observe(el);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 4. 平滑滚动增强 ==========
|
||||
function initSmoothScroll() {
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
if (anchor.dataset.smoothScrollInit) return;
|
||||
anchor.dataset.smoothScrollInit = 'true';
|
||||
|
||||
anchor.addEventListener('click', function(e) {
|
||||
const targetId = this.getAttribute('href');
|
||||
if (targetId === '#') return;
|
||||
|
||||
const target = document.querySelector(targetId);
|
||||
if (target) {
|
||||
e.preventDefault();
|
||||
target.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'start'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 5. 页面加载进度条 ==========
|
||||
function initLoadingBar() {
|
||||
// 检查是否已存在
|
||||
if (document.getElementById('page-loading-bar')) return;
|
||||
|
||||
const bar = document.createElement('div');
|
||||
bar.id = 'page-loading-bar';
|
||||
bar.style.width = '0%';
|
||||
document.body.appendChild(bar);
|
||||
|
||||
// 模拟加载进度
|
||||
let progress = 0;
|
||||
const interval = setInterval(() => {
|
||||
progress += Math.random() * 10;
|
||||
if (progress >= 90) {
|
||||
clearInterval(interval);
|
||||
progress = 90;
|
||||
}
|
||||
bar.style.width = progress + '%';
|
||||
}, 100);
|
||||
|
||||
// 页面加载完成
|
||||
window.addEventListener('load', () => {
|
||||
clearInterval(interval);
|
||||
bar.style.width = '100%';
|
||||
setTimeout(() => {
|
||||
bar.style.opacity = '0';
|
||||
setTimeout(() => bar.remove(), 300);
|
||||
}, 200);
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 6. PJAX 加载动画 ==========
|
||||
function initPjaxAnimations() {
|
||||
if (typeof jQuery === 'undefined') return;
|
||||
|
||||
jQuery(document).on('pjax:start', function() {
|
||||
jQuery('#primary').addClass('pjax-loading');
|
||||
|
||||
// 显示加载进度条
|
||||
let bar = document.getElementById('page-loading-bar');
|
||||
if (!bar) {
|
||||
bar = document.createElement('div');
|
||||
bar.id = 'page-loading-bar';
|
||||
document.body.appendChild(bar);
|
||||
}
|
||||
bar.style.opacity = '1';
|
||||
bar.style.width = '30%';
|
||||
|
||||
setTimeout(() => bar.style.width = '60%', 200);
|
||||
});
|
||||
|
||||
jQuery(document).on('pjax:end', function() {
|
||||
jQuery('#primary').removeClass('pjax-loading');
|
||||
|
||||
const bar = document.getElementById('page-loading-bar');
|
||||
if (bar) {
|
||||
bar.style.width = '100%';
|
||||
setTimeout(() => {
|
||||
bar.style.opacity = '0';
|
||||
setTimeout(() => bar.remove(), 300);
|
||||
}, 200);
|
||||
}
|
||||
|
||||
// 重新初始化动画
|
||||
setTimeout(() => {
|
||||
initRippleEffect();
|
||||
initImageLoadAnimation();
|
||||
initScrollAnimations();
|
||||
initSmoothScroll();
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 7. 卡片倾斜效果 (桌面端) ==========
|
||||
function initCardTiltEffect() {
|
||||
if (!window.matchMedia('(hover: hover)').matches) return;
|
||||
|
||||
const cards = document.querySelectorAll('article.post.card');
|
||||
|
||||
cards.forEach(card => {
|
||||
if (card.dataset.tiltInit) return;
|
||||
card.dataset.tiltInit = 'true';
|
||||
|
||||
card.addEventListener('mousemove', function(e) {
|
||||
const rect = this.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
const y = e.clientY - rect.top;
|
||||
const centerX = rect.width / 2;
|
||||
const centerY = rect.height / 2;
|
||||
|
||||
const rotateX = (y - centerY) / 20;
|
||||
const rotateY = (centerX - x) / 20;
|
||||
|
||||
this.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) translateY(-6px)`;
|
||||
});
|
||||
|
||||
card.addEventListener('mouseleave', function() {
|
||||
this.style.transform = '';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 8. 浮动按钮显示/隐藏动画 ==========
|
||||
function initFabAnimation() {
|
||||
const fab = document.getElementById('float_action_buttons');
|
||||
if (!fab) return;
|
||||
|
||||
let lastScrollY = window.scrollY;
|
||||
let ticking = false;
|
||||
|
||||
window.addEventListener('scroll', function() {
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(function() {
|
||||
const currentScrollY = window.scrollY;
|
||||
|
||||
// 向下滚动时隐藏,向上滚动时显示
|
||||
if (currentScrollY > lastScrollY && currentScrollY > 300) {
|
||||
fab.style.transform = 'translateY(100px)';
|
||||
fab.style.opacity = '0';
|
||||
} else {
|
||||
fab.style.transform = '';
|
||||
fab.style.opacity = '';
|
||||
}
|
||||
|
||||
lastScrollY = currentScrollY;
|
||||
ticking = false;
|
||||
});
|
||||
ticking = true;
|
||||
}
|
||||
}, { passive: true });
|
||||
}
|
||||
|
||||
// ========== 9. 主题切换动画增强 ==========
|
||||
function initThemeTransition() {
|
||||
// 监听暗色模式切换
|
||||
const observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.attributeName === 'class') {
|
||||
const html = document.documentElement;
|
||||
if (html.classList.contains('darkmode') || !html.classList.contains('darkmode')) {
|
||||
// 添加过渡类
|
||||
html.classList.add('theme-transitioning');
|
||||
setTimeout(() => {
|
||||
html.classList.remove('theme-transitioning');
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 10. 减少动画偏好检测 ==========
|
||||
function checkReducedMotion() {
|
||||
if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
||||
document.documentElement.classList.add('reduced-motion');
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 初始化 ==========
|
||||
function init() {
|
||||
checkReducedMotion();
|
||||
initRippleEffect();
|
||||
initImageLoadAnimation();
|
||||
initScrollAnimations();
|
||||
initSmoothScroll();
|
||||
initPjaxAnimations();
|
||||
initThemeTransition();
|
||||
|
||||
// 桌面端特效
|
||||
if (window.matchMedia('(hover: hover)').matches) {
|
||||
// initCardTiltEffect(); // 可选:卡片倾斜效果
|
||||
}
|
||||
|
||||
// 移动端特效
|
||||
if (!window.matchMedia('(hover: hover)').matches) {
|
||||
// initFabAnimation(); // 可选:浮动按钮滚动隐藏
|
||||
}
|
||||
}
|
||||
|
||||
// DOM 加载完成后初始化
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
|
||||
// 首次加载时显示进度条
|
||||
if (document.readyState !== 'complete') {
|
||||
initLoadingBar();
|
||||
}
|
||||
|
||||
})();
|
||||
261
style.css
261
style.css
@@ -16295,3 +16295,264 @@ html.darkmode.style-glass article.post.post-full.card {
|
||||
transform: translateZ(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== Modern UI Enhancements - 现代化布局和动画优化 ========== */
|
||||
|
||||
/* 1. 增强动画变量 */
|
||||
:root {
|
||||
--micro-duration: 80ms;
|
||||
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
|
||||
--ease-in-out-expo: cubic-bezier(0.87, 0, 0.13, 1);
|
||||
--ease-elastic: cubic-bezier(0.68, -0.6, 0.32, 1.6);
|
||||
--ease-back: cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
--shadow-1: 0 1px 2px rgba(0, 0, 0, 0.05), 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
--shadow-2: 0 2px 4px rgba(0, 0, 0, 0.05), 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
--shadow-3: 0 4px 8px rgba(0, 0, 0, 0.05), 0 8px 16px rgba(0, 0, 0, 0.1);
|
||||
--shadow-4: 0 8px 16px rgba(0, 0, 0, 0.08), 0 16px 32px rgba(0, 0, 0, 0.12);
|
||||
--shadow-5: 0 12px 24px rgba(0, 0, 0, 0.1), 0 24px 48px rgba(0, 0, 0, 0.15);
|
||||
--shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.1), 0 4px 10px rgba(var(--themecolor-rgbstr), 0.08);
|
||||
--shadow-active: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
html.darkmode {
|
||||
--shadow-1: 0 1px 2px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
--shadow-2: 0 2px 4px rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||
--shadow-3: 0 4px 8px rgba(0, 0, 0, 0.2), 0 8px 16px rgba(0, 0, 0, 0.3);
|
||||
--shadow-4: 0 8px 16px rgba(0, 0, 0, 0.25), 0 16px 32px rgba(0, 0, 0, 0.35);
|
||||
--shadow-5: 0 12px 24px rgba(0, 0, 0, 0.3), 0 24px 48px rgba(0, 0, 0, 0.4);
|
||||
--shadow-hover: 0 8px 25px rgba(0, 0, 0, 0.35), 0 4px 10px rgba(var(--themecolor-rgbstr), 0.15);
|
||||
}
|
||||
|
||||
/* 2. 桌面端卡片悬停效果增强 */
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
article.post.card {
|
||||
transition: transform var(--animation-normal) var(--ease-out-expo), box-shadow var(--animation-normal) var(--ease-standard);
|
||||
will-change: transform, box-shadow;
|
||||
}
|
||||
article.post.card:hover {
|
||||
transform: translateY(-6px) scale(1.005);
|
||||
box-shadow: var(--shadow-hover);
|
||||
}
|
||||
article.post.card:active {
|
||||
transform: translateY(-2px) scale(0.995);
|
||||
box-shadow: var(--shadow-active);
|
||||
transition-duration: var(--micro-duration);
|
||||
}
|
||||
article.post.card .post-thumbnail {
|
||||
transition: transform var(--animation-slow) var(--ease-out-expo);
|
||||
will-change: transform;
|
||||
}
|
||||
article.post.card:hover .post-thumbnail {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
.card:not(article):not(.no-hover-effect) {
|
||||
transition: transform var(--animation-normal) var(--ease-standard), box-shadow var(--animation-normal) var(--ease-standard);
|
||||
}
|
||||
.card:not(article):not(.no-hover-effect):hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--shadow-3);
|
||||
}
|
||||
#leftbar .card, #rightbar .card {
|
||||
transition: transform var(--animation-normal) var(--ease-standard), box-shadow var(--animation-normal) var(--ease-standard), border-color var(--animation-fast) var(--ease-standard);
|
||||
}
|
||||
#leftbar .card:hover, #rightbar .card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-2);
|
||||
border-color: rgba(var(--themecolor-rgbstr), 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
/* 3. 按钮和链接悬停效果 */
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
.btn { transition: all var(--animation-fast) var(--ease-standard); position: relative; overflow: hidden; }
|
||||
.btn::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(255,255,255,0.15) 0%, transparent 100%); opacity: 0; transition: opacity var(--animation-fast) var(--ease-standard); pointer-events: none; }
|
||||
.btn:hover::after { opacity: 1; }
|
||||
.btn:hover { transform: translateY(-1px); }
|
||||
.btn:active { transform: translateY(0) scale(0.98); transition-duration: var(--micro-duration); }
|
||||
article .post-content a:not([class*="button"]):not(.no-underline) { background-image: linear-gradient(var(--themecolor), var(--themecolor)); background-size: 0% 2px; background-position: 0 100%; background-repeat: no-repeat; transition: background-size var(--animation-normal) var(--ease-out-expo); }
|
||||
article .post-content a:not([class*="button"]):not(.no-underline):hover { background-size: 100% 2px; }
|
||||
.navbar-nav .nav-link { position: relative; transition: color var(--animation-fast) var(--ease-standard); }
|
||||
.navbar-nav .nav-link::before { content: ""; position: absolute; bottom: 0; left: 50%; width: 0; height: 2px; background: currentColor; transition: width var(--animation-normal) var(--ease-out-expo), left var(--animation-normal) var(--ease-out-expo); border-radius: 1px; }
|
||||
.navbar-nav .nav-link:hover::before { width: 100%; left: 0; }
|
||||
.comment-item { transition: transform var(--animation-normal) var(--ease-standard), box-shadow var(--animation-normal) var(--ease-standard); }
|
||||
.comment-item:hover { transform: translateX(4px); box-shadow: -4px 0 0 var(--themecolor); }
|
||||
}
|
||||
|
||||
/* 4. 滚动入场动画 */
|
||||
@keyframes modernFadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
|
||||
@keyframes modernFadeInScale { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } }
|
||||
@keyframes modernSlideInLeft { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } }
|
||||
@keyframes modernSlideInRight { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } }
|
||||
|
||||
.article-list article.post { animation: modernFadeInUp var(--animation-slow) var(--ease-emphasized-decelerate) both; }
|
||||
.article-list article.post:nth-child(1) { animation-delay: 0ms; }
|
||||
.article-list article.post:nth-child(2) { animation-delay: 50ms; }
|
||||
.article-list article.post:nth-child(3) { animation-delay: 100ms; }
|
||||
.article-list article.post:nth-child(4) { animation-delay: 150ms; }
|
||||
.article-list article.post:nth-child(5) { animation-delay: 200ms; }
|
||||
.article-list article.post:nth-child(6) { animation-delay: 250ms; }
|
||||
.article-list article.post:nth-child(7) { animation-delay: 300ms; }
|
||||
.article-list article.post:nth-child(8) { animation-delay: 350ms; }
|
||||
.article-list article.post:nth-child(n+9) { animation-delay: 400ms; }
|
||||
|
||||
#leftbar .card { animation: modernSlideInLeft var(--animation-slow) var(--ease-emphasized-decelerate) both; }
|
||||
#leftbar .card:nth-child(1) { animation-delay: 100ms; }
|
||||
#leftbar .card:nth-child(2) { animation-delay: 150ms; }
|
||||
#leftbar .card:nth-child(3) { animation-delay: 200ms; }
|
||||
#leftbar .card:nth-child(4) { animation-delay: 250ms; }
|
||||
#leftbar .card:nth-child(5) { animation-delay: 300ms; }
|
||||
|
||||
#rightbar .card { animation: modernSlideInRight var(--animation-slow) var(--ease-emphasized-decelerate) both; }
|
||||
#rightbar .card:nth-child(1) { animation-delay: 100ms; }
|
||||
#rightbar .card:nth-child(2) { animation-delay: 150ms; }
|
||||
#rightbar .card:nth-child(3) { animation-delay: 200ms; }
|
||||
|
||||
/* 5. 页面过渡和浮动按钮动画 */
|
||||
#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 { animation: modernContentFadeIn var(--animation-slow) var(--ease-emphasized-decelerate); }
|
||||
|
||||
#float_action_buttons { transition: transform var(--animation-normal) var(--ease-back), opacity var(--animation-normal) var(--ease-standard); }
|
||||
#float_action_buttons .fabtn { transition: transform var(--animation-fast) var(--ease-spring), background var(--animation-fast) var(--ease-standard), box-shadow var(--animation-fast) var(--ease-standard), opacity var(--animation-normal) var(--ease-standard); }
|
||||
@media (hover: hover) { #float_action_buttons .fabtn:hover { transform: scale(1.1); box-shadow: var(--shadow-3); } }
|
||||
#float_action_buttons .fabtn:active { transform: scale(0.9); transition-duration: var(--micro-duration); }
|
||||
@keyframes modernFabtnBounceIn { 0% { opacity: 0; transform: scale(0.3); } 50% { transform: scale(1.05); } 70% { transform: scale(0.95); } 100% { opacity: 1; transform: scale(1); } }
|
||||
#float_action_buttons:not(.fabtns-unloaded) .fabtn:not(.fabtn-hidden) { animation: modernFabtnBounceIn var(--animation-slow) var(--ease-spring) both; }
|
||||
#float_action_buttons .fabtn:nth-child(1) { animation-delay: 0ms; }
|
||||
#float_action_buttons .fabtn:nth-child(2) { animation-delay: 50ms; }
|
||||
#float_action_buttons .fabtn:nth-child(3) { animation-delay: 100ms; }
|
||||
#float_action_buttons .fabtn:nth-child(4) { animation-delay: 150ms; }
|
||||
#float_action_buttons .fabtn:nth-child(5) { animation-delay: 200ms; }
|
||||
|
||||
/* 6. 顶栏和评论区动画 */
|
||||
#navbar-main { transition: background-color var(--animation-normal) var(--ease-standard), padding var(--animation-normal) var(--ease-standard), box-shadow var(--animation-normal) var(--ease-standard), transform var(--animation-normal) var(--ease-standard), backdrop-filter var(--animation-normal) var(--ease-standard); }
|
||||
#navbar-main:not(.navbar-ontop) { box-shadow: var(--shadow-2); }
|
||||
#navbar_search_input_container .input-group { transition: width var(--animation-normal) var(--ease-out-expo), background var(--animation-fast) var(--ease-standard), box-shadow var(--animation-fast) var(--ease-standard); }
|
||||
#navbar_search_input_container.open .input-group { box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); }
|
||||
|
||||
.comment-item { animation: modernFadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) both; }
|
||||
.comment-item:nth-child(1) { animation-delay: 0ms; }
|
||||
.comment-item:nth-child(2) { animation-delay: 30ms; }
|
||||
.comment-item:nth-child(3) { animation-delay: 60ms; }
|
||||
.comment-item:nth-child(4) { animation-delay: 90ms; }
|
||||
.comment-item:nth-child(5) { animation-delay: 120ms; }
|
||||
.comment-item:nth-child(n+6) { animation-delay: 150ms; }
|
||||
@keyframes modernCommentSuccess { 0% { transform: scale(0.8); opacity: 0; } 50% { transform: scale(1.02); } 100% { transform: scale(1); opacity: 1; } }
|
||||
.comment-item.new-comment { animation: modernCommentSuccess var(--animation-slow) var(--ease-spring); }
|
||||
|
||||
/* 7. 图片和表单动画 */
|
||||
article img, .post-thumbnail img { transition: opacity var(--animation-normal) var(--ease-standard); }
|
||||
article img[loading="lazy"], .post-thumbnail img[loading="lazy"] { opacity: 0; }
|
||||
article img.loaded, .post-thumbnail img.loaded, article img:not([loading="lazy"]), .post-thumbnail img:not([loading="lazy"]) { opacity: 1; }
|
||||
|
||||
.form-control { transition: border-color var(--animation-fast) var(--ease-standard), box-shadow var(--animation-fast) var(--ease-standard), background-color var(--animation-fast) var(--ease-standard); }
|
||||
.form-control:focus { box-shadow: 0 0 0 3px rgba(var(--themecolor-rgbstr), 0.15); border-color: var(--themecolor); }
|
||||
.form-group.floating-label { position: relative; }
|
||||
.form-group.floating-label label { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); transition: all var(--animation-fast) var(--ease-standard); pointer-events: none; color: #999; background: var(--color-foreground); padding: 0 4px; }
|
||||
.form-group.floating-label .form-control:focus ~ label, .form-group.floating-label .form-control:not(:placeholder-shown) ~ label { top: 0; font-size: 12px; color: var(--themecolor); }
|
||||
|
||||
/* 8. 滚动条美化 */
|
||||
::-webkit-scrollbar { width: 8px; height: 8px; }
|
||||
::-webkit-scrollbar-track { background: transparent; }
|
||||
::-webkit-scrollbar-thumb { background: rgba(var(--themecolor-rgbstr), 0.3); border-radius: 4px; border: 2px solid transparent; background-clip: content-box; }
|
||||
::-webkit-scrollbar-thumb:hover { background: rgba(var(--themecolor-rgbstr), 0.5); background-clip: content-box; }
|
||||
* { scrollbar-width: thin; scrollbar-color: rgba(var(--themecolor-rgbstr), 0.3) transparent; }
|
||||
|
||||
/* 9. 移动端触摸优化 */
|
||||
@media (hover: none) and (pointer: coarse) {
|
||||
article.post.card:hover { transform: none; box-shadow: var(--shadow-1); }
|
||||
article.post.card:active { transform: scale(0.98); transition-duration: var(--micro-duration); }
|
||||
.card:active { transform: scale(0.99); transition-duration: var(--micro-duration); }
|
||||
.btn:active { transform: scale(0.95); transition-duration: var(--micro-duration); }
|
||||
a:active { opacity: 0.7; }
|
||||
* { -webkit-tap-highlight-color: transparent; }
|
||||
.touch-ripple { position: absolute; border-radius: 50%; background: rgba(var(--themecolor-rgbstr), 0.25); transform: scale(0); animation: modernTouchRipple 0.6s var(--ease-out-expo) forwards; pointer-events: none; }
|
||||
@keyframes modernTouchRipple { to { transform: scale(4); opacity: 0; } }
|
||||
}
|
||||
|
||||
/* 10. 移动端侧边栏动画增强 */
|
||||
@media screen and (max-width: 900px) {
|
||||
#leftbar { transition: transform var(--animation-normal) var(--ease-out-expo), box-shadow var(--animation-normal) var(--ease-standard); transform: translateX(-100%); box-shadow: none; }
|
||||
html.leftbar-opened #leftbar { transform: translateX(0); box-shadow: 4px 0 25px rgba(0, 0, 0, 0.15); }
|
||||
#leftbar_backdrop { transition: opacity var(--animation-normal) var(--ease-standard), visibility var(--animation-normal); }
|
||||
@keyframes modernSlideInDown { from { opacity: 0; transform: translateY(-15px); } to { opacity: 1; transform: translateY(0); } }
|
||||
html.leftbar-opened .leftbar-mobile-profile { animation: modernSlideInDown var(--animation-normal) var(--ease-emphasized-decelerate) 0.1s both; }
|
||||
html.leftbar-opened .leftbar-mobile-search { animation: modernFadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) 0.15s both; }
|
||||
html.leftbar-opened .leftbar-mobile-menu-section { animation: modernFadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) 0.2s both; }
|
||||
html.leftbar-opened .leftbar-mobile-footer { animation: modernFadeInUp var(--animation-normal) var(--ease-emphasized-decelerate) 0.25s both; }
|
||||
.leftbar-mobile-menu-item > a { transition: background var(--animation-fast) var(--ease-standard), transform var(--micro-duration) var(--ease-standard); }
|
||||
.leftbar-mobile-menu-item > a:active { background: rgba(var(--themecolor-rgbstr), 0.12); transform: scale(0.98); }
|
||||
article.post.card { transition: transform var(--micro-duration) var(--ease-standard), box-shadow var(--animation-fast) var(--ease-standard); }
|
||||
article.post.card:active { transform: scale(0.98); }
|
||||
#navbar-main { transition: transform var(--animation-normal) var(--ease-standard), background-color var(--animation-fast) var(--ease-standard); }
|
||||
}
|
||||
|
||||
/* 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); }
|
||||
|
||||
/* 12. 模态框和下拉菜单动画 */
|
||||
.modal { transition: opacity var(--animation-normal) var(--ease-standard); }
|
||||
.modal.show { opacity: 1; }
|
||||
.modal-dialog { transition: transform var(--animation-normal) var(--ease-emphasized-decelerate), opacity var(--animation-normal) var(--ease-standard); transform: scale(0.9) translateY(-20px); opacity: 0; }
|
||||
.modal.show .modal-dialog { transform: scale(1) translateY(0); opacity: 1; }
|
||||
@media screen and (max-width: 900px) {
|
||||
.modal-dialog.modal-bottom { position: fixed; bottom: 0; left: 0; right: 0; margin: 0; transform: translateY(100%); border-radius: 20px 20px 0 0; }
|
||||
.modal.show .modal-dialog.modal-bottom { transform: translateY(0); }
|
||||
}
|
||||
.dropdown-menu { opacity: 0; transform: translateY(-10px) scale(0.95); transform-origin: top center; transition: opacity var(--animation-fast) var(--ease-standard), transform var(--animation-fast) var(--ease-emphasized-decelerate), visibility var(--animation-fast); visibility: hidden; }
|
||||
.dropdown-menu.show { opacity: 1; transform: translateY(0) scale(1); visibility: visible; }
|
||||
.dropdown-item { transition: background var(--animation-fast) var(--ease-standard), color var(--animation-fast) var(--ease-standard); }
|
||||
|
||||
/* 13. 工具提示、标签、分页动画 */
|
||||
.tooltip { opacity: 0; transform: translateY(5px); transition: opacity var(--animation-fast) var(--ease-standard), transform var(--animation-fast) var(--ease-emphasized-decelerate); }
|
||||
.tooltip.show { opacity: 1; transform: translateY(0); }
|
||||
.badge, .tag { transition: transform var(--animation-fast) var(--ease-spring), background var(--animation-fast) var(--ease-standard); }
|
||||
@media (hover: hover) { .badge:hover, .tag:hover { transform: scale(1.05); } }
|
||||
.badge:active, .tag:active { transform: scale(0.95); }
|
||||
.pagination .page-link { transition: all var(--animation-fast) var(--ease-standard); }
|
||||
@media (hover: hover) { .pagination .page-link:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); } }
|
||||
.pagination .page-link:active { transform: translateY(0) scale(0.95); }
|
||||
|
||||
/* 14. 目录导航动画 */
|
||||
.index-link { transition: all var(--animation-fast) var(--ease-standard); position: relative; }
|
||||
.index-link::before { content: ""; position: absolute; left: -8px; top: 50%; transform: translateY(-50%) scaleY(0); width: 3px; height: 60%; background: var(--themecolor); border-radius: 2px; transition: transform var(--animation-normal) var(--ease-spring); }
|
||||
.index-item.current > .index-link::before { transform: translateY(-50%) scaleY(1); }
|
||||
|
||||
/* 15. 时间线动画 */
|
||||
.timeline-item { opacity: 0; transform: translateX(-20px); animation: modernTimelineSlideIn var(--animation-slow) var(--ease-emphasized-decelerate) forwards; }
|
||||
@keyframes modernTimelineSlideIn { to { opacity: 1; transform: translateX(0); } }
|
||||
.timeline-item:nth-child(1) { animation-delay: 0ms; }
|
||||
.timeline-item:nth-child(2) { animation-delay: 100ms; }
|
||||
.timeline-item:nth-child(3) { animation-delay: 200ms; }
|
||||
.timeline-item:nth-child(4) { animation-delay: 300ms; }
|
||||
.timeline-item:nth-child(5) { animation-delay: 400ms; }
|
||||
.timeline-item:nth-child(n+6) { animation-delay: 500ms; }
|
||||
|
||||
/* 16. 友链和代码块动画 */
|
||||
.friend-link-item { transition: transform var(--animation-normal) var(--ease-spring), box-shadow var(--animation-normal) var(--ease-standard); }
|
||||
@media (hover: hover) {
|
||||
.friend-link-item:hover { transform: translateY(-5px) rotate(1deg); box-shadow: var(--shadow-4); }
|
||||
.friend-link-item:hover .friend-link-avatar { transform: scale(1.1) rotate(-5deg); }
|
||||
}
|
||||
.friend-link-avatar { transition: transform var(--animation-normal) var(--ease-spring); }
|
||||
.hljs-codeblock { transition: box-shadow var(--animation-normal) var(--ease-standard); }
|
||||
@media (hover: hover) { .hljs-codeblock:hover { box-shadow: var(--shadow-3); } }
|
||||
.code-copy-btn { opacity: 0; transform: translateY(-5px); transition: opacity var(--animation-fast) var(--ease-standard), transform var(--animation-fast) var(--ease-standard), background var(--animation-fast) var(--ease-standard); }
|
||||
.hljs-codeblock:hover .code-copy-btn { opacity: 1; transform: translateY(0); }
|
||||
|
||||
/* 17. 减少动画偏好支持 */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
|
||||
.card, .btn, a { transition: none !important; }
|
||||
}
|
||||
|
||||
/* 18. 打印样式优化 */
|
||||
@media print {
|
||||
*, *::before, *::after { animation: none !important; transition: none !important; }
|
||||
}
|
||||
/* ========== End of Modern UI Enhancements ========== */
|
||||
Reference in New Issue
Block a user