移动端视差滚动 + 滑动丝滑优化
- 背景编号(01-06)随滚动错位移动,速率30%,GPU加速transform - 移除will-change减少内存压力,解决滑动卡顿/拖不动问题 - IntersectionObserver阈值降至0.05,触发更自然 - 滚动监听使用requestAnimationFrame防抖动 - 编号透明度降至0.12,明确作为背景层
This commit is contained in:
parent
35bef7dad9
commit
7d16a2bb91
118
index.html
118
index.html
|
|
@ -360,76 +360,91 @@
|
||||||
}
|
}
|
||||||
@keyframes sectionFadeIn { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
|
@keyframes sectionFadeIn { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
|
||||||
|
|
||||||
/* 移动端:痛点和思路板块用 CSS 滚动触发动画 */
|
/* 移动端:痛点和思路板块 - 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);
|
||||||
}
|
}
|
||||||
/* 子元素默认隐藏 */
|
|
||||||
#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 {
|
#pain-points .pain-item .pain-num {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1),
|
||||||
|
transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
|
||||||
|
}
|
||||||
|
#pain-points .pain-item .pain-icon {
|
||||||
|
transform: scale(0.7) translateY(15px);
|
||||||
|
}
|
||||||
|
#pain-points .pain-item h3,
|
||||||
|
#pain-points .pain-item p {
|
||||||
|
transform: translateY(25px);
|
||||||
|
}
|
||||||
|
#pain-points .pain-item .pain-num {
|
||||||
|
transform: translateY(15px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 进入视口后 */
|
/* 进入视口后:平滑过渡 */
|
||||||
#pain-points .pain-item.in-view {
|
#pain-points .pain-item.in-view {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
#pain-points .pain-item.in-view .pain-icon {
|
#pain-points .pain-item.in-view .pain-icon {
|
||||||
animation: iconPop 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.1s both;
|
opacity: 0.35;
|
||||||
|
transform: scale(1) translateY(0);
|
||||||
|
transition-delay: 0.05s;
|
||||||
}
|
}
|
||||||
#pain-points .pain-item.in-view h3 {
|
#pain-points .pain-item.in-view h3 {
|
||||||
animation: titleSlide 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.15s both;
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
transition-delay: 0.1s;
|
||||||
}
|
}
|
||||||
#pain-points .pain-item.in-view p {
|
#pain-points .pain-item.in-view p {
|
||||||
animation: textSlide 0.9s cubic-bezier(0.16, 1, 0.3, 1) 0.3s both;
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
transition-delay: 0.18s;
|
||||||
}
|
}
|
||||||
#pain-points .pain-item.in-view .pain-num {
|
#pain-points .pain-item.in-view .pain-num {
|
||||||
animation: numReveal 1.2s ease 0.5s both;
|
opacity: 0.12;
|
||||||
|
transform: translateY(0);
|
||||||
|
transition-delay: 0.25s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 思路板块同样 */
|
/* 思路板块同样 */
|
||||||
#approach .approach-item {
|
#approach .approach-item {
|
||||||
opacity: 0.08;
|
opacity: 0.08;
|
||||||
|
transition: opacity 0.6s 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);
|
||||||
|
transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1),
|
||||||
|
transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
|
||||||
}
|
}
|
||||||
#approach .approach-item.in-view {
|
#approach .approach-item.in-view {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
#approach .approach-item.in-view .approach-step {
|
#approach .approach-item.in-view .approach-step {
|
||||||
animation: textSlide 0.6s ease 0.1s both;
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
transition-delay: 0.05s;
|
||||||
}
|
}
|
||||||
#approach .approach-item.in-view .approach-body h3 {
|
#approach .approach-item.in-view .approach-body h3 {
|
||||||
animation: titleSlide 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.15s both;
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
transition-delay: 0.1s;
|
||||||
}
|
}
|
||||||
#approach .approach-item.in-view .approach-body p {
|
#approach .approach-item.in-view .approach-body p {
|
||||||
animation: textSlide 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.25s both;
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
transition-delay: 0.18s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes titleSlide {
|
@keyframes sectionFadeIn { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
|
||||||
from { opacity: 0; transform: translateY(40px); }
|
|
||||||
to { opacity: 1; transform: translateY(0); }
|
|
||||||
}
|
|
||||||
@keyframes textSlide {
|
|
||||||
from { opacity: 0; transform: translateY(25px); }
|
|
||||||
to { opacity: 1; transform: translateY(0); }
|
|
||||||
}
|
|
||||||
@keyframes iconPop {
|
|
||||||
from { opacity: 0; transform: scale(0.6) translateY(20px); }
|
|
||||||
to { opacity: 0.5; transform: scale(1) translateY(0); }
|
|
||||||
}
|
|
||||||
@keyframes numReveal {
|
|
||||||
from { opacity: 0; transform: translateY(15px); }
|
|
||||||
to { opacity: 1; transform: translateY(0); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 移动端痛点沉浸式布局 */
|
/* 移动端痛点沉浸式布局 */
|
||||||
@media (max-width: 900px) {
|
@media (max-width: 900px) {
|
||||||
|
|
@ -541,7 +556,7 @@
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 编号 - 超大背景装饰 */
|
/* 编号 - 超大背景装饰 + 视差 */
|
||||||
.pain-num {
|
.pain-num {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 30px;
|
bottom: 30px;
|
||||||
|
|
@ -551,7 +566,9 @@
|
||||||
color: rgba(255,255,255,0.04);
|
color: rgba(255,255,255,0.04);
|
||||||
letter-spacing: -5px;
|
letter-spacing: -5px;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
transition: none;
|
transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1);
|
||||||
|
will-change: transform;
|
||||||
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 破局之道 - 高潮区域 */
|
/* 破局之道 - 高潮区域 */
|
||||||
|
|
@ -938,36 +955,35 @@
|
||||||
}, { 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));
|
||||||
|
|
||||||
// 移动端:滚动触发动画(低 threshold 确保全高元素也能触发)
|
// 移动端:轻量级 IntersectionObserver + 视差滚动
|
||||||
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 => {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) entry.target.classList.add('in-view');
|
||||||
entry.target.classList.add('in-view');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}, { threshold: 0.1, rootMargin: "0px 0px -10% 0px" });
|
}, { threshold: 0.05, rootMargin: "0px 0px -5% 0px" });
|
||||||
|
|
||||||
mobileItems.forEach(item => mobileObserver.observe(item));
|
mobileItems.forEach(item => mobileObserver.observe(item));
|
||||||
|
|
||||||
// 背景网格视差
|
// 2. 背景编号视差(仅操作 transform,GPU 加速)
|
||||||
const gridBg = document.querySelector('.pain-grid-bg');
|
let ticking = false;
|
||||||
const painSection = document.getElementById('pain-points');
|
const painNums = document.querySelectorAll('.pain-num');
|
||||||
if (gridBg && painSection) {
|
window.addEventListener('scroll', () => {
|
||||||
let ticking = false;
|
if (!ticking) {
|
||||||
window.addEventListener('scroll', () => {
|
requestAnimationFrame(() => {
|
||||||
if (!ticking) {
|
painNums.forEach(num => {
|
||||||
requestAnimationFrame(() => {
|
const rect = num.parentElement.getBoundingClientRect();
|
||||||
const rect = painSection.getBoundingClientRect();
|
// 计算元素在视口中的位置比例
|
||||||
const progress = Math.max(0, Math.min(1, -rect.top / rect.height));
|
const progress = -rect.top / window.innerHeight;
|
||||||
gridBg.style.transform = `translateY(${progress * -60}px)`;
|
// 视差位移:数字移动速度是滚动速度的 30%
|
||||||
ticking = false;
|
num.style.transform = `translateY(${progress * -40}px)`;
|
||||||
});
|
});
|
||||||
ticking = true;
|
ticking = false;
|
||||||
}
|
});
|
||||||
}, { passive: true });
|
ticking = true;
|
||||||
}
|
}
|
||||||
|
}, { passive: true });
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue