This commit is contained in:
张成
2025-08-25 15:57:54 +08:00
parent 1ad48b234c
commit 3ed48736b6
19 changed files with 4233 additions and 2097 deletions

View File

@@ -1,785 +0,0 @@
/* 动画效果库 - 为项目添加丰富的动画效果 */
/* ===== 基础动画关键帧 ===== */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInLeft {
from {
opacity: 0;
transform: translateX(-30px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes fadeInRight {
from {
opacity: 0;
transform: translateX(30px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInUp {
from {
transform: translateY(100px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes slideInDown {
from {
transform: translateY(-100px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes slideInLeft {
from {
transform: translateX(-100px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideInRight {
from {
transform: translateX(100px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes zoomIn {
from {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes zoomOut {
from {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 1;
}
to {
opacity: 0;
transform: scale(0.3);
}
}
@keyframes bounce {
0%, 20%, 53%, 80%, 100% {
transform: translate3d(0, 0, 0);
}
40%, 43% {
transform: translate3d(0, -30px, 0);
}
70% {
transform: translate3d(0, -15px, 0);
}
90% {
transform: translate3d(0, -4px, 0);
}
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
@keyframes shake {
0%, 100% {
transform: translateX(0);
}
10%, 30%, 50%, 70%, 90% {
transform: translateX(-10px);
}
20%, 40%, 60%, 80% {
transform: translateX(10px);
}
}
@keyframes swing {
20% {
transform: rotate(15deg);
}
40% {
transform: rotate(-10deg);
}
60% {
transform: rotate(5deg);
}
80% {
transform: rotate(-5deg);
}
100% {
transform: rotate(0deg);
}
}
@keyframes rotateIn {
from {
transform: rotate(-200deg);
opacity: 0;
}
to {
transform: rotate(0);
opacity: 1;
}
}
@keyframes flipInX {
from {
transform: perspective(400px) rotate3d(1, 0, 0, 90deg);
opacity: 0;
}
40% {
transform: perspective(400px) rotate3d(1, 0, 0, -20deg);
}
60% {
transform: perspective(400px) rotate3d(1, 0, 0, 10deg);
}
80% {
transform: perspective(400px) rotate3d(1, 0, 0, -5deg);
}
to {
transform: perspective(400px);
opacity: 1;
}
}
@keyframes flipInY {
from {
transform: perspective(400px) rotate3d(0, 1, 0, 90deg);
opacity: 0;
}
40% {
transform: perspective(400px) rotate3d(0, 1, 0, -20deg);
}
60% {
transform: perspective(400px) rotate3d(0, 1, 0, 10deg);
}
80% {
transform: perspective(400px) rotate3d(0, 1, 0, -5deg);
}
to {
transform: perspective(400px);
opacity: 1;
}
}
@keyframes lightSpeedIn {
from {
transform: translate3d(100%, 0, 0) skewX(-30deg);
opacity: 0;
}
60% {
transform: skewX(20deg);
opacity: 1;
}
80% {
transform: skewX(-5deg);
}
to {
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
@keyframes rubberBand {
from {
transform: scale(1);
}
30% {
transform: scaleX(1.25) scaleY(0.75);
}
40% {
transform: scaleX(0.75) scaleY(1.25);
}
50% {
transform: scaleX(1.15) scaleY(0.85);
}
65% {
transform: scaleX(0.95) scaleY(1.05);
}
75% {
transform: scaleX(1.05) scaleY(0.95);
}
to {
transform: scale(1);
}
}
@keyframes wobble {
from {
transform: translate3d(0, 0, 0);
}
15% {
transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
}
30% {
transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
}
45% {
transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
}
60% {
transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
}
75% {
transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
}
to {
transform: translate3d(0, 0, 0);
}
}
@keyframes tada {
from {
transform: scale3d(1, 1, 1);
}
10%, 20% {
transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
}
30%, 50%, 70%, 90% {
transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
}
40%, 60%, 80% {
transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
}
to {
transform: scale3d(1, 1, 1);
}
}
@keyframes heartBeat {
0% {
transform: scale(1);
}
14% {
transform: scale(1.3);
}
28% {
transform: scale(1);
}
42% {
transform: scale(1.3);
}
70% {
transform: scale(1);
}
}
@keyframes hinge {
0% {
transform: rotate(0);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
20%, 60% {
transform: rotate(80deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
40% {
transform: rotate(60deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
80% {
transform: rotate(60deg) translateY(0);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
100% {
transform: translateY(700px);
}
}
@keyframes rollIn {
from {
opacity: 0;
transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
@keyframes rollOut {
from {
opacity: 1;
}
to {
opacity: 0;
transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg);
}
}
/* ===== 动画类 ===== */
.animate {
animation-duration: 1s;
animation-fill-mode: both;
}
.animate.infinite {
animation-iteration-count: infinite;
}
.animate.delay-1s {
animation-delay: 1s;
}
.animate.delay-2s {
animation-delay: 2s;
}
.animate.delay-3s {
animation-delay: 3s;
}
.animate.delay-4s {
animation-delay: 4s;
}
.animate.delay-5s {
animation-delay: 5s;
}
.animate.fast {
animation-duration: 0.5s;
}
.animate.slow {
animation-duration: 2s;
}
.animate.slower {
animation-duration: 3s;
}
/* ===== 淡入动画 ===== */
.fade-in {
animation-name: fadeIn;
}
.fade-in-up {
animation-name: fadeInUp;
}
.fade-in-down {
animation-name: fadeInDown;
}
.fade-in-left {
animation-name: fadeInLeft;
}
.fade-in-right {
animation-name: fadeInRight;
}
/* ===== 滑入动画 ===== */
.slide-in-up {
animation-name: slideInUp;
}
.slide-in-down {
animation-name: slideInDown;
}
.slide-in-left {
animation-name: slideInLeft;
}
.slide-in-right {
animation-name: slideInRight;
}
/* ===== 缩放动画 ===== */
.zoom-in {
animation-name: zoomIn;
}
.zoom-out {
animation-name: zoomOut;
}
/* ===== 特殊效果动画 ===== */
.bounce {
animation-name: bounce;
}
.pulse {
animation-name: pulse;
}
.shake {
animation-name: shake;
}
.swing {
animation-name: swing;
}
.rotate-in {
animation-name: rotateIn;
}
.flip-in-x {
animation-name: flipInX;
}
.flip-in-y {
animation-name: flipInY;
}
.light-speed-in {
animation-name: lightSpeedIn;
}
.rubber-band {
animation-name: rubberBand;
}
.wobble {
animation-name: wobble;
}
.tada {
animation-name: tada;
}
.heart-beat {
animation-name: heartBeat;
}
.hinge {
animation-name: hinge;
}
.roll-in {
animation-name: rollIn;
}
.roll-out {
animation-name: rollOut;
}
/* ===== 悬停动画 ===== */
.hover-lift {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.hover-lift:hover {
transform: translateY(-10px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.hover-scale {
transition: transform 0.3s ease;
}
.hover-scale:hover {
transform: scale(1.05);
}
.hover-rotate {
transition: transform 0.3s ease;
}
.hover-rotate:hover {
transform: rotate(5deg);
}
.hover-glow {
transition: box-shadow 0.3s ease;
}
.hover-glow:hover {
box-shadow: 0 0 20px rgba(52, 152, 219, 0.5);
}
.hover-bounce {
transition: transform 0.3s ease;
}
.hover-bounce:hover {
animation: bounce 0.6s ease;
}
/* ===== 滚动触发动画 ===== */
.scroll-animate {
opacity: 0;
transform: translateY(30px);
transition: all 0.8s ease;
}
.scroll-animate.animate-in {
opacity: 1;
transform: translateY(0);
}
/* ===== 加载动画 ===== */
.loading-spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-dots {
display: inline-block;
}
.loading-dots::after {
content: '';
animation: dots 1.5s steps(5, end) infinite;
}
@keyframes dots {
0%, 20% { content: ''; }
40% { content: '.'; }
60% { content: '..'; }
80%, 100% { content: '...'; }
}
/* ===== 打字机效果 ===== */
.typewriter {
overflow: hidden;
border-right: 2px solid #333;
white-space: nowrap;
animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite;
}
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
@keyframes blink-caret {
from, to { border-color: transparent; }
50% { border-color: #333; }
}
/* ===== 波浪效果 ===== */
.wave {
position: relative;
overflow: hidden;
}
.wave::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
animation: wave 2s infinite;
}
@keyframes wave {
0% { left: -100%; }
100% { left: 100%; }
}
/* ===== 粒子效果 ===== */
.particles {
position: relative;
}
.particle {
position: absolute;
width: 4px;
height: 4px;
background: #3498db;
border-radius: 50%;
animation: particle-float 3s infinite ease-in-out;
}
.particle:nth-child(1) { animation-delay: 0s; }
.particle:nth-child(2) { animation-delay: 0.5s; }
.particle:nth-child(3) { animation-delay: 1s; }
.particle:nth-child(4) { animation-delay: 1.5s; }
.particle:nth-child(5) { animation-delay: 2s; }
@keyframes particle-float {
0%, 100% {
transform: translateY(0) scale(1);
opacity: 1;
}
50% {
transform: translateY(-20px) scale(1.2);
opacity: 0.7;
}
}
/* ===== 3D翻转效果 ===== */
.flip-card {
perspective: 1000px;
height: 200px;
}
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.8s;
transform-style: preserve-3d;
}
.flip-card:hover .flip-card-inner {
transform: rotateY(180deg);
}
.flip-card-front, .flip-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flip-card-back {
transform: rotateY(180deg);
}
/* ===== 渐变背景动画 ===== */
.gradient-bg {
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 400% 400%;
animation: gradient-shift 15s ease infinite;
}
@keyframes gradient-shift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* ===== 霓虹灯效果 ===== */
.neon-text {
color: #fff;
text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #0073e6, 0 0 20px #0073e6, 0 0 25px #0073e6, 0 0 30px #0073e6, 0 0 35px #0073e6;
animation: neon-pulse 1.5s ease-in-out infinite alternate;
}
@keyframes neon-pulse {
from { text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #0073e6, 0 0 20px #0073e6, 0 0 25px #0073e6, 0 0 30px #0073e6, 0 0 35px #0073e6; }
to { text-shadow: 0 0 2px #fff, 0 0 4px #fff, 0 0 6px #0073e6, 0 0 8px #0073e6, 0 0 10px #0073e6, 0 0 12px #0073e6, 0 0 14px #0073e6; }
}
/* ===== 响应式动画 ===== */
@media (prefers-reduced-motion: reduce) {
.animate,
.hover-lift,
.hover-scale,
.hover-rotate,
.hover-glow,
.hover-bounce {
animation: none !important;
transition: none !important;
transform: none !important;
}
}
/* ===== 动画工具类 ===== */
.animate-on-scroll {
opacity: 0;
transform: translateY(50px);
transition: all 0.8s ease;
}
.animate-on-scroll.visible {
opacity: 1;
transform: translateY(0);
}
.animate-stagger > * {
opacity: 0;
transform: translateY(30px);
transition: all 0.6s ease;
}
.animate-stagger.visible > * {
opacity: 1;
transform: translateY(0);
}
.animate-stagger.visible > *:nth-child(1) { transition-delay: 0.1s; }
.animate-stagger.visible > *:nth-child(2) { transition-delay: 0.2s; }
.animate-stagger.visible > *:nth-child(3) { transition-delay: 0.3s; }
.animate-stagger.visible > *:nth-child(4) { transition-delay: 0.4s; }
.animate-stagger.visible > *:nth-child(5) { transition-delay: 0.5s; }
.animate-stagger.visible > *:nth-child(6) { transition-delay: 0.6s; }

View File

@@ -0,0 +1,761 @@
// 动画效果库 - LESS版本
@import './variables.less';
// ===== 动画变量 =====
@animation-duration: @animation-duration-base;
@animation-timing: @animation-timing-base;
@animation-fill-mode: both;
// ===== 基础动画关键帧 =====
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInLeft {
from {
opacity: 0;
transform: translateX(-30px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes fadeInRight {
from {
opacity: 0;
transform: translateX(30px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInUp {
from {
transform: translateY(100px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes slideInDown {
from {
transform: translateY(-100px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes slideInLeft {
from {
transform: translateX(-100px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideInRight {
from {
transform: translateX(100px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes zoomIn {
from {
opacity: 0;
transform: scale(0.3);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes zoomOut {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.3);
}
}
@keyframes bounce {
0%, 20%, 53%, 80%, 100% {
transform: translate3d(0, 0, 0);
}
40%, 43% {
transform: translate3d(0, -30px, 0);
}
70% {
transform: translate3d(0, -15px, 0);
}
90% {
transform: translate3d(0, -4px, 0);
}
}
@keyframes pulse {
from {
transform: scale3d(1, 1, 1);
}
50% {
transform: scale3d(1.05, 1.05, 1.05);
}
to {
transform: scale3d(1, 1, 1);
}
}
@keyframes shake {
0%, 100% {
transform: translate3d(0, 0, 0);
}
10%, 30%, 50%, 70%, 90% {
transform: translate3d(-10px, 0, 0);
}
20%, 40%, 60%, 80% {
transform: translate3d(10px, 0, 0);
}
}
@keyframes swing {
20% {
transform: rotate(15deg);
}
40% {
transform: rotate(-10deg);
}
60% {
transform: rotate(5deg);
}
80% {
transform: rotate(-5deg);
}
100% {
transform: rotate(0deg);
}
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes flip {
0% {
transform: perspective(400px) rotateY(0);
}
40% {
transform: perspective(400px) rotateY(90deg);
}
60% {
transform: perspective(400px) rotateY(180deg);
}
80% {
transform: perspective(400px) rotateY(270deg);
}
100% {
transform: perspective(400px) rotateY(360deg);
}
}
@keyframes lightSpeedIn {
from {
transform: translate3d(100%, 0, 0) skewX(-30deg);
opacity: 0;
}
60% {
transform: skewX(20deg);
opacity: 1;
}
80% {
transform: skewX(-5deg);
opacity: 1;
}
to {
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
@keyframes rubberBand {
from {
transform: scale3d(1, 1, 1);
}
30% {
transform: scale3d(1.25, 0.75, 1);
}
40% {
transform: scale3d(0.75, 1.25, 1);
}
50% {
transform: scale3d(1.15, 0.85, 1);
}
65% {
transform: scale3d(0.95, 1.05, 1);
}
75% {
transform: scale3d(1.05, 0.95, 1);
}
to {
transform: scale3d(1, 1, 1);
}
}
@keyframes wobble {
0% {
transform: translate3d(0, 0, 0);
}
15% {
transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
}
30% {
transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
}
45% {
transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
}
60% {
transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
}
75% {
transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
}
100% {
transform: translate3d(0, 0, 0);
}
}
@keyframes tada {
0% {
transform: scale3d(1, 1, 1);
}
10%, 20% {
transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg);
}
30%, 50%, 70%, 90% {
transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg);
}
40%, 60%, 80% {
transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg);
}
100% {
transform: scale3d(1, 1, 1);
}
}
@keyframes heartBeat {
0% {
transform: scale(1);
}
14% {
transform: scale(1.3);
}
28% {
transform: scale(1);
}
42% {
transform: scale(1.3);
}
70% {
transform: scale(1);
}
}
@keyframes hinge {
0% {
transform: rotate(0);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
20%, 60% {
transform: rotate(80deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
}
40%, 80% {
transform: rotate(60deg);
transform-origin: top left;
animation-timing-function: ease-in-out;
opacity: 1;
}
100% {
transform: translate3d(0, 700px, 0);
opacity: 0;
}
}
@keyframes roll {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
// ===== 基础动画类 =====
.animate {
animation-duration: @animation-duration;
animation-fill-mode: @animation-fill-mode;
animation-timing-function: @animation-timing;
}
// 淡入动画
.fade-in { animation-name: fadeIn; }
.fade-in-up { animation-name: fadeInUp; }
.fade-in-down { animation-name: fadeInDown; }
.fade-in-left { animation-name: fadeInLeft; }
.fade-in-right { animation-name: fadeInRight; }
// 滑入动画
.slide-in-up { animation-name: slideInUp; }
.slide-in-down { animation-name: slideInDown; }
.slide-in-left { animation-name: slideInLeft; }
.slide-in-right { animation-name: slideInRight; }
// 缩放动画
.zoom-in { animation-name: zoomIn; }
.zoom-out { animation-name: zoomOut; }
// 特殊动画
.bounce { animation-name: bounce; }
.pulse { animation-name: pulse; }
.shake { animation-name: shake; }
.swing { animation-name: swing; }
.rotate { animation-name: rotate; }
.flip { animation-name: flip; }
.light-speed-in { animation-name: lightSpeedIn; }
.rubber-band { animation-name: rubberBand; }
.wobble { animation-name: wobble; }
.tada { animation-name: tada; }
.heart-beat { animation-name: heartBeat; }
.hinge { animation-name: hinge; }
.roll { animation-name: roll; }
// ===== 动画时长 =====
.duration-0_5s { animation-duration: 0.5s; }
.duration-1s { animation-duration: 1s; }
.duration-1_5s { animation-duration: 1.5s; }
.duration-2s { animation-duration: 2s; }
.duration-3s { animation-duration: 3s; }
// ===== 动画延迟 =====
.delay-0_5s { animation-delay: 0.5s; }
.delay-1s { animation-delay: 1s; }
.delay-1_5s { animation-delay: 1.5s; }
.delay-2s { animation-delay: 2s; }
.delay-3s { animation-delay: 3s; }
// ===== 动画重复 =====
.infinite { animation-iteration-count: infinite; }
.repeat-2 { animation-iteration-count: 2; }
.repeat-3 { animation-iteration-count: 3; }
// ===== 悬停动画效果 =====
.hover-lift {
transition: transform 0.3s ease, box-shadow 0.3s ease;
&:hover {
transform: translateY(-5px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}
}
.hover-scale {
transition: transform 0.3s ease;
&:hover {
transform: scale(1.05);
}
}
.hover-glow {
transition: box-shadow 0.3s ease;
&:hover {
box-shadow: 0 0 20px rgba(0, 123, 255, 0.5);
}
}
.hover-rotate {
transition: transform 0.3s ease;
&:hover {
transform: rotate(5deg);
}
}
.hover-bounce {
transition: transform 0.3s ease;
&:hover {
animation: bounce 0.6s ease;
}
}
// ===== 滚动触发动画 =====
.scroll-animate {
opacity: 0;
transform: translateY(30px);
transition: all 0.8s ease;
&.animate-in {
opacity: 1;
transform: translateY(0);
}
}
// ===== 交错动画 =====
.animate-stagger {
> * {
opacity: 0;
transform: translateY(20px);
transition: all 0.6s ease;
&:nth-child(1) { transition-delay: 0.1s; }
&:nth-child(2) { transition-delay: 0.2s; }
&:nth-child(3) { transition-delay: 0.3s; }
&:nth-child(4) { transition-delay: 0.4s; }
&:nth-child(5) { transition-delay: 0.5s; }
&:nth-child(6) { transition-delay: 0.6s; }
&.animate-in {
opacity: 1;
transform: translateY(0);
}
}
}
// ===== 加载指示器 =====
.loading-spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
// ===== 打字机效果 =====
.typewriter {
overflow: hidden;
border-right: 2px solid #000;
white-space: nowrap;
animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite;
}
@keyframes typing {
from { width: 0; }
to { width: 100%; }
}
@keyframes blink-caret {
from, to { border-color: transparent; }
50% { border-color: #000; }
}
// ===== 波浪效果 =====
.wave {
position: relative;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.3) 50%, transparent 70%);
animation: wave 2s infinite;
}
}
@keyframes wave {
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}
// ===== 粒子效果 =====
.particles {
position: relative;
overflow: hidden;
&::before,
&::after {
content: '';
position: absolute;
width: 4px;
height: 4px;
background: rgba(255, 255, 255, 0.8);
border-radius: 50%;
animation: float 6s infinite;
}
&::before {
left: 20%;
animation-delay: 0s;
}
&::after {
right: 20%;
animation-delay: 3s;
}
}
@keyframes float {
0%, 100% { transform: translateY(0px) rotate(0deg); opacity: 1; }
50% { transform: translateY(-20px) rotate(180deg); opacity: 0.5; }
}
// ===== 3D翻转卡片 =====
.flip-card {
perspective: 1000px;
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.6s;
transform-style: preserve-3d;
&:hover {
transform: rotateY(180deg);
}
}
.flip-card-front,
.flip-card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
}
.flip-card-back {
transform: rotateY(180deg);
}
}
// ===== 渐变背景动画 =====
.gradient-bg {
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 400% 400%;
animation: gradient 15s ease infinite;
}
@keyframes gradient {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
// ===== 霓虹文字效果 =====
.neon-text {
color: #fff;
text-shadow:
0 0 5px #fff,
0 0 10px #fff,
0 0 15px #0073e6,
0 0 20px #0073e6,
0 0 25px #0073e6,
0 0 30px #0073e6,
0 0 35px #0073e6;
animation: neon-pulse 1.5s ease-in-out infinite alternate;
}
@keyframes neon-pulse {
from { text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #0073e6, 0 0 20px #0073e6, 0 0 25px #0073e6, 0 0 30px #0073e6, 0 0 35px #0073e6; }
to { text-shadow: 0 0 2px #fff, 0 0 4px #fff, 0 0 6px #0073e6, 0 0 8px #0073e6, 0 0 10px #0073e6, 0 0 12px #0073e6, 0 0 14px #0073e6; }
}
// ===== 滚动进度条 =====
.scroll-progress-bar {
position: fixed;
top: 0;
left: 0;
width: 0%;
height: 3px;
background: linear-gradient(90deg, #0073e6, #00d4ff);
z-index: 9999;
transition: width 0.1s ease;
}
// ===== 视差滚动元素 =====
.parallax {
position: relative;
overflow: hidden;
.parallax-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 120%;
background-size: cover;
background-position: center;
transform: translateZ(0);
will-change: transform;
}
}
// ===== 浮动粒子 =====
.floating-particles {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
pointer-events: none;
z-index: 1;
.floating-particle {
position: absolute;
width: 4px;
height: 4px;
background: rgba(255, 255, 255, 0.6);
border-radius: 50%;
animation: float-particle 8s infinite linear;
&:nth-child(1) { left: 10%; animation-delay: 0s; animation-duration: 8s; }
&:nth-child(2) { left: 20%; animation-delay: 1s; animation-duration: 10s; }
&:nth-child(3) { left: 30%; animation-delay: 2s; animation-duration: 12s; }
&:nth-child(4) { left: 40%; animation-delay: 3s; animation-duration: 9s; }
&:nth-child(5) { left: 50%; animation-delay: 4s; animation-duration: 11s; }
&:nth-child(6) { left: 60%; animation-delay: 5s; animation-duration: 7s; }
&:nth-child(7) { left: 70%; animation-delay: 6s; animation-duration: 13s; }
&:nth-child(8) { left: 80%; animation-delay: 7s; animation-duration: 8s; }
&:nth-child(9) { left: 90%; animation-delay: 8s; animation-duration: 10s; }
&:nth-child(10) { left: 95%; animation-delay: 9s; animation-duration: 12s; }
}
}
@keyframes float-particle {
0% {
transform: translateY(100vh) scale(0);
opacity: 0;
}
10% {
opacity: 1;
}
90% {
opacity: 1;
}
100% {
transform: translateY(-100px) scale(1);
opacity: 0;
}
}
// ===== 文字发光效果 =====
.text-glow {
text-shadow:
0 0 5px currentColor,
0 0 10px currentColor,
0 0 15px currentColor,
0 0 20px currentColor;
animation: text-glow-pulse 2s ease-in-out infinite alternate;
}
@keyframes text-glow-pulse {
from { text-shadow: 0 0 5px currentColor, 0 0 10px currentColor, 0 0 15px currentColor, 0 0 20px currentColor; }
to { text-shadow: 0 0 10px currentColor, 0 0 20px currentColor, 0 0 30px currentColor, 0 0 40px currentColor; }
}
// ===== 响应式动画考虑 =====
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
// ===== 移动端动画优化 =====
@media (max-width: 768px) {
.floating-particles {
display: none; // 移动端隐藏浮动粒子以提升性能
}
.animate {
animation-duration: 0.8s; // 移动端减少动画时长
}
.scroll-animate {
transform: translateY(20px); // 移动端减少移动距离
}
}
// ===== 性能优化 =====
.animate,
.hover-lift,
.hover-scale,
.hover-glow,
.hover-rotate,
.hover-bounce {
will-change: transform, opacity;
transform: translate3d(0, 0, 0); // 启用硬件加速
}
// ===== 动画工具类 =====
.animation-paused { animation-play-state: paused; }
.animation-running { animation-play-state: running; }
.animation-reverse { animation-direction: reverse; }
.animation-alternate { animation-direction: alternate; }
.animation-alternate-reverse { animation-direction: alternate-reverse; }

View File

@@ -1,39 +0,0 @@
.scrollToContentWrapper {
height: 6em;
text-align: center;
z-index: 5000;
}
.scrollToContentWrapper>a.scrollToContent {
position: relative;
display: inline-block;
margin-top: -3em;
background: lightyellow;
width: 4.8em;
height: 4.8em;
line-height: 5.6em;
border: 1px solid #eee;
border-radius: 50%;
background-color: #fff;
text-align: center;
cursor: pointer;
text-decoration: none;
color: #000;
}
.scrollToContentWrapper>a.scrollToContent:hover {
background-color: #000 !important;
border-color: #111;
text-decoration: none;
}
.scrollToContentWrapper>a.scrollToContent:hover img {
-webkit-filter: invert(100%);
filter: invert(100%);
}
.scrollToContentWrapper>a.scrollToContent>img {
height: 1.0em;
}

View File

@@ -0,0 +1,40 @@
// 通用样式 - LESS版本
@import './variables.less';
.scrollToContentWrapper {
height: 6em;
text-align: center;
z-index: 5000;
> a.scrollToContent {
position: relative;
display: inline-block;
margin-top: -3em;
background: lightyellow;
width: 4.8em;
height: 4.8em;
line-height: 5.6em;
border: 1px solid #eee;
border-radius: 50%;
background-color: #fff;
text-align: center;
cursor: pointer;
text-decoration: none;
color: #000;
&:hover {
background-color: #000 !important;
border-color: #111;
text-decoration: none;
img {
-webkit-filter: invert(100%);
filter: invert(100%);
}
}
> img {
height: 1.0em;
}
}
}

View File

@@ -0,0 +1,933 @@
// 通用移动端适配样式 - 适用于所有页面 - LESS版本
@import './variables.less';
// ===== 移动端断点变量 =====
// 使用全局变量文件中的断点
// ===== 移动端基础适配 =====
@media (max-width: @mobile-breakpoint) {
// 页面横幅移动端适配
.page-banner {
padding: 60px 0 40px !important;
}
.banner-title {
font-size: 2.5rem !important;
line-height: 1.2 !important;
}
.banner-subtitle {
font-size: 1.2rem !important;
line-height: 1.4 !important;
}
// 容器移动端适配
.container {
padding: 0 15px !important;
}
// 标题移动端适配
.section-title {
font-size: 2rem !important;
line-height: 1.3 !important;
}
.section-subtitle {
font-size: 1.1rem !important;
line-height: 1.5 !important;
}
// 网格布局移动端适配
.grid,
.advantages-grid,
.areas-grid,
.services-grid,
.team-grid,
.contact-grid,
.tech-grid {
grid-template-columns: 1fr !important;
gap: 20px !important;
}
// 卡片移动端适配
.card,
.advantage-card,
.area-card,
.service-item,
.team-member,
.contact-card,
.tech-layer {
padding: 25px 20px !important;
margin-bottom: 20px !important;
}
// 内容区域移动端适配
.content-section {
margin-bottom: 40px !important;
}
.section-text {
font-size: 1rem !important;
line-height: 1.6 !important;
}
// 图标移动端适配
.icon,
.service-icon,
.advantage-icon,
.area-icon,
.contact-icon {
font-size: 2.5rem !important;
margin-bottom: 15px !important;
}
// 列表移动端适配
.feature-list,
.advantage-features,
.area-features {
padding-left: 20px !important;
li {
margin-bottom: 8px !important;
font-size: 0.95rem !important;
}
}
// 时间线移动端适配
.timeline {
padding-left: 20px !important;
.timeline-item {
margin-bottom: 30px !important;
padding-left: 20px !important;
.timeline-date {
font-size: 0.9rem !important;
margin-bottom: 8px !important;
}
.timeline-title {
font-size: 1.1rem !important;
margin-bottom: 10px !important;
}
.timeline-content {
font-size: 0.95rem !important;
line-height: 1.5 !important;
}
}
}
// 统计数字移动端适配
.stats-section {
padding: 40px 0 !important;
.stats-grid {
grid-template-columns: repeat(2, 1fr) !important;
gap: 20px !important;
}
.stat-item {
text-align: center !important;
padding: 20px 15px !important;
.stat-number {
font-size: 2rem !important;
margin-bottom: 10px !important;
}
.stat-label {
font-size: 0.9rem !important;
}
}
}
// 团队介绍移动端适配
.team-section {
.team-grid {
grid-template-columns: 1fr !important;
gap: 25px !important;
}
.team-member {
text-align: center !important;
.member-photo {
width: 120px !important;
height: 120px !important;
margin: 0 auto 15px !important;
}
.member-name {
font-size: 1.2rem !important;
margin-bottom: 8px !important;
}
.member-position {
font-size: 0.9rem !important;
margin-bottom: 10px !important;
}
.member-description {
font-size: 0.9rem !important;
line-height: 1.5 !important;
}
}
}
// 联系信息移动端适配
.contact-section {
.contact-grid {
grid-template-columns: 1fr !important;
gap: 25px !important;
}
.contact-info {
text-align: center !important;
.contact-icon {
font-size: 2rem !important;
margin-bottom: 15px !important;
}
.contact-title {
font-size: 1.1rem !important;
margin-bottom: 8px !important;
}
.contact-detail {
font-size: 0.95rem !important;
line-height: 1.5 !important;
}
}
}
// 技术栈移动端适配
.tech-section {
.tech-grid {
grid-template-columns: repeat(2, 1fr) !important;
gap: 15px !important;
}
.tech-layer {
padding: 20px 15px !important;
text-align: center !important;
.tech-icon {
font-size: 2rem !important;
margin-bottom: 10px !important;
}
.tech-name {
font-size: 0.9rem !important;
}
}
}
// 解决方案移动端适配
.solutions-section {
.solution-item {
margin-bottom: 30px !important;
padding: 20px !important;
.solution-icon {
font-size: 2.5rem !important;
margin-bottom: 15px !important;
text-align: center !important;
}
.solution-title {
font-size: 1.3rem !important;
margin-bottom: 12px !important;
text-align: center !important;
}
.solution-description {
font-size: 0.95rem !important;
line-height: 1.6 !important;
text-align: center !important;
}
}
}
// 优势特点移动端适配
.advantages-section {
.advantage-item {
margin-bottom: 25px !important;
padding: 20px !important;
text-align: center !important;
.advantage-icon {
font-size: 2.5rem !important;
margin-bottom: 15px !important;
}
.advantage-title {
font-size: 1.2rem !important;
margin-bottom: 10px !important;
}
.advantage-description {
font-size: 0.9rem !important;
line-height: 1.5 !important;
}
}
}
// 服务领域移动端适配
.areas-section {
.area-item {
margin-bottom: 25px !important;
padding: 20px !important;
text-align: center !important;
.area-icon {
font-size: 2.5rem !important;
margin-bottom: 15px !important;
}
.area-title {
font-size: 1.2rem !important;
margin-bottom: 10px !important;
}
.area-description {
font-size: 0.9rem !important;
line-height: 1.5 !important;
}
.area-features {
margin-top: 15px !important;
text-align: left !important;
}
}
}
// 按钮移动端适配
.btn,
.button {
padding: 12px 24px !important;
font-size: 16px !important;
min-height: 44px !important; // 触摸友好尺寸
width: 100% !important; // 移动端全宽按钮
&.btn-large {
padding: 15px 30px !important;
font-size: 18px !important;
}
&.btn-small {
padding: 8px 16px !important;
font-size: 14px !important;
}
&.btn-block {
display: block !important;
width: 100% !important;
}
}
// 表单移动端适配
.form-section {
.form-group {
margin-bottom: 20px !important;
label {
display: block !important;
margin-bottom: 8px !important;
font-weight: 500 !important;
font-size: 0.95rem !important;
}
input,
textarea,
select {
width: 100% !important;
padding: 12px !important;
font-size: 16px !important; // 防止iOS缩放
border: 1px solid #ddd !important;
border-radius: 4px !important;
min-height: 44px !important; // 触摸友好尺寸
&:focus {
outline: none !important;
border-color: #3498db !important;
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2) !important;
}
}
textarea {
min-height: 100px !important;
resize: vertical !important;
}
.form-help {
font-size: 0.85rem !important;
color: #666 !important;
margin-top: 5px !important;
}
}
.form-actions {
text-align: center !important;
margin-top: 30px !important;
.btn {
margin: 0 5px 10px !important;
}
}
}
// 图片移动端适配
.image-section {
img {
max-width: 100% !important;
height: auto !important;
border-radius: 8px !important;
}
.image-caption {
font-size: 0.9rem !important;
color: #666 !important;
text-align: center !important;
margin-top: 10px !important;
}
}
// 视频移动端适配
.video-section {
.video-container {
position: relative !important;
width: 100% !important;
height: 0 !important;
padding-bottom: 56.25% !important; // 16:9 比例
iframe,
video {
position: absolute !important;
top: 0 !important;
left: 0 !important;
width: 100% !important;
height: 100% !important;
border-radius: 8px !important;
}
}
}
// 表格移动端适配
.table-section {
.table-responsive {
overflow-x: auto !important;
-webkit-overflow-scrolling: touch !important;
table {
min-width: 600px !important;
font-size: 0.9rem !important;
th,
td {
padding: 8px 12px !important;
white-space: nowrap !important;
}
}
}
}
// 分页移动端适配
.pagination {
display: flex !important;
justify-content: center !important;
flex-wrap: wrap !important;
gap: 5px !important;
margin: 30px 0 !important;
.page-item {
.page-link {
padding: 8px 12px !important;
font-size: 14px !important;
min-width: 40px !important;
text-align: center !important;
border-radius: 4px !important;
}
}
}
// 面包屑移动端适配
.breadcrumb {
padding: 10px 0 !important;
font-size: 0.9rem !important;
.breadcrumb-item {
margin-right: 8px !important;
&:not(:last-child)::after {
content: '>' !important;
margin-left: 8px !important;
color: #999 !important;
}
}
}
// 标签移动端适配
.tags {
display: flex !important;
flex-wrap: wrap !important;
gap: 8px !important;
margin: 15px 0 !important;
.tag {
padding: 4px 8px !important;
font-size: 0.8rem !important;
border-radius: 12px !important;
background: #f0f0f0 !important;
color: #333 !important;
}
}
// 警告框移动端适配
.alert {
padding: 15px !important;
margin: 20px 0 !important;
border-radius: 4px !important;
font-size: 0.95rem !important;
&.alert-success {
background: #d4edda !important;
border: 1px solid #c3e6cb !important;
color: #155724 !important;
}
&.alert-warning {
background: #fff3cd !important;
border: 1px solid #ffeaa7 !important;
color: #856404 !important;
}
&.alert-danger {
background: #f8d7da !important;
border: 1px solid #f5c6cb !important;
color: #721c24 !important;
}
&.alert-info {
background: #d1ecf1 !important;
border: 1px solid #bee5eb !important;
color: #0c5460 !important;
}
}
// 进度条移动端适配
.progress {
height: 20px !important;
margin: 15px 0 !important;
border-radius: 10px !important;
overflow: hidden !important;
.progress-bar {
height: 100% !important;
border-radius: 10px !important;
font-size: 0.8rem !important;
line-height: 20px !important;
}
}
// 模态框移动端适配
.modal {
.modal-dialog {
margin: 10px !important;
max-width: calc(100% - 20px) !important;
}
.modal-content {
border-radius: 8px !important;
}
.modal-header {
padding: 15px 20px !important;
.modal-title {
font-size: 1.2rem !important;
}
}
.modal-body {
padding: 20px !important;
font-size: 0.95rem !important;
}
.modal-footer {
padding: 15px 20px !important;
.btn {
margin: 0 5px !important;
}
}
}
// 工具提示移动端适配
.tooltip {
font-size: 0.85rem !important;
max-width: 200px !important;
}
// 弹出框移动端适配
.popover {
max-width: 250px !important;
font-size: 0.9rem !important;
.popover-header {
font-size: 1rem !important;
padding: 10px 15px !important;
}
.popover-body {
padding: 10px 15px !important;
}
}
// 手风琴移动端适配
.accordion {
.accordion-item {
margin-bottom: 10px !important;
border-radius: 8px !important;
overflow: hidden !important;
.accordion-header {
.accordion-button {
padding: 15px 20px !important;
font-size: 1rem !important;
&:not(.collapsed) {
background-color: #f8f9fa !important;
}
}
}
.accordion-body {
padding: 15px 20px !important;
font-size: 0.95rem !important;
line-height: 1.6 !important;
}
}
}
// 标签页移动端适配
.nav-tabs {
flex-wrap: wrap !important;
.nav-item {
margin-bottom: 5px !important;
.nav-link {
padding: 8px 12px !important;
font-size: 0.9rem !important;
border-radius: 4px !important;
&.active {
background-color: #007bff !important;
border-color: #007bff !important;
color: white !important;
}
}
}
}
// 导航栏移动端适配
.navbar {
.navbar-brand {
font-size: 1.2rem !important;
}
.navbar-nav {
.nav-link {
padding: 10px 15px !important;
font-size: 0.95rem !important;
border-bottom: 1px solid #eee !important;
&:hover {
background-color: #f8f9fa !important;
}
}
}
}
// 侧边栏移动端适配
.sidebar {
position: fixed !important;
top: 0 !important;
left: -100% !important;
width: 80% !important;
height: 100vh !important;
background: white !important;
z-index: 1000 !important;
transition: left 0.3s ease !important;
overflow-y: auto !important;
&.active {
left: 0 !important;
}
.sidebar-header {
padding: 20px !important;
border-bottom: 1px solid #eee !important;
.close-sidebar {
float: right !important;
background: none !important;
border: none !important;
font-size: 1.5rem !important;
cursor: pointer !important;
}
}
.sidebar-body {
padding: 20px !important;
}
}
// 页脚移动端适配
.footer {
padding: 40px 0 20px !important;
text-align: center !important;
.footer-content {
margin-bottom: 30px !important;
.footer-section {
margin-bottom: 25px !important;
.footer-title {
font-size: 1.1rem !important;
margin-bottom: 15px !important;
}
.footer-links {
list-style: none !important;
padding: 0 !important;
li {
margin-bottom: 8px !important;
a {
color: #666 !important;
text-decoration: none !important;
font-size: 0.9rem !important;
&:hover {
color: #333 !important;
}
}
}
}
}
}
.footer-bottom {
border-top: 1px solid #eee !important;
padding-top: 20px !important;
font-size: 0.85rem !important;
color: #999 !important;
}
}
}
// ===== 平板端适配 =====
@media (min-width: @mobile-breakpoint + 1) and (max-width: @tablet-breakpoint) {
.container {
padding: 0 30px !important;
}
.grid,
.advantages-grid,
.areas-grid,
.services-grid,
.team-grid,
.contact-grid,
.tech-grid {
grid-template-columns: repeat(2, 1fr) !important;
gap: 25px !important;
}
.stats-grid {
grid-template-columns: repeat(4, 1fr) !important;
}
.tech-grid {
grid-template-columns: repeat(3, 1fr) !important;
}
}
// ===== 小屏幕移动端适配 =====
@media (max-width: @small-mobile) {
.container {
padding: 0 10px !important;
}
.banner-title {
font-size: 2rem !important;
}
.banner-subtitle {
font-size: 1rem !important;
}
.section-title {
font-size: 1.8rem !important;
}
.section-subtitle {
font-size: 1rem !important;
}
.stats-grid {
grid-template-columns: 1fr !important;
}
.card,
.advantage-card,
.area-card,
.service-item,
.team-member,
.contact-card,
.tech-layer {
padding: 20px 15px !important;
}
}
// ===== 超小屏幕移动端适配 =====
@media (max-width: @xs-mobile) {
.container {
padding: 0 8px !important;
}
.banner-title {
font-size: 1.8rem !important;
}
.banner-subtitle {
font-size: 0.9rem !important;
}
.section-title {
font-size: 1.6rem !important;
}
.section-subtitle {
font-size: 0.9rem !important;
}
.card,
.advantage-card,
.area-card,
.service-item,
.team-member,
.contact-card,
.tech-layer {
padding: 15px 12px !important;
}
.btn,
.button {
padding: 8px 16px !important;
font-size: 14px !important;
}
}
// ===== 触摸设备优化 =====
@media (hover: none) and (pointer: coarse) {
// 触摸设备禁用悬停效果
.btn:hover,
.button:hover,
.card:hover,
.advantage-card:hover,
.area-card:hover,
.service-item:hover,
.team-member:hover,
.contact-card:hover,
.tech-layer:hover {
transform: none !important;
box-shadow: none !important;
}
// 触摸设备增加触摸反馈
.btn,
.button,
.card,
.advantage-card,
.area-card,
.service-item,
.team-member,
.contact-card,
.tech-layer {
-webkit-tap-highlight-color: rgba(52, 152, 219, 0.3) !important;
&:active {
transform: scale(0.98) !important;
transition: transform 0.1s ease !important;
}
}
}
// ===== 高分辨率屏幕适配 =====
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
.icon,
.service-icon,
.advantage-icon,
.area-icon,
.contact-icon {
image-rendering: -webkit-optimize-contrast !important;
image-rendering: crisp-edges !important;
}
}
// ===== 横屏模式适配 =====
@media (orientation: landscape) and (max-height: 500px) {
.page-banner {
padding: 30px 0 20px !important;
}
.banner-title {
font-size: 2rem !important;
margin-bottom: 15px !important;
}
.banner-subtitle {
font-size: 1rem !important;
margin-bottom: 20px !important;
}
.section {
padding: 30px 0 !important;
}
}
// ===== 打印样式 =====
@media print {
.mobile-nav,
.sidebar,
.modal,
.tooltip,
.popover {
display: none !important;
}
.container {
padding: 0 !important;
}
.section {
padding: 20px 0 !important;
page-break-inside: avoid !important;
}
.card,
.advantage-card,
.area-card,
.service-item,
.team-member,
.contact-card,
.tech-layer {
page-break-inside: avoid !important;
margin-bottom: 15px !important;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,251 @@
/*PAGE*/
/* 导入全局变量 */
@import './variables.less';
/* 使用 LESS 变量定义响应式断点 */
@breakpoint-xs: 380px;
@breakpoint-sm: 480px;
@breakpoint-md: 620px;
@breakpoint-lg: 768px;
@breakpoint-xl: 992px;
@breakpoint-xxl: 1200px;
@breakpoint-xxxl: 1500px;
@breakpoint-xxxxl: 1600px;
/* 间距变量 */
@spacing-xs: 0.5em;
@spacing-sm: 1em;
@spacing-md: 1.5em;
@spacing-lg: 2em;
@spacing-xl: 3em;
@spacing-xxl: 4em;
@spacing-xxxl: 5em;
@spacing-xxxxl: 7em;
/* 字体大小变量 */
@font-size-xs: 0.9em;
@font-size-sm: 1.2em;
@font-size-md: 1.5em;
@font-size-lg: 2.5em;
@font-size-xl: 3em;
/* 布局变量 */
@sidebar-width: 25%;
@content-width: 75%;
@content-padding: 4em;
@sidebar-padding: 5em;
.contentPage {
position: relative;
width: 100%;
vertical-align: top;
margin: 0 auto;
padding-top: @spacing-xxxxl;
min-height: 100vh;
/* 容器查询支持 */
container-type: inline-size;
container-name: content-page;
}
/* CONTENT TABLES */
.contentTableLeft {
width: @sidebar-width;
padding-left: @sidebar-padding;
padding-top: @spacing-xl;
vertical-align: top;
}
.contentTableRight {
width: @content-width;
padding-top: 3.5em;
padding-left: @content-padding;
padding-right: @content-padding;
vertical-align: top;
}
/* 使用容器查询替代媒体查询 */
@container content-page (max-width: @breakpoint-xxxxl) {
.contentTableRight {
padding-right: 8em;
}
}
@container content-page (max-width: @breakpoint-xxxl) {
.contentTableRight {
padding-right: 6em;
}
.contentPage .contentPageBanner .bannerBox .bannerBoxTitle {
font-size: @font-size-xl;
}
}
@container content-page (max-width: @breakpoint-xxl) {
.contentPage .contentPageBanner .bannerBox .bannerBoxTitle {
font-size: @font-size-lg;
}
.contentPage .contentPageBanner .bannerBox .bread {
width: 75%;
}
.contentTableLeft {
padding-left: @spacing-xl;
padding-top: @spacing-xl;
}
.contentTableRight {
padding-left: @spacing-xl;
padding-right: @spacing-xl;
}
}
@container content-page (max-width: @breakpoint-xl) {
.contentPage .contentPageBanner .bannerBox .bannerBoxTitle {
font-size: @font-size-md;
}
.contentPage .contentPageBanner .bannerBox .bread {
width: 85%;
}
.contentTableLeft {
padding-left: @spacing-lg;
padding-top: @spacing-lg;
}
.contentTableRight {
padding-left: @spacing-lg;
padding-right: @spacing-lg;
}
}
@container content-page (max-width: @breakpoint-lg) {
.contentPage .contentPageBanner .bannerBox .bannerBoxTitle {
font-size: @font-size-sm;
}
.contentPage .contentPageBanner .bannerBox .bread {
width: 90%;
}
.contentTableLeft {
padding-left: @spacing-md;
padding-top: @spacing-md;
}
.contentTableRight {
padding-left: @spacing-md;
padding-right: @spacing-md;
}
}
@container content-page (max-width: @breakpoint-md) {
.contentPage .contentPageBanner .bannerBox .bannerBoxTitle {
font-size: @font-size-xs;
}
.contentPage .contentPageBanner .bannerBox .bread {
width: 95%;
}
.contentTableLeft {
padding-left: @spacing-sm;
padding-top: @spacing-sm;
}
.contentTableRight {
padding-left: @spacing-sm;
padding-right: @spacing-sm;
}
}
@container content-page (max-width: @breakpoint-sm) {
.contentPage .contentPageBanner .bannerBox .bannerBoxTitle {
font-size: @font-size-xs;
}
.contentPage .contentPageBanner .bannerBox .bread {
width: 100%;
}
.contentTableLeft {
padding-left: @spacing-xs;
padding-top: @spacing-xs;
}
.contentTableRight {
padding-left: @spacing-xs;
padding-right: @spacing-xs;
}
}
@container content-page (max-width: @breakpoint-xs) {
.contentPage .contentPageBanner .bannerBox .bannerBoxTitle {
font-size: @font-size-xs;
}
.contentPage .contentPageBanner .bannerBox .bread {
width: 100%;
}
.contentTableLeft {
padding-left: @spacing-xs;
padding-top: @spacing-xs;
}
.contentTableRight {
padding-left: @spacing-xs;
padding-right: @spacing-xs;
}
}
/* 响应式布局调整 */
@media (max-width: @breakpoint-lg) {
.contentPage {
padding-top: @spacing-xxl;
}
.contentTableLeft,
.contentTableRight {
width: 100%;
display: block;
}
.contentTableLeft {
padding-bottom: @spacing-lg;
}
}
@media (max-width: @breakpoint-md) {
.contentPage {
padding-top: @spacing-xl;
}
.contentTableLeft {
padding-bottom: @spacing-md;
}
}
@media (max-width: @breakpoint-sm) {
.contentPage {
padding-top: @spacing-lg;
}
.contentTableLeft {
padding-bottom: @spacing-sm;
}
}
@media (max-width: @breakpoint-xs) {
.contentPage {
padding-top: @spacing-md;
}
.contentTableLeft {
padding-bottom: @spacing-xs;
}
}

View File

@@ -0,0 +1,602 @@
// 移动端响应式适配样式 - LESS版本
@import './variables.less';
// ===== 移动端断点变量 =====
// 使用全局变量文件中的断点
// ===== 移动端断点 =====
@media (max-width: @mobile-breakpoint) {
// 头部导航移动端适配
.header {
padding: 10px 0;
.content {
padding: 0 15px;
}
}
// 桌面端导航隐藏
.desktop {
display: none !important;
}
// 移动端导航显示
.mobile {
display: flex !important;
}
// 移动端导航样式
.mobile-nav {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.logoCell {
.logo {
height: 40px;
width: auto;
}
}
.mobileIconsCell {
cursor: pointer;
img {
width: 24px;
height: 24px;
}
}
// 移动端菜单样式
.headerMobileMenu {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background: rgba(0, 0, 0, 0.9);
z-index: 1000;
display: none;
overflow-y: auto;
&.active {
display: block;
}
.menuContent {
padding: 80px 20px 20px;
color: white;
ul {
list-style: none;
padding: 0;
margin: 0;
}
li {
margin: 15px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
padding-bottom: 15px;
}
a {
color: white;
text-decoration: none;
font-size: 18px;
display: block;
padding: 10px 0;
}
.hasSubmenu {
color: #3498db;
font-weight: bold;
margin-bottom: 10px;
}
.subMenu {
margin-left: 20px;
margin-top: 10px;
li {
border-bottom: none;
margin: 10px 0;
padding-bottom: 5px;
a {
font-size: 16px;
color: rgba(255, 255, 255, 0.8);
}
}
}
}
.closeMenu {
position: absolute;
top: 20px;
right: 20px;
background: none;
border: none;
color: white;
font-size: 24px;
cursor: pointer;
padding: 10px;
&:hover {
color: #3498db;
}
}
.goBack {
margin-top: 30px;
padding-top: 20px;
border-top: 2px solid rgba(255, 255, 255, 0.3);
text-align: center;
a {
color: white;
text-decoration: none;
font-size: 16px;
display: inline-flex;
align-items: center;
gap: 8px;
&:hover {
color: #3498db;
}
img {
width: 16px;
height: 16px;
filter: invert(1);
}
}
}
}
// 移动端横幅适配
.banner {
height: 60vh;
min-height: 400px;
.banner-content {
padding: 40px 20px;
text-align: center;
.banner-title {
font-size: 2.5rem;
line-height: 1.2;
margin-bottom: 20px;
}
.banner-subtitle {
font-size: 1.2rem;
line-height: 1.4;
margin-bottom: 30px;
}
.banner-button {
padding: 12px 24px;
font-size: 16px;
}
}
}
// 移动端内容区域适配
.pageWidth {
padding: 0 15px;
}
.section {
padding: 40px 0;
.section-title {
font-size: 2rem;
line-height: 1.3;
margin-bottom: 20px;
}
.section-subtitle {
font-size: 1.1rem;
line-height: 1.5;
margin-bottom: 30px;
}
}
// 移动端网格布局适配
.grid,
.advantages-grid,
.areas-grid,
.services-grid,
.team-grid,
.contact-grid {
grid-template-columns: 1fr;
gap: 20px;
}
// 移动端卡片适配
.card,
.advantage-card,
.area-card,
.service-card,
.team-card,
.contact-card {
padding: 20px;
margin-bottom: 20px;
.card-title {
font-size: 1.3rem;
margin-bottom: 15px;
}
.card-content {
font-size: 1rem;
line-height: 1.6;
}
}
// 移动端按钮适配
.btn,
.button {
padding: 12px 24px;
font-size: 16px;
min-height: 44px; // 触摸友好尺寸
&.btn-large {
padding: 15px 30px;
font-size: 18px;
}
&.btn-small {
padding: 8px 16px;
font-size: 14px;
}
}
// 移动端表单适配
.form-group {
margin-bottom: 20px;
label {
display: block;
margin-bottom: 8px;
font-weight: 500;
}
input,
textarea,
select {
width: 100%;
padding: 12px;
font-size: 16px; // 防止iOS缩放
border: 1px solid #ddd;
border-radius: 4px;
min-height: 44px; // 触摸友好尺寸
&:focus {
outline: none;
border-color: #3498db;
box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
}
}
textarea {
min-height: 100px;
resize: vertical;
}
}
// 移动端图片适配
img {
max-width: 100%;
height: auto;
}
// 移动端图标适配
.icon {
width: 24px;
height: 24px;
&.icon-large {
width: 32px;
height: 32px;
}
&.icon-small {
width: 16px;
height: 16px;
}
}
// 移动端间距适配
.mt-mobile { margin-top: 20px !important; }
.mb-mobile { margin-bottom: 20px !important; }
.ml-mobile { margin-left: 15px !important; }
.mr-mobile { margin-right: 15px !important; }
.pt-mobile { padding-top: 20px !important; }
.pb-mobile { padding-bottom: 20px !important; }
.pl-mobile { padding-left: 15px !important; }
.pr-mobile { padding-right: 15px !important; }
// 移动端隐藏元素
.hide-mobile {
display: none !important;
}
// 移动端显示元素
.show-mobile {
display: block !important;
}
// 移动端文本对齐
.text-center-mobile {
text-align: center !important;
}
.text-left-mobile {
text-align: left !important;
}
.text-right-mobile {
text-align: right !important;
}
}
// ===== 平板端适配 =====
@media (min-width: @mobile-breakpoint + 1) and (max-width: @tablet-breakpoint) {
.pageWidth {
padding: 0 30px;
}
.grid,
.advantages-grid,
.areas-grid,
.services-grid,
.team-grid,
.contact-grid {
grid-template-columns: repeat(2, 1fr);
gap: 25px;
}
.section {
padding: 50px 0;
}
.banner {
height: 70vh;
.banner-content {
padding: 60px 40px;
.banner-title {
font-size: 3rem;
}
.banner-subtitle {
font-size: 1.4rem;
}
}
}
}
// ===== 小屏幕移动端适配 =====
@media (max-width: @small-mobile) {
.pageWidth {
padding: 0 10px;
}
.banner {
.banner-content {
padding: 30px 15px;
.banner-title {
font-size: 2rem;
}
.banner-subtitle {
font-size: 1rem;
}
}
}
.section {
padding: 30px 0;
.section-title {
font-size: 1.8rem;
}
.section-subtitle {
font-size: 1rem;
}
}
.card,
.advantage-card,
.area-card,
.service-card,
.team-card,
.contact-card {
padding: 15px;
.card-title {
font-size: 1.2rem;
}
}
.btn,
.button {
padding: 10px 20px;
font-size: 15px;
}
}
// ===== 超小屏幕移动端适配 =====
@media (max-width: @xs-mobile) {
.pageWidth {
padding: 0 8px;
}
.banner {
.banner-content {
padding: 25px 10px;
.banner-title {
font-size: 1.8rem;
}
.banner-subtitle {
font-size: 0.9rem;
}
}
}
.section {
padding: 25px 0;
.section-title {
font-size: 1.6rem;
}
.section-subtitle {
font-size: 0.9rem;
}
}
.card,
.advantage-card,
.area-card,
.service-card,
.team-card,
.contact-card {
padding: 12px;
.card-title {
font-size: 1.1rem;
}
}
.btn,
.button {
padding: 8px 16px;
font-size: 14px;
}
}
// ===== 触摸设备优化 =====
@media (hover: none) and (pointer: coarse) {
// 触摸设备禁用悬停效果
.hover-lift:hover,
.hover-scale:hover,
.hover-glow:hover,
.hover-rotate:hover,
.hover-bounce:hover {
transform: none;
box-shadow: none;
}
// 触摸设备增加触摸反馈
.btn,
.button,
.card,
.advantage-card,
.area-card,
.service-card,
.team-card,
.contact-card {
-webkit-tap-highlight-color: rgba(52, 152, 219, 0.3);
&:active {
transform: scale(0.98);
transition: transform 0.1s ease;
}
}
// 触摸设备优化菜单项
.menuContent {
li {
a {
padding: 15px 0; // 增加触摸区域
min-height: 44px; // 触摸友好尺寸
display: flex;
align-items: center;
}
}
}
}
// ===== 高分辨率屏幕适配 =====
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
.logo {
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
}
.icon {
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
}
}
// ===== 横屏模式适配 =====
@media (orientation: landscape) and (max-height: 500px) {
.headerMobileMenu {
.menuContent {
padding: 60px 20px 20px;
}
.closeMenu {
top: 15px;
right: 15px;
}
}
.banner {
height: 100vh;
.banner-content {
padding: 30px 20px;
.banner-title {
font-size: 2rem;
margin-bottom: 15px;
}
.banner-subtitle {
font-size: 1rem;
margin-bottom: 20px;
}
}
}
}
// ===== 打印样式 =====
@media print {
.headerMobileMenu,
.mobile-nav,
.floating-particles,
.scroll-progress-bar {
display: none !important;
}
.pageWidth {
padding: 0 !important;
}
.section {
padding: 20px 0 !important;
page-break-inside: avoid;
}
.card,
.advantage-card,
.area-card,
.service-card,
.team-card,
.contact-card {
page-break-inside: avoid;
margin-bottom: 15px !important;
}
}

View File

@@ -0,0 +1,279 @@
// ===== LESS 变量定义文件 =====
// ===== 颜色变量 =====
@primary-color: #3498db;
@primary-light: #5dade2;
@primary-dark: #2980b9;
@primary-lighter: #ebf3fd;
@success-color: #52c41a;
@success-light: #73d13d;
@success-dark: #389e0d;
@success-lighter: #f6ffed;
@warning-color: #faad14;
@warning-light: #ffc53d;
@warning-dark: #d48806;
@warning-lighter: #fffbe6;
@error-color: #f5222d;
@error-light: #ff4d4f;
@error-dark: #cf1322;
@error-lighter: #fff2f0;
@info-color: #1890ff;
@info-light: #40a9ff;
@info-dark: #096dd9;
@info-lighter: #e6f7ff;
// 中性色
@white: #ffffff;
@black: #000000;
@gray-1: #fafafa;
@gray-2: #f5f5f5;
@gray-3: #f0f0f0;
@gray-4: #d9d9d9;
@gray-5: #bfbfbf;
@gray-6: #8c8c8c;
@gray-7: #595959;
@gray-8: #434343;
@gray-9: #262626;
@gray-10: #1f1f1f;
// 文字颜色
@text-color: @gray-8;
@text-color-secondary: @gray-6;
@text-color-disabled: @gray-5;
@heading-color: @gray-9;
@link-color: @primary-color;
@link-hover-color: @primary-light;
// 背景颜色
@bg-color: @white;
@bg-color-light: @gray-1;
@bg-color-dark: @gray-2;
// 边框颜色
@border-color: @gray-4;
@border-color-light: @gray-3;
@border-color-dark: @gray-5;
// ===== 字体变量 =====
@font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
@font-family-code: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
@font-size-base: 14px;
@font-size-lg: 16px;
@font-size-sm: 12px;
@font-size-xs: 10px;
@font-size-h1: 38px;
@font-size-h2: 30px;
@font-size-h3: 24px;
@font-size-h4: 20px;
@font-size-h5: 16px;
@font-size-h6: 14px;
@line-height-base: 1.5715;
@line-height-lg: 1.5;
@line-height-sm: 1.4;
@line-height-xs: 1.3;
@font-weight-light: 300;
@font-weight-normal: 400;
@font-weight-medium: 500;
@font-weight-semibold: 600;
@font-weight-bold: 700;
@font-weight-extrabold: 800;
// ===== 间距变量 =====
@spacing-xs: 4px;
@spacing-sm: 8px;
@spacing-md: 16px;
@spacing-lg: 24px;
@spacing-xl: 32px;
@spacing-xxl: 48px;
@spacing-xxxl: 64px;
@padding-xs: @spacing-xs;
@padding-sm: @spacing-sm;
@padding-md: @spacing-md;
@padding-lg: @spacing-lg;
@padding-xl: @spacing-xl;
@margin-xs: @spacing-xs;
@margin-sm: @spacing-sm;
@margin-md: @spacing-md;
@margin-lg: @spacing-lg;
@margin-xl: @spacing-xl;
// ===== 尺寸变量 =====
@border-radius-base: 4px;
@border-radius-sm: 2px;
@border-radius-lg: 8px;
@border-radius-xl: 12px;
@border-radius-circle: 50%;
@border-width-base: 1px;
@border-width-thick: 2px;
@border-width-thin: 0.5px;
// ===== 阴影变量 =====
@box-shadow-base: 0 2px 8px rgba(0, 0, 0, 0.15);
@box-shadow-sm: 0 1px 4px rgba(0, 0, 0, 0.1);
@box-shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.2);
@box-shadow-xl: 0 8px 24px rgba(0, 0, 0, 0.25);
@text-shadow-base: 0 1px 2px rgba(0, 0, 0, 0.1);
@text-shadow-lg: 0 2px 4px rgba(0, 0, 0, 0.2);
// ===== 断点变量 =====
@screen-xs: 480px;
@screen-sm: 576px;
@screen-md: 768px;
@screen-lg: 992px;
@screen-xl: 1200px;
@screen-xxl: 1600px;
@mobile-breakpoint: @screen-md;
@tablet-breakpoint: @screen-lg;
@desktop-breakpoint: @screen-xl;
// 移动端断点变量
@small-mobile: 480px;
@xs-mobile: 360px;
// ===== 动画变量 =====
@animation-duration-base: 0.2s;
@animation-duration-fast: 0.1s;
@animation-duration-slow: 0.3s;
@animation-duration-slower: 0.5s;
@animation-timing-base: ease;
@animation-timing-ease-in: ease-in;
@animation-timing-ease-out: ease-out;
@animation-timing-ease-in-out: ease-in-out;
@animation-timing-linear: linear;
@animation-delay-base: 0s;
@animation-delay-fast: 0.1s;
@animation-delay-slow: 0.3s;
// ===== Z-index 变量 =====
@zindex-dropdown: 1000;
@zindex-sticky: 1020;
@zindex-fixed: 1030;
@zindex-modal-backdrop: 1040;
@zindex-modal: 1050;
@zindex-popover: 1060;
@zindex-tooltip: 1070;
@zindex-toast: 1080;
// ===== 组件特定变量 =====
// 按钮
@btn-height-base: 32px;
@btn-height-lg: 40px;
@btn-height-sm: 24px;
@btn-padding-horizontal-base: @padding-md;
@btn-padding-horizontal-lg: @padding-lg;
@btn-padding-horizontal-sm: @padding-sm;
// 输入框
@input-height-base: 32px;
@input-height-lg: 40px;
@input-height-sm: 24px;
@input-padding-horizontal: @padding-sm;
// 卡片
@card-padding-base: @padding-lg;
@card-padding-sm: @padding-md;
@card-padding-lg: @padding-xl;
// 表格
@table-padding-vertical: @padding-sm;
@table-padding-horizontal: @padding-md;
// 分页
@pagination-item-size: 32px;
@pagination-item-size-sm: 24px;
// 标签
@tag-height: 20px;
@tag-height-lg: 28px;
@tag-height-sm: 16px;
// 徽章
@badge-height: 20px;
@badge-height-sm: 14px;
@badge-height-lg: 24px;
// ===== 工具函数 =====
// 颜色混合函数
.lighten(@color, @amount) {
color: lighten(@color, @amount);
}
.darken(@color, @amount) {
color: darken(@color, @amount);
}
// 透明度函数
.alpha(@color, @opacity) {
color: fade(@color, @opacity);
}
// 响应式混合
.mobile(@rules) {
@media (max-width: @mobile-breakpoint) {
@rules();
}
}
.tablet(@rules) {
@media (min-width: @mobile-breakpoint + 1) and (max-width: @tablet-breakpoint) {
@rules();
}
}
.desktop(@rules) {
@media (min-width: @tablet-breakpoint + 1) {
@rules();
}
}
// 触摸设备检测
.touch-device(@rules) {
@media (hover: none) and (pointer: coarse) {
@rules();
}
}
// 高分辨率屏幕
.high-dpi(@rules) {
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
@rules();
}
}
// 打印样式
.print(@rules) {
@media print {
@rules();
}
}
// 横屏模式
.landscape(@rules) {
@media (orientation: landscape) and (max-height: 500px) {
@rules();
}
}
// 减少动画偏好
.reduced-motion(@rules) {
@media (prefers-reduced-motion: reduce) {
@rules();
}
}

View File

@@ -116,6 +116,7 @@ export default {
mounted() {
this.initHeader()
this.initScrollListener()
this.initMobileMenu()
},
methods: {
// 封装事件监听器创建,提高代码复用性
@@ -197,6 +198,52 @@ export default {
}
}
});
},
// 初始化移动端菜单
initMobileMenu() {
// 汉堡菜单点击事件
this.add_event_listener("hamburger", "click", () => {
this.toggle_class("mobileMenu", "active", true);
}, true);
// 返回按钮点击事件
this.add_event_listener(".linkGoBack", "click", () => {
this.remove_class("mobileMenu", "active", true);
// 关闭移动端菜单后滚动到顶部
window.scrollTo({
top: 0,
left: 0,
behavior: 'smooth'
});
});
// 点击菜单项后自动关闭菜单
const menuLinks = document.querySelectorAll('.headerMobileMenu a');
menuLinks.forEach(link => {
link.addEventListener('click', () => {
this.remove_class("mobileMenu", "active", true);
});
});
// 点击菜单外部区域关闭菜单
document.addEventListener('click', (e) => {
const mobileMenu = document.getElementById('mobileMenu');
const hamburger = document.getElementById('hamburger');
if (mobileMenu && mobileMenu.classList.contains('active') &&
!mobileMenu.contains(e.target) &&
!hamburger.contains(e.target)) {
this.remove_class("mobileMenu", "active", true);
}
});
// ESC键关闭菜单
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
this.remove_class("mobileMenu", "active", true);
}
});
}
}
}

View File

@@ -1,9 +1,13 @@
import './assets/css/cookieconsent.min.css'
import './assets/css/common.css'
import './assets/css/animations.css'
import './assets/css/common.less'
import './assets/css/content_pages.less'
import './assets/css/animations.less'
import './assets/css/mobile_responsive.less'
import './assets/css/common_mobile.less'
import 'swiper/css/swiper.min.css'
import 'es6-promise/auto'
import './static/animation_helper'
import './static/scroll_helper'
import Vue from 'vue'
import App from './App.vue'
import Vuex from 'vuex'

250
src/static/scroll_helper.js Normal file
View File

@@ -0,0 +1,250 @@
/**
* 滚动控制助手 - 处理页面刷新和路由切换时的滚动行为
*/
class ScrollHelper {
constructor() {
this.isInitialized = false;
this.init();
}
/**
* 初始化滚动助手
*/
init() {
if (this.isInitialized) return;
// 监听页面加载完成事件
this.handlePageLoad();
// 监听路由变化事件
this.handleRouteChange();
// 监听页面刷新事件
this.handlePageRefresh();
// 监听浏览器前进后退事件
this.handleBrowserNavigation();
this.isInitialized = true;
}
/**
* 处理页面加载完成
*/
handlePageLoad() {
// 页面完全加载后滚动到顶部
if (document.readyState === 'complete') {
this.scrollToTop();
} else {
window.addEventListener('load', () => {
this.scrollToTop();
});
}
// DOM内容加载完成后也滚动到顶部
document.addEventListener('DOMContentLoaded', () => {
this.scrollToTop();
});
}
/**
* 处理路由变化
*/
handleRouteChange() {
// 监听 Vue Router 的全局前置守卫
if (window.Vue && window.Vue.prototype.$router) {
window.Vue.prototype.$router.beforeEach((to, from, next) => {
// 路由切换时滚动到顶部
this.scrollToTop();
next();
});
}
}
/**
* 处理页面刷新
*/
handlePageRefresh() {
// 监听页面即将刷新事件
window.addEventListener('beforeunload', () => {
// 保存当前滚动位置到 sessionStorage
sessionStorage.setItem('scrollPosition', window.pageYOffset);
});
// 页面加载完成后检查是否需要滚动到顶部
window.addEventListener('load', () => {
const savedPosition = sessionStorage.getItem('scrollPosition');
if (savedPosition) {
// 清除保存的位置
sessionStorage.removeItem('scrollPosition');
// 滚动到顶部
this.scrollToTop();
}
});
}
/**
* 处理浏览器前进后退
*/
handleBrowserNavigation() {
// 监听 popstate 事件(浏览器前进后退)
window.addEventListener('popstate', () => {
// 延迟执行,确保路由更新完成
setTimeout(() => {
this.scrollToTop();
}, 100);
});
}
/**
* 滚动到页面顶部
*/
scrollToTop(options = {}) {
const defaultOptions = {
top: 0,
left: 0,
behavior: 'smooth'
};
const config = { ...defaultOptions, ...options };
// 检查浏览器是否支持平滑滚动
if (!this.supportsSmoothScrolling()) {
config.behavior = 'auto';
}
// 执行滚动
window.scrollTo(config);
// 同时滚动 body 和 html 元素(兼容性处理)
if (document.body) {
document.body.scrollTop = 0;
document.body.scrollLeft = 0;
}
if (document.documentElement) {
document.documentElement.scrollTop = 0;
document.documentElement.scrollLeft = 0;
}
}
/**
* 滚动到指定元素
*/
scrollToElement(selector, options = {}) {
const element = document.querySelector(selector);
if (!element) return;
const defaultOptions = {
behavior: 'smooth',
block: 'start',
inline: 'nearest'
};
const config = { ...defaultOptions, ...options };
// 检查浏览器是否支持 scrollIntoView
if (element.scrollIntoView) {
element.scrollIntoView(config);
} else {
// 降级处理:计算元素位置并滚动
const rect = element.getBoundingClientRect();
const scrollTop = window.pageYOffset + rect.top;
this.scrollToTop({ top: scrollTop, behavior: config.behavior });
}
}
/**
* 检查浏览器是否支持平滑滚动
*/
supportsSmoothScrolling() {
return 'scrollBehavior' in document.documentElement.style;
}
/**
* 获取当前滚动位置
*/
getScrollPosition() {
return {
x: window.pageXOffset || document.documentElement.scrollLeft,
y: window.pageYOffset || document.documentElement.scrollTop
};
}
/**
* 设置滚动位置
*/
setScrollPosition(x, y, behavior = 'smooth') {
const options = {
top: y,
left: x,
behavior: this.supportsSmoothScrolling() ? behavior : 'auto'
};
window.scrollTo(options);
}
/**
* 滚动到底部
*/
scrollToBottom(behavior = 'smooth') {
const scrollHeight = Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight,
document.body.offsetHeight,
document.documentElement.offsetHeight,
document.body.clientHeight,
document.documentElement.clientHeight
);
this.scrollToTop({
top: scrollHeight,
behavior: behavior
});
}
/**
* 滚动到指定百分比位置
*/
scrollToPercentage(percentage, behavior = 'smooth') {
const scrollHeight = Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight
);
const targetPosition = (scrollHeight - window.innerHeight) * (percentage / 100);
this.scrollToTop({
top: targetPosition,
behavior: behavior
});
}
/**
* 监听滚动事件
*/
onScroll(callback) {
window.addEventListener('scroll', callback, { passive: true });
}
/**
* 移除滚动监听器
*/
offScroll(callback) {
window.removeEventListener('scroll', callback);
}
/**
* 销毁滚动助手
*/
destroy() {
// 清理事件监听器
this.isInitialized = false;
}
}
// 创建全局实例
window.scrollHelper = new ScrollHelper();
// 导出类(如果使用模块系统)
if (typeof module !== 'undefined' && module.exports) {
module.exports = ScrollHelper;
}

View File

@@ -7,13 +7,27 @@
<!-- 现代化横幅区域 -->
<div class="banner" data-parallax="0.3">
<!-- 浮动粒子背景 -->
<div class="floating-particles">
<div class="floating-particle"></div>
<div class="floating-particle"></div>
<div class="floating-particle"></div>
<div class="floating-particle"></div>
<div class="floating-particle"></div>
<div class="floating-particle"></div>
<div class="floating-particle"></div>
<div class="floating-particle"></div>
<div class="floating-particle"></div>
<div class="floating-particle"></div>
</div>
<swiper ref="swiper" :options="swiperOption">
<swiper-slide v-for="banner in banners" :key="banner.img">
<div class="banner-content">
<img :src="banner.img" width="100%" />
<div class="banner-overlay">
<div class="banner-text">
<h1 class="banner-title animate fade-in-down">{{banner.title}}</h1>
<h1 class="banner-title animate fade-in-down text-glow">{{banner.title}}</h1>
<p class="banner-subtitle animate fade-in-up delay-1s">{{banner.subtitle}}</p>
</div>
</div>