Initial commit

This commit is contained in:
2026-02-02 22:47:52 +03:00
committed by GitHub
commit f53016aeda
239 changed files with 84360 additions and 0 deletions

483
src/styles/banner.css Normal file
View File

@@ -0,0 +1,483 @@
/*
* Banner 组件样式
* Banner Component Styles
* 包含 Banner 模式下的所有响应式样式和动画效果
*/
/**
* 基础样式
*/
/* 淡入上移动画 */
@keyframes fadeInUp {
from {
opacity: 0;
translate: 0 30px;
}
to {
opacity: 1;
translate: 0 0;
}
}
/* 初始加载中且未开始恢复时,高度归零;退出 Banner 模式时,高度归零 */
html.is-loading:not(.banner-restoring) #banner-wrapper,
html.banner-transitioning #banner-wrapper,
html.banner-hiding #banner-wrapper {
height: 0 !important;
}
/* 退出动画时,强制子组件同步上移,避免主内容区域出现“两段式”位移 */
html.banner-hiding #main-grid {
translate: none !important;
}
html.banner-hiding #top-row {
height: 0 !important;
}
html.banner-hiding #sidebar-sticky {
top: 1rem !important;
}
/* 切换模式时隐藏标题,以便后续触发动画 */
html.banner-transitioning .banner-title,
html.banner-transitioning .banner-subtitle {
opacity: 0 !important;
}
/* 标题样式 */
.banner-title {
text-shadow: 0px 3px 12px rgba(0, 0, 0, 0.36), 0 0 24px color-mix(in srgb, var(--primary), transparent 48%);
font-weight: bold;
opacity: 0;
}
.banner-subtitle {
text-shadow: 0px 3px 6px rgba(0, 0, 0, 0.36), 0 0 12px color-mix(in srgb, var(--primary), transparent 48%);
opacity: 0;
}
/* 标题动画 */
.show-initial-animation .banner-title,
.show-banner-animation .banner-title {
animation: fadeInUp 1s ease-out forwards;
}
.show-initial-animation .banner-subtitle,
.show-banner-animation .banner-subtitle {
animation: fadeInUp 1s ease-out 0.3s both;
}
/* 动画结束后的状态 */
html:not(.is-loading):not(.show-initial-animation):not(.show-banner-animation) .banner-title,
html:not(.is-loading):not(.show-initial-animation):not(.show-banner-animation) .banner-subtitle {
opacity: 1;
}
/* 页面背景平滑过渡Fullscreen 与 Banner 模式切换时) */
body {
transition: background-color 0.6s ease, background-image 0.6s ease;
}
html.is-wallpaper-transitioning body {
transition: background-color 0.6s ease, background-image 0.6s ease !important;
}
/**
*
*/
/* Ken Burns 效果 */
@keyframes ken-burns {
from {
scale: 1.0;
translate: 0 0 0;
}
to {
scale: 1.2;
translate: 0 0 0;
}
}
/* 桌面端 */
@media (min-width: 1280px) {
.banner-text-overlay {
align-items: center !important; /* 垂直居中 */
justify-content: center !important; /* 水平居中 */
padding: 2rem !important;
text-align: center !important; /* 文字居中对齐 */
}
.banner-text-overlay > div {
margin-bottom: 0 !important;
width: 75% !important;
text-align: center !important; /* 确保文字居中 */
}
/* 确保轮播容器有正确的 overflow 设置 */
#banner-carousel {
overflow: hidden !important;
}
/* 图片容器 */
.carousel-item img,
#banner img {
object-position: center center !important; /* 确保图片居中显示 */
transition: transform 1.2s ease-out !important;
}
/* 轮播图片过渡 */
.carousel-item {
transition: opacity 1.2s ease-in-out !important;
}
.carousel-item.ken-burns-enabled {
transform-origin: center center !important; /* 确保缩放从中心开始 */
scale: 1.0;
translate: 0 0 0;
}
.carousel-item.ken-burns-enabled.is-animating {
animation: ken-burns 12s linear forwards !important;
}
.carousel-item:not(.ken-burns-enabled) {
scale: 1.0;
translate: 0 0 0; /* 取消默认缩放 */
}
/* 当前图片缩放效果 */
.carousel-item.opacity-100 {
opacity: 1 !important;
}
/* 非当前图片缩放效果 */
.carousel-item.opacity-0 {
opacity: 0 !important;
}
}
/* 移动端轮播图片 */
@media (max-width: 1279px) {
/* 确保轮播容器有正确的 overflow 设置 */
#banner-carousel {
overflow: hidden !important;
}
/* 图片容器 */
.carousel-item img,
#banner img {
object-position: center center !important; /* 确保图片居中显示 */
transition: transform 1.2s ease-out !important;
}
/* 轮播图片过渡 */
.carousel-item {
transition: opacity 1.2s ease-in-out !important;
}
.carousel-item.ken-burns-enabled {
transform-origin: center center !important; /* 确保缩放从中心开始 */
scale: 1.0;
}
.carousel-item.ken-burns-enabled.is-animating {
animation: ken-burns 12s linear forwards !important;
}
.carousel-item:not(.ken-burns-enabled) {
scale: 1.0; /* 取消默认缩放 */
}
/* 当前图片缩放效果 */
.carousel-item.opacity-100 {
opacity: 1 !important;
}
/* 非当前图片缩放效果 */
.carousel-item.opacity-0 {
opacity: 0 !important;
}
}
/* 移动端 banner 性能 */
@media (max-width: 1279px) {
.banner-container {
/* 启用硬件加速 */
translate: 0 0 0;
will-change: transform, opacity;
/* 渲染性能 */
contain: layout style paint;
/* 减少重绘 */
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
/* 图片 */
.banner-container img {
/* 图片渲染 */
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
/* 防止图片拖拽 */
-webkit-user-drag: none;
-khtml-user-drag: none;
-moz-user-drag: none;
-o-user-drag: none;
/* 触摸 */
pointer-events: none;
}
.banner-text-overlay {
/* 文字渲染 */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
/* 减少重排 */
contain: layout style;
}
.carousel-item.ken-burns-enabled {
/* 硬件加速与缩放维持 */
scale: 1.0;
translate: 0 0 0;
will-change: transform, opacity;
/* 触摸响应 */
touch-action: pan-y;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
.carousel-item:not(.ken-burns-enabled) {
scale: 1.0;
translate: 0 0 0;
will-change: transform, opacity;
/* 触摸响应 */
touch-action: pan-y;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
/* 轮播指示器 */
.carousel-indicators {
position: absolute;
bottom: 20px;
left: 50%;
translate: -50% 0;
display: flex;
gap: 8px;
z-index: 10;
}
.carousel-indicator {
width: 8px;
height: 8px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
transition: all 0.3s ease;
cursor: pointer;
}
.carousel-indicator.active {
background: rgba(255, 255, 255, 0.9);
scale: 1.2;
}
}
/* 移动端暗色模式 */
@media (max-width: 1279px) and (prefers-color-scheme: dark) {
.banner-text-overlay {
background: linear-gradient(
to top,
rgba(0, 0, 0, 0.8) 0%,
rgba(0, 0, 0, 0.4) 50%,
transparent 100%
);
}
}
/* 移动端横屏 */
@media (max-width: 1279px) and (orientation: landscape) {
.banner-text-overlay {
padding: 1rem 1.5rem;
align-items: center !important; /* 垂直居中 */
justify-content: center !important; /* 水平居中 */
text-align: center !important; /* 文字居中对齐 */
}
.banner-title {
font-size: 2.2rem !important; /* 增大字体大小 */
line-height: 1.3;
}
.banner-subtitle {
font-size: 0.9rem;
margin-top: 0.5rem;
}
}
/* 平板 */
@media (min-width: 768px) and (max-width: 1279px) {
/* 横幅文本覆盖层 */
.banner-text-overlay {
align-items: center !important; /* 垂直居中 */
justify-content: center !important; /* 水平居中 */
padding: 2rem !important;
text-align: center !important; /* 文字居中对齐 */
}
/* 文本容器 */
.banner-text-overlay > div {
margin-bottom: 0 !important; /* 移除底部边距,保持居中 */
width: 85% !important;
text-align: center !important; /* 确保文字居中 */
}
/* 标题文本 */
.banner-title {
font-size: 4rem !important;
line-height: 1.1 !important;
margin-bottom: 1rem !important;
}
/* 副标题文本 */
.banner-subtitle {
font-size: 1.5rem !important;
line-height: 1.4 !important;
}
}
/* 中屏手机 */
@media (min-width: 513px) and (max-width: 768px) {
/* 横幅文本覆盖层 */
.banner-text-overlay {
align-items: center !important; /* 垂直居中 */
justify-content: center !important; /* 水平居中 */
padding: 1.5rem !important;
text-align: center !important; /* 文字居中对齐 */
}
/* 文本容器 */
.banner-text-overlay > div {
margin-bottom: 0 !important; /* 移除底部边距,保持居中 */
width: 90% !important;
text-align: center !important; /* 确保文字居中 */
}
/* 标题文本 */
.banner-title {
font-size: 3.8rem !important; /* 增大字体大小 */
line-height: 1.1 !important;
margin-bottom: 0.75rem !important;
}
/* 副标题文本 */
.banner-subtitle {
font-size: 1.125rem !important;
line-height: 1.4 !important;
}
}
/* 小屏手机 */
@media (max-width: 512px) {
/* 横幅文本覆盖层 */
.banner-text-overlay {
align-items: center !important; /* 垂直居中 */
justify-content: center !important; /* 水平居中 */
padding: 1rem !important;
text-align: center !important; /* 文字居中对齐 */
}
/* 文本容器 */
.banner-text-overlay > div {
margin-bottom: 0 !important; /* 移除底部边距,保持居中 */
width: 95% !important; /* 增加文本宽度利用率 */
text-align: center !important; /* 确保文字居中 */
}
/* 标题文本 */
.banner-title {
font-size: 3.2rem !important; /* 增大字体大小 */
line-height: 1.1 !important;
margin-bottom: 0.5rem !important;
}
/* 副标题文本 */
.banner-subtitle {
font-size: 1rem !important;
line-height: 1.3 !important;
}
}
/**
* 波浪
*/
/* 波浪动画 */
@keyframes wave {
0% {
translate: -90px 0 0;
}
100% {
translate: 85px 0 0;
}
}
/* 波浪与背景同步切换 */
#header-waves {
/* 确保波浪容器与页面背景在同一合成层 */
isolation: isolate;
/* 优化渲染性能 - 移除 strict containment 改用 none */
contain: none;
/* 精确对齐 */
margin-bottom: -1px;
}
/* 统一波浪动画 */
#header-waves .parallax use {
animation-name: wave;
animation-duration: 25s;
animation-timing-function: cubic-bezier(0.5, 0.5, 0.45, 0.5);
animation-iteration-count: infinite;
transform: translateZ(0);
will-change: transform;
backface-visibility: hidden;
}
/* 分层动画时序(替代内联 style */
#header-waves .parallax use:nth-child(1) {
animation-duration: 7s;
animation-delay: -2s;
}
#header-waves .parallax use:nth-child(2) {
animation-duration: 10s;
animation-delay: -3s;
}
#header-waves .parallax use:nth-child(3) {
animation-duration: 13s;
animation-delay: -4s;
}
#header-waves .parallax use:nth-child(4) {
animation-duration: 20s;
animation-delay: -5s;
}
#header-waves .waves {
/* 确保 SVG 完整渲染svg 本身即为 .waves */
width: 100%;
height: 100%;
display: block;
/* 确保水波纹完整显示 */
overflow: visible;
z-index: 5;
/* 硬件加速,确保与背景同步渲染 */
transform: translateZ(0);
will-change: transform;
backface-visibility: hidden;
/* 优化渲染性能 - 移除 strict containment 改用 none */
contain: none;
}
/* 波浪填充色主题切换 */
#header-waves .waves use {
/* 确保填充色与页面背景同步更新 */
will-change: fill;
}
/* 主题切换时的额外保护 */
.theme-changing #header-waves,
.theme-changing #header-waves svg,
.theme-changing #header-waves use {
/* 在主题切换期间禁用所有可能的渲染延迟 */
will-change: auto;
transform: translateZ(0);
backface-visibility: hidden;
}
/* 移动端水波纹特殊 */
@media (max-width: 1023px) {
#header-waves {
/* 确保水波纹容器不被裁剪 */
overflow: visible;
z-index: 5;
}
#header-waves .waves {
/* 移动端SVG */
min-height: 60px;
}
}