【问题标题】:Random CSS animation time on each iteration每次迭代的随机 CSS 动画时间
【发布时间】:2019-05-27 23:54:58
【问题描述】:

尝试在每次迭代中设置随机动画时间。我设置了一个 CSS 自定义属性 --animation-time ,每次动画迭代都会随机更改 JS。

let square = document.getElementById('square');
let time;

square.addEventListener('animationiteration', duration);

function duration() {
  time = Math.random() + 1;
  square.style.setProperty('--animation-time', time + 's');
  console.log(time);
}
:root {
  --animation-time: 5s;
  --color-1: #ff0000;
  --color-2: #ffee00;
}

@keyframes fire {
  0% {
    background-color: var(--color-1);
  }
  100% {
    background-color: var(--color-2);
  }
}

#square {
  width: 100px;
  height: 100px;
  animation: fire var(--animation-time) ease alternate infinite;
}
<div id="square"></div>

动画的持续时间设置为time = Math.random() + 1;,因此迭代的时间不应少于 1 秒。但是,它有时会很快发生。为什么?

这是一个 CodePen:https://codepen.io/aitormendez/pen/YbvvKw

【问题讨论】:

    标签: javascript css css-animations


    【解决方案1】:

    当您更改animation-duration 时,您不仅会更改每次迭代的方式,还会更改整个动画。例如,如果您有3s 作为持续时间,那么第一次迭代将采用3s,如果在3s(迭代结束)您更改为5s,这就像您创建另一个动画,其中迭代将持续 5 秒然后您跳转到那个新动画的新状态,即3s of 5s

    这是一个更好地说明问题的示例。我将继续增加持续时间,您会注意到,一旦您到达迭代结束,您将回到之前的状态,因为您增加了持续时间,然后您将再次到达最后一个状态,您将返回等等。

    就像有人正在运行到100% 状态,而你不断增加该状态。

    let square = document.getElementById('square');
    let time = 1;
    
    square.addEventListener('animationiteration', duration);
    
    function duration() {
      time*=2;
      square.style.setProperty('--animation-time', time + 's');
      console.log(time);
    }
    :root {
      --animation-time: 1s;
    }
    
    @keyframes fire {
      0% {
        background-color: red;
      }
      50% {
        background:yellow;
      }
      100% {
        background-color: black;
      }
    }
    
    #square {
      width: 100px;
      height: 100px;
      animation: fire var(--animation-time) ease infinite alternate;
    }
    <div id="square"></div>

    在上面的示例中,我将持续时间乘以 2,因此每次我跳回从 50% 状态开始,一旦我到达 100%,我将再次重复相同的操作。


    您的代码也会发生同样的情况,但方式更复杂,因为您正在增加/减少持续时间。减少持续时间将使您跳到下一个迭代和备用状态。

    换句话说,您将以随机闪烁的动画结束。

    为了直观地说明这里发生的事情是一个动画,我将为你的动画的时间轴制作动画

    .box {
      height:50px;
      border:1px solid;
      background:
        /* This will illustrate the current state */
        linear-gradient(green,green) left/2px 100% no-repeat,
        /* This is our animation with a duration of 5s (50px) intially*/
        linear-gradient(to right,yellow,red,red,yellow) left/100px 100%;
       
      animation:
        move 10s linear infinite, /* This is the current state*/
        change 2s steps(3) infinite /* this is the change of the animation duration*/
      ; /**/
    }
    
    @keyframes move {
      to {
        background-position:right,left;
      }
    }
    @keyframes change {
      to {
        background-size:2px 100%,40px 100%;
      }
    }
    <div class="box">
    
    </div>

    您可以看到我们并没有改变当前状态(如绿线所示),但我们正在改变整个动画,使当前状态以不同的颜色随机跳跃。


    获得你想要的一个想法是考虑转换和类切换:

    let square = document.getElementById('square');
    let time;
    
    /* We intially add the class to trigger the transition*/
    setTimeout(function(){square.classList.toggle('change')},10);
    
    square.addEventListener('transitionend', duration);
    
    /* When the transition is done we toggle the class to start another one*/
    function duration() {
      time = Math.random() + 1;
      square.style.setProperty('--animation-time', time + 's');
      square.classList.toggle('change');
      console.log(time);
    }
    :root {
      --animation-time: 1s;
      --color-1: #ff0000;
      --color-2: #ffee00;
    }
    
    #square {
      width: 100px;
      height: 100px;
      transition: var(--animation-time) ease;
      background-color: var(--color-1);
    }
    
    #square.change {
      background-color: var(--color-2);
    }
    &lt;div id="square"&gt;&lt;/div&gt;

    【讨论】:

      猜你喜欢
      • 2019-01-04
      • 2016-05-17
      • 2012-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-04
      相关资源
      最近更新 更多