You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现滚动到指定区域时触发动画效果?

实现滚动到指定区域才触发动画的方案

我在页面的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 21:36:21