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

如何实现多小球依次动画的CSS序列循环播放?

实现小球动画循环播放的解决方案

问题描述

现有一段CSS+HTML代码,实现了4个小球依次执行一次动画的序列,但当前仅能播放一次,需要实现以下循环效果:

  • 序列开始
  • 小球1执行一次动画
  • 延迟1秒
  • 小球2执行一次动画
  • 延迟1秒
  • 小球3执行一次动画
  • 延迟1秒
  • 小球4执行一次动画
  • 延迟1秒
  • 序列从第一步重新开始

纯CSS解决方案

通过调整动画总周期与关键帧的时间占比,让整个序列在一个循环周期内完成,规避animation-delay仅首次生效的问题。

完整代码

<div class="ball" id="ball-1"></div>
<div class="ball" id="ball-2"></div>
<div class="ball" id="ball-3"></div>
<div class="ball" id="ball-4"></div>
/* 总周期设为4秒,每个小球在对应1秒窗口内执行动画 */
@keyframes ball1 {
  0% { transform: translateX(0px); opacity: 0%; }
  6.25% { opacity: 100%; }
  12.5% { transform: translateX(120px); opacity: 0%; }
  12.51%, 100% { transform: translateX(120px); opacity: 0%; }
}

@keyframes ball2 {
  0%, 25% { transform: translateX(0px); opacity: 0%; }
  31.25% { opacity: 100%; }
  37.5% { transform: translateX(160px); opacity: 0%; }
  37.51%, 100% { transform: translateX(160px); opacity: 0%; }
}

@keyframes ball3 {
  0%, 50% { transform: translateX(0px); opacity: 0%; }
  56.25% { opacity: 100%; }
  62.5% { transform: translateX(200px); opacity: 0%; }
  62.51%, 100% { transform: translateX(200px); opacity: 0%; }
}

@keyframes ball4 {
  0%, 75% { transform: translateX(0px); opacity: 0%; }
  81.25% { opacity: 100%; }
  87.5% { transform: translateX(240px); opacity: 0%; }
  87.51%, 100% { transform: translateX(240px); opacity: 0%; }
}

.ball {
  background: black;
  width: 20px;
  height: 20px;
  border-radius: 20px;
  margin: 10px;
  animation-duration: 4s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}

#ball-1 { animation-name: ball1; }
#ball-2 { animation-name: ball2; }
#ball-3 { animation-name: ball3; }
#ball-4 { animation-name: ball4; }

核心逻辑:将总循环周期设为4秒,每个小球的动画仅在对应1秒时间段内执行,其余时间保持终点状态,实现自动循环序列。


JavaScript解决方案

通过监听动画结束事件,手动控制每个小球的触发时机,精准匹配需求的序列逻辑。

完整代码

<div class="ball" id="ball-1"></div>
<div class="ball" id="ball-2"></div>
<div class="ball" id="ball-3"></div>
<div class="ball" id="ball-4"></div>
@keyframes ball1 {
  0% { transform: translateX(0px); opacity: 0%; }
  50% { opacity: 100%; }
  100% { transform: translateX(120px); opacity: 0%; }
}

@keyframes ball2 {
  0% { transform: translateX(0px); opacity: 0%; }
  50% { opacity: 100%; }
  100% { transform: translateX(160px); opacity: 0%; }
}

@keyframes ball3 {
  0% { transform: translateX(0px); opacity: 0%; }
  50% { opacity: 100%; }
  100% { transform: translateX(200px); opacity: 0%; }
}

@keyframes ball4 {
  0% { transform: translateX(0px); opacity: 0%; }
  50% { opacity: 100%; }
  100% { transform: translateX(240px); opacity: 0%; }
}

.ball {
  background: black;
  width: 20px;
  height: 20px;
  border-radius: 20px;
  margin: 10px;
  animation-duration: 1s;
  animation-iteration-count: 1;
  animation-fill-mode: forwards;
}
const balls = [document.getElementById('ball-1'), document.getElementById('ball-2'), document.getElementById('ball-3'), document.getElementById('ball-4')];
const animations = ['ball1', 'ball2', 'ball3', 'ball4'];

function playSequence() {
  let index = 0;
  
  function playNext() {
    if (index >= balls.length) {
      setTimeout(playSequence, 1000);
      return;
    }
    
    const ball = balls[index];
    // 重置动画状态
    ball.style.animation = 'none';
    void ball.offsetWidth;
    ball.style.animation = `${animations[index]} 1s forwards`;
    
    // 动画结束后触发下一个
    ball.addEventListener('animationend', function handler() {
      ball.removeEventListener('animationend', handler);
      index++;
      setTimeout(playNext, 1000);
    }, { once: true });
  }
  
  playNext();
}

// 启动序列
playSequence();

核心逻辑:逐个触发小球动画,监听动画结束事件,延迟1秒后播放下一个,全部完成后再延迟1秒重启序列,完全匹配需求步骤。


内容的提问来源于stack exchange,提问作者coce

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 11:16:01