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

如何触发同一动画且不中断已运行的动画实例

解决方案

问题根源在于你复用了同一个子弹元素,新触发的动画会覆盖旧元素的状态,导致前序动画中断。要实现叠加效果,每次触发时需要创建新的子弹元素,让每个元素独立执行动画。

修改后的完整代码

HTML

<!-- 新增容器用于存放所有子弹元素 -->
<div class="bullets-container"></div>

CSS

.bullets-container {
  position: relative;
  width: 100%;
  height: 100vh; /* 占满视口高度,确保子弹在可视区域内 */
}

.bullet {
  width: 50px;
  height: 50px;
  position: absolute;
  animation: bullet linear 5s forwards; /* 使用forwards让动画结束后保持最后状态 */
  filter: hue-rotate(186deg);
}

@keyframes bullet {
  0% {
    left: 0%;
    opacity: 0%;
  }
  5% {
    left: 5%;
    opacity: 100%;
  }
  20% {
    left: 15%;
    opacity: 100%;
  }
  70% {
    opacity: 0%;
  }
  100% {
    left: 70%;
    opacity: 0%;
  }
}

/* 保留Y轴位置类 */
.posY1 { bottom: 50%; }
.posY2 { bottom: 40%; }
.posY3 { bottom: 30%; }
.posY4 { bottom: 20%; }
.posY5 { bottom: 10%; }

JavaScript

// 改成可重复调用的函数
function createRandomBullet() {
  const bulletPosY = ["posY1", "posY2", "posY3", "posY4", "posY5"];
  const randomIndex = Math.floor(Math.random() * bulletPosY.length);
  
  // 创建新的子弹元素
  const bullet = document.createElement('img');
  bullet.src = "https://i.sstatic.net/qgNyF.png?s=328&g=1";
  bullet.classList.add('bullet', bulletPosY[randomIndex]);
  
  // 插入到容器中
  document.querySelector('.bullets-container').appendChild(bullet);
  
  // 动画结束后移除元素,避免内存占用
  bullet.addEventListener('animationend', () => {
    bullet.remove();
  });
}

// 示例:每隔1秒触发一次,测试叠加效果
setInterval(createRandomBullet, 1000);

关键修改点

  • 新增容器:用.bullets-container统一管理所有子弹元素,确保定位正确。
  • 动态创建元素:每次调用createRandomBullet时生成新的<img>,每个元素独立执行动画,互不干扰。
  • 自动清理元素:监听animationend事件,动画结束后移除子弹元素,防止DOM节点过多导致性能问题。
  • 动画属性优化:给.bullet添加forwards,让动画结束后保持最后一帧状态(透明且移出位置)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 05:46:05