移动端错位动画:内容上移 + 数字下落

- 内容元素从下方40px滑入(从下至上)
- 数字编号从上方70px落下(从上至下)
- 两者反向运动产生明显错位感
- 数字延迟0.08s提前出现,内容0.12s跟随
- 移除JS滚动视差,纯CSS transition处理
- 背景网格position:fixed钉在墙上不动
This commit is contained in:
Omega 2026-04-20 22:38:56 +08:00
parent 7d16a2bb91
commit a22c465a3b
1 changed files with 37 additions and 60 deletions

View File

@ -358,35 +358,33 @@
#pain-points .pain-grid > .fade-up:nth-child(5) { animation-delay: 0.55s; } #pain-points .pain-grid > .fade-up:nth-child(5) { animation-delay: 0.55s; }
#pain-points .pain-grid > .fade-up:nth-child(6) { animation-delay: 0.65s; } #pain-points .pain-grid > .fade-up:nth-child(6) { animation-delay: 0.65s; }
} }
@keyframes sectionFadeIn { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } /* 移动端:痛点和思路板块 - 错位动画 */
/* 移动端:痛点和思路板块 - GPU 加速平滑动画 */
@media (max-width: 900px) { @media (max-width: 900px) {
/* 默认状态:微弱可见 + 子元素透明 */ /* 默认状态:卡片微弱可见 */
#pain-points .pain-item { #pain-points .pain-item {
opacity: 0.08; opacity: 0.08;
transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1); transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1);
} }
/* 内容元素默认在下方(准备从下往上滑入) */
#pain-points .pain-item .pain-icon, #pain-points .pain-item .pain-icon,
#pain-points .pain-item h3, #pain-points .pain-item h3,
#pain-points .pain-item p, #pain-points .pain-item p {
#pain-points .pain-item .pain-num {
opacity: 0; opacity: 0;
transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), transform: translateY(40px);
transform 0.6s cubic-bezier(0.16, 1, 0.3, 1); transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1),
transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
} }
#pain-points .pain-item .pain-icon { #pain-points .pain-item .pain-icon {
transform: scale(0.7) translateY(15px); transform: scale(0.6) translateY(40px);
}
#pain-points .pain-item h3,
#pain-points .pain-item p {
transform: translateY(25px);
} }
/* 数字默认在上方(准备从上往下滑入) */
#pain-points .pain-item .pain-num { #pain-points .pain-item .pain-num {
transform: translateY(15px); opacity: 0;
transform: translateY(-70px);
transition: opacity 0.9s ease, transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
} }
/* 进入视口后:平滑过渡 */ /* 进入视口后:内容上移,数字下落 */
#pain-points .pain-item.in-view { #pain-points .pain-item.in-view {
opacity: 1; opacity: 1;
} }
@ -398,31 +396,31 @@
#pain-points .pain-item.in-view h3 { #pain-points .pain-item.in-view h3 {
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
transition-delay: 0.1s; transition-delay: 0.12s;
} }
#pain-points .pain-item.in-view p { #pain-points .pain-item.in-view p {
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
transition-delay: 0.18s; transition-delay: 0.2s;
} }
#pain-points .pain-item.in-view .pain-num { #pain-points .pain-item.in-view .pain-num {
opacity: 0.12; opacity: 0.15;
transform: translateY(0); transform: translateY(0);
transition-delay: 0.25s; transition-delay: 0.08s;
} }
/* 思路板块同样 */ /* 思路板块同样 */
#approach .approach-item { #approach .approach-item {
opacity: 0.08; opacity: 0.08;
transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1); transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1);
} }
#approach .approach-item .approach-step, #approach .approach-item .approach-step,
#approach .approach-item .approach-body h3, #approach .approach-item .approach-body h3,
#approach .approach-item .approach-body p { #approach .approach-item .approach-body p {
opacity: 0; opacity: 0;
transform: translateY(20px); transform: translateY(30px);
transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1),
transform 0.6s cubic-bezier(0.16, 1, 0.3, 1); transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
} }
#approach .approach-item.in-view { #approach .approach-item.in-view {
opacity: 1; opacity: 1;
@ -435,12 +433,12 @@
#approach .approach-item.in-view .approach-body h3 { #approach .approach-item.in-view .approach-body h3 {
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
transition-delay: 0.1s; transition-delay: 0.12s;
} }
#approach .approach-item.in-view .approach-body p { #approach .approach-item.in-view .approach-body p {
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
transition-delay: 0.18s; transition-delay: 0.2s;
} }
} }
@ -463,27 +461,29 @@
margin-right: auto; margin-right: auto;
max-width: 90%; max-width: 90%;
} }
/* 背景网格 - 钉在墙上完全不动 */
.pain-grid-bg { .pain-grid-bg {
position: absolute; position: fixed;
top: 0; left: 0; right: 0; bottom: 0; top: 0; left: 0; right: 0; bottom: 0;
z-index: 0; z-index: 0;
animation: none; animation: none;
background-image: background-image:
linear-gradient(rgba(255,255,255,0.04) 1px, transparent 1px), linear-gradient(rgba(255,255,255,0.06) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.04) 1px, transparent 1px); linear-gradient(90deg, rgba(255,255,255,0.06) 1px, transparent 1px);
background-size: 60px 60px; background-size: 60px 60px;
} }
.pain-glow { .pain-glow {
position: absolute; position: fixed;
top: 50%; left: 50%; top: 50%; left: 50%;
width: 400px; height: 400px; width: 400px; height: 400px;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
background: radial-gradient(circle, rgba(255,255,255,0.06) 0%, transparent 70%); background: radial-gradient(circle, rgba(255,255,255,0.08) 0%, transparent 70%);
animation: glowPulse 6s ease-in-out infinite alternate; animation: glowPulse 6s ease-in-out infinite alternate;
z-index: 0; z-index: 0;
pointer-events: none; pointer-events: none;
} }
/* 内容层 - 在背景上正常滚动 */
.pain-grid { .pain-grid {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -556,19 +556,16 @@
padding-right: 0; padding-right: 0;
} }
/* 编号 - 超大背景装饰 + 视差 */ /* 编号 - 超大背景装饰 */
.pain-num { .pain-num {
position: absolute; position: absolute;
bottom: 30px; bottom: 40px;
right: 24px; right: 30px;
font-size: 100px; font-size: 110px;
font-weight: 900; font-weight: 900;
color: rgba(255,255,255,0.04); color: rgba(255,255,255,0.08);
letter-spacing: -5px; letter-spacing: -5px;
line-height: 1; line-height: 1;
transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1);
will-change: transform;
transform: translateY(0);
} }
/* 破局之道 - 高潮区域 */ /* 破局之道 - 高潮区域 */
@ -955,9 +952,8 @@
}, { threshold: 0.15, rootMargin: "0px 0px -50px 0px" }); }, { threshold: 0.15, rootMargin: "0px 0px -50px 0px" });
document.querySelectorAll('.fade-up').forEach(el => observer.observe(el)); document.querySelectorAll('.fade-up').forEach(el => observer.observe(el));
// 移动端:轻量级 IntersectionObserver + 视差滚动 // 移动端:轻量级 IntersectionObserver(入场错位动画由 CSS transition 处理)
if (window.innerWidth <= 900) { if (window.innerWidth <= 900) {
// 1. 入场动画
const mobileItems = document.querySelectorAll('#pain-points .pain-item, #approach .approach-item'); const mobileItems = document.querySelectorAll('#pain-points .pain-item, #approach .approach-item');
const mobileObserver = new IntersectionObserver((entries) => { const mobileObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => { entries.forEach(entry => {
@ -965,25 +961,6 @@
}); });
}, { threshold: 0.05, rootMargin: "0px 0px -5% 0px" }); }, { threshold: 0.05, rootMargin: "0px 0px -5% 0px" });
mobileItems.forEach(item => mobileObserver.observe(item)); mobileItems.forEach(item => mobileObserver.observe(item));
// 2. 背景编号视差(仅操作 transformGPU 加速)
let ticking = false;
const painNums = document.querySelectorAll('.pain-num');
window.addEventListener('scroll', () => {
if (!ticking) {
requestAnimationFrame(() => {
painNums.forEach(num => {
const rect = num.parentElement.getBoundingClientRect();
// 计算元素在视口中的位置比例
const progress = -rect.top / window.innerHeight;
// 视差位移:数字移动速度是滚动速度的 30%
num.style.transform = `translateY(${progress * -40}px)`;
});
ticking = false;
});
ticking = true;
}
}, { passive: true });
} }
</script> </script>
</body> </body>