滚动时文本位置平滑切换与透明度渐变的实现方案咨询
实现滚动驱动的文本切换效果
核心思路
把所有文本放在同一个容器的相同位置,通过监听滚动事件,根据滚动方向和距离,控制当前文本的透明度衰减,同时让目标文本从侧边滑入并逐渐显示,滚动到指定距离后完成切换。
代码实现
HTML结构
<div class="text-container"> <div class="text-item active">text 1</div> <div class="text-item">text 2</div> <div class="text-item">text 3</div> <div class="text-item">text 4</div> </div>
CSS样式
.text-container { position: relative; width: 200px; height: 50px; overflow: hidden; margin: 50px auto; } .text-item { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 24px; opacity: 0; transform: translateX(100%); transition: none; /* 禁用CSS过渡,用JS控制实时变化 */ } .text-item.active { opacity: 1; transform: translateX(0); }
JavaScript逻辑
const container = document.querySelector('.text-container'); const textItems = document.querySelectorAll('.text-item'); const scrollThreshold = 150; // 完成一次切换需要滚动的像素值 let currentIndex = 0; let lastScrollTop = window.pageYOffset; let progress = 0; window.addEventListener('scroll', () => { const scrollTop = window.pageYOffset; const scrollDelta = scrollTop - lastScrollTop; lastScrollTop = scrollTop; // 更新滚动进度,限制在0-1之间 progress += scrollDelta / scrollThreshold; progress = Math.max(0, Math.min(1, progress)); // 向下滚动(切换到下一个文本) if (scrollDelta > 0 && currentIndex < textItems.length - 1) { const currentItem = textItems[currentIndex]; const nextItem = textItems[currentIndex + 1]; // 当前文本透明度从1降到0 currentItem.style.opacity = 1 - progress; // 下一个文本从右侧滑入,透明度从0升到1 nextItem.style.transform = `translateX(${100 - progress * 100}%)`; nextItem.style.opacity = progress; // 进度满1,完成切换 if (progress === 1) { currentItem.classList.remove('active'); nextItem.classList.add('active'); currentIndex++; progress = 0; } } // 向上滚动(切换到上一个文本) else if (scrollDelta < 0 && currentIndex > 0) { const currentItem = textItems[currentIndex]; const prevItem = textItems[currentIndex - 1]; // 当前文本透明度从1降到0 currentItem.style.opacity = 1 - progress; // 上一个文本从左侧滑入,透明度从0升到1 currentItem.style.transform = `translateX(${progress * 100}%)`; prevItem.style.opacity = progress; // 进度满1,完成切换 if (progress === 1) { currentItem.classList.remove('active'); prevItem.classList.add('active'); currentIndex--; progress = 0; } } else { // 滚动到边界,重置进度 progress = 0; } });
关键细节说明
- 滚动阈值:
scrollThreshold可按需调整,值越小切换越灵敏,值越大切换所需滚动距离越长。 - 实时控制:禁用CSS过渡动画,改用JS直接计算进度更新样式,保证滚动与动画同步。
- 边界处理:判断当前索引范围,避免越界切换。
- 方向判断:通过滚动前后的位置差值区分上下滚动,执行对应动画逻辑。
内容的提问来源于stack exchange,提问作者Lvasche
相关产品推荐
相关产品推荐

