如何触发同一动画且不中断已运行的动画实例
解决方案
问题根源在于你复用了同一个子弹元素,新触发的动画会覆盖旧元素的状态,导致前序动画中断。要实现叠加效果,每次触发时需要创建新的子弹元素,让每个元素独立执行动画。
修改后的完整代码
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
相关产品推荐
相关产品推荐

