首页 > 解决方案 > 每次迭代后更改动画持续时间

问题描述

所以我有这些移动的动画盒子。它们从底部无限移动到顶部。到达顶峰后,他们重新开始。我最初可以通过一些 sass 和它们的 random() 函数来改变它们的大小和速度。但是每次都以相同的速度前进,所以看起来很陈旧。

所以我尝试使用 javascript 在每次动画时改变每个框的持续时间。我这样做了:

let ignBox = document.querySelectorAll('.ign-box');
  let $rand = 0;
  ignBox.forEach(box =>{
    box.addEventListener('animationiteration', function(){

       $rand = (Math.floor(Math.random() * 20) + 3);
      console.log(this);
        this.style.animationDuration =  $rand + 's';
    });
  });

有用。但它为每个项目触发了很多次。似乎动画持续时间的更改立即再次触发了该事件!所以一个项目可能有 8s 然后它跳到 20s 然后到 5s。启用 JS 后,他们现在跳起来很不稳定。这是一个代码笔: https ://codepen.io/saltnpixels/pen/yqzZBb

标签: javascriptcssanimationsass

解决方案


这是因为animationiteration在每次新迭代开始时触发,并更改animationDuration实际重新启动动画,因此它进入半无限循环。

一种方法是仅运行 css 动画 1 次,然后在animationend事件中更改animationDurationand并重新启动动画。

CSS:

.animated{
  animation: slowMoveUp 3s linear 1;
}

js:

//change box animation times to vary things up
  let ignBox = document.querySelectorAll('.ign-box');
  let $rand = 0;
  ignBox.forEach(box =>{
    box.classList.add("animated");
    box.addEventListener('animationend', function(){
      this.classList.remove("animated");
      $rand = (Math.floor(Math.random() * 20) + 3);
      console.log(this);
      this.style.animationDuration =  $rand + 's';
      void this.offsetWidth; // hack to reflow css animation
      this.classList.add("animated");
    });
  });

归功于这个关于如何重新启动 css 动画和 hack 的链接。


推荐阅读