diff --git a/argontheme.js b/argontheme.js index 5a36622..d968465 100644 --- a/argontheme.js +++ b/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 ========== */ \ No newline at end of file diff --git a/header.php b/header.php index ba93850..f1355b2 100644 --- a/header.php +++ b/header.php @@ -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); ?> diff --git a/modern-enhancements.css b/modern-enhancements.css deleted file mode 100644 index 9669723..0000000 --- a/modern-enhancements.css +++ /dev/null @@ -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; - } -} diff --git a/modern-enhancements.js b/modern-enhancements.js deleted file mode 100644 index ea8b72b..0000000 --- a/modern-enhancements.js +++ /dev/null @@ -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(); - } - -})(); diff --git a/style.css b/style.css index d44f241..19142b9 100644 --- a/style.css +++ b/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 ========== */ \ No newline at end of file