每次迭代的随机CSS动画时间 [英] Random CSS animation time on each iteration

查看:173
本文介绍了每次迭代的随机CSS动画时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试在每次迭代中设置随机动画时间。我设置了CSS自定义属性-动画时间使用JS在每次动画迭代中随机更改。



  let square = document.getElementById('square'); let time; square.addEventListener('animationiteration',duration); function duration(){time = Math.random()+ 1; square.style.setProperty(’-动画时间’,时间+’s); console.log(time);}  

 :root {-动画时间:5秒; --color-1:#ff0000; --color-2:#ffee00;} @ keyframes射击{0%{background-color:var(-color-1); } 100%{background-color:var(-color-2); }}#square {width:100px;高度:100px;动画:fire var(-animation-time)缓解交替无限;}  

 < div id = square>< / div>  



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



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

解决方案

更改 animation-duration ,您不仅可以更改每次迭代的执行方式,还可以更改整个动画。例如,如果您将 3s 作为持续时间,则第一次迭代将花费 3s ,并且如果迭代时间为 3s (迭代结束),您将更改为 5s ,就好像您创建了另一个动画,该动画将持续5s并跳至该动画的新状态新动画是 3s 5s



此处是一个更好地说明问题的示例。我将继续增加持续时间,并且您会注意到,一旦到达迭代的末尾,您将返回到先前的状态,因为您增加了持续时间,然后您将再次到达最后一个状态,并且您将返回,依此类推。 / p>

这就像某人正在进入 100%状态,而您一直在增加该状态。



  let square = document.getElementById('square'); let time = 1 ; square.addEventListener('animationiteration',duration); function duration(){time * = 2; square.style.setProperty(’-动画时间’,时间+’s); console.log(time);}  

 :root {- -动画时间:1秒;} @关键帧触发{0%{背景颜色:红色; } 50%{背景:黄色; } 100%{background-color:黑色; }}#square {width:100px;高度:100px;动画:fire var(-animation-time)缓解无限交替;}  

 < div id = square>< / div>  



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






正在发生同样的情况代码,但是以更复杂的方式进行,因为您增加/减少了持续时间。减少持续时间将使您跳至下一个迭代和替代状态。



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



以可视方式说明此处发生的情况是一个动画,我将在其中动画您的动画

的时间轴

  .box {height:50px;边框:1px实线;背景:/ *这将说明当前状态* / linear-gradient(green,green)left / 2px 100%no-repeat,/ *这是我们的动画,持续时间最初为5s(50px)* / linear-gradient(向右,黄色,红色,红色,黄色)向左/ 100px 100%;动画:移动10s线性无限,/ *这是当前状态* /更改2s step(3)无限/ *这是动画持续时间的变化* /; / ** /} @关键帧将{移动到{background-position:right,left; }} @ keyframes更改{到{background-size:2px 100%,40px 100%; }}  

 < div class = box> < / div>  



您可以看到我们不是更改当前状态(用绿线表示),但我们正在更改整个动画,使当前状态随机以不同的颜色跳跃。






获得所需内容的一个想法是考虑过渡和类切换:



  let square = document.getElementById('square'); let time; / *我们最初添加了该类以触发转换* / setTimeout(function(){square.classList.toggle('change')}, 10); square.addEventListener('transitionend',duration); / *完成转换后,我们切换该类以开始另一个* / function duration(){time = Math.r andom()+ 1; square.style.setProperty(’-动画时间’,时间+’s); square.classList.toggle('change'); console.log(time);}  

 :root {- -动画时间:1秒; --color-1:#ff0000; --color-2:#ffee00;}#square {宽度:100px;高度:100px;过渡:var(-animation-time)easy; background-color:var(-color-1);}#square.change {background-color:var(-color-2);}  

 < div id = square>< / div>  


Trying to set a random animation time on each iteration. I set a CSS custom property --animation-time changed randomly each animation iteration with 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>

The duration of animation is set to time = Math.random() + 1; so, the iterations should never have less than 1 second. However, it hapens sometimes very quickly. Why?

Here is a CodePen: https://codepen.io/aitormendez/pen/YbvvKw

解决方案

When you change the animation-duration you will not simply change how each iteration will take but you will change the whole animation. If for example you have 3s as a duration so the first iteration will take 3s and if at 3s (iterationend) you change to 5s it's like you create another animation where the iteration will last 5s and you jump to a new state of that new animation which is 3s of 5s.

Here is an example to better illustrate the issue. I will keep increasing the duration and you will notice that once you reach the end of the iteration you will get back to a previous state because you increased the duration then you will reach again the last state and you will get back and so on.

It's like someone is running to the 100% state and you keep increasing that state.

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>

In the above example I am multiplying the duration by 2 so each time I jump back to start from the 50% state and once I reach the 100% I will repeat the same again.


The same is happening with your code but in a more complex way since you are increasing/decreasing the duration. Decreasing the duration will make you jump to the next iteration and the alternate state.

In other words, You will end with a random flickering animation.

To visually illustrate what is happening here is an animation where I will animate the timeline of your animation

.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>

You can see that we aren't changing the current state (illustrated by the green line) but we are changing the whole animation making the current state jumping in different color randomly.


One idea to obtain what you want is to consider transition and class toggling:

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);
}

<div id="square"></div>

这篇关于每次迭代的随机CSS动画时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆