实现同背景滚动文本切换动画(参考Groupamana网站)
实现滚动触发的文本切换动画(固定视频背景)
需求说明
滚动页面时,视频背景固定不动,文本内容逐段切换:当前文本淡出消失,下一段文本淡入显示,始终保持在同一背景区域。
修改后的完整代码
HTML
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <title>滚动文本切换</title> </head> <body> <!-- 固定视频背景容器 --> <div class="video-container"> <video autoplay loop muted plays-inline class="background-clip"> <source src="../images/Video.mp4" type="video/mp4"> </video> </div> <!-- 滚动切换的文本容器 --> <div class="text-slider-container"> <div class="text-slide"> <h1>第一段文本内容</h1> </div> <div class="text-slide"> <h1>第二段文本内容</h1> </div> <div class="text-slide"> <h1>第三段文本内容</h1> </div> <div class="text-slide"> <h1>第四段文本内容</h1> </div> <div class="text-slide"> <h1>第五段文本内容</h1> </div> </div> <!-- 撑开页面高度用于滚动测试 --> <div class="scroll-spacer"></div> <script src="main.js"></script> </body> </html>
CSS
* { margin: 0; padding: 0; box-sizing: border-box; } body { min-height: 100vh; } /* 固定视频背景 */ .video-container { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; overflow: hidden; z-index: -1; } .background-clip { width: 100%; height: 100%; object-fit: cover; } /* 文本滑块容器 - 粘性定位,保持在视口内 */ .text-slider-container { position: sticky; top: 0; width: 100%; height: 100vh; display: flex; align-items: center; justify-content: center; } /* 每个文本块 */ .text-slide { position: absolute; width: 100%; text-align: center; color: #fff; opacity: 0; visibility: hidden; transition: opacity 0.6s ease, visibility 0.6s ease; } .text-slide.active { opacity: 1; visibility: visible; } /* 撑开页面高度,确保有足够滚动空间 */ .scroll-spacer { height: 400vh; }
JavaScript
document.addEventListener("DOMContentLoaded", function() { const textSlides = document.querySelectorAll('.text-slide'); const slideCount = textSlides.length; // 每段文本对应的滚动区间(根据页面总高度均分) const scrollSegment = window.innerHeight * 4 / slideCount; window.addEventListener('scroll', function() { const scrollTop = window.pageYOffset; // 计算当前显示的文本索引 const activeIndex = Math.floor(scrollTop / scrollSegment); // 重置所有文本状态,激活当前文本 textSlides.forEach((slide, index) => { if (index === activeIndex && activeIndex < slideCount) { slide.classList.add('active'); } else { slide.classList.remove('active'); } }); }); // 初始化触发一次滚动事件,确保初始状态正确 window.dispatchEvent(new Event('scroll')); });
关键修改说明
HTML结构优化:
- 拆分视频容器和文本容器,视频用fixed定位固定在视口
- 文本块统一使用
text-slide类,便于批量控制 - 添加滚动占位区
scroll-spacer,提供足够滚动空间
CSS核心调整:
- 视频容器设为
fixed+object-fit: cover,确保背景全屏且比例正确 - 文本容器用
sticky定位,固定在视口内,所有文本块绝对定位重叠在同一位置 - 文本块通过
active类控制显示/隐藏,配合过渡动画实现淡入淡出
- 视频容器设为
JS逻辑实现:
- 监听滚动事件,根据滚动距离计算当前应该显示的文本索引
- 均分滚动区间,确保每滚动一段距离切换一次文本
- 初始化时触发滚动事件,避免初始状态异常
内容的提问来源于stack exchange,提问作者Abdallah Kondakji
相关产品推荐
相关产品推荐

