如何实现滚动到指定区域时触发动画效果?
实现滚动到指定区域才触发动画的方案
我在页面的skills区域做了动画,但页面一刷新动画就自动启动了,怎么设置成只有滚动到该区域时才触发动画?
解决思路
- 移除CSS中默认绑定到元素的动画,改用独立的动画类控制触发时机,避免页面加载就执行动画
- 监听页面滚动事件,判断目标区域是否进入浏览器视口
- 检测到区域进入视口后,添加动画类启动圆圈动画,同时触发数字计数逻辑,并用标记确保动画只执行一次
修改后的完整代码
CSS 部分
.o1 { fill: none; stroke: rgb(94, 217, 250); stroke-width: 20px; stroke-dasharray: 472; stroke-dashoffset: 472; } /* 单独定义动画类,默认不添加到元素上 */ .animate-circle { animation: anim 2s linear forwards; } @keyframes anim { 100% { stroke-dashoffset: 70; } }
HTML & JS 部分
<section id="skills"> <div class="skill"> <div class="outer"> <div class="inner"> <div id="number"></div> </div> </div> <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="160px" height="160px"> <circle class="o1" cx="80" cy="80" r="70" stroke-linecap="round" /> </svg> </div> <script> const skillsSection = document.getElementById('skills'); const circle = document.querySelector('.o1'); const number = document.getElementById('number'); let animationTriggered = false; // 标记动画是否已执行,防止重复触发 // 判断元素是否进入视口的工具函数 function isElementInViewport(el) { const rect = el.getBoundingClientRect(); // 元素顶部不超过视口底部,且元素底部不低于视口顶部,即为进入视口 return rect.top <= window.innerHeight && rect.bottom >= 0; } // 滚动事件处理逻辑 function handleScroll() { if (isElementInViewport(skillsSection) && !animationTriggered) { animationTriggered = true; // 给圆圈添加动画类,启动描边动画 circle.classList.add('animate-circle'); // 启动数字计数动画 let counter = 0; const countTimer = setInterval(() => { if (counter === 95) { clearInterval(countTimer); } else { counter++; number.textContent = `${counter}%`; } }, 20); } } // 页面加载完成后先检查一次,避免区域已在视口但动画不启动 handleScroll(); // 绑定滚动监听 window.addEventListener('scroll', handleScroll); </script> </section>
关键细节说明
isElementInViewport:通过getBoundingClientRect()获取元素相对于视口的位置,精准判断元素是否进入视野animationTriggered:一旦动画执行就标记为true,避免用户反复滚动时重复触发动画和计数- 初始化调用
handleScroll():处理页面加载时目标区域已经在视口内的场景,确保动画能正常启动
内容的提问来源于stack exchange,提问作者Tabshir
相关产品推荐
相关产品推荐

