Как анимировать позиции divs с помощью CSS один за другим?

#css #css-animations

#css #css-анимации

Вопрос:

Я хочу сделать бесконечную анимацию CSS на черных кругах. Если один черный круг анимируется сверху или снизу, другие не должны быть. И если эта анимация снова получит 0% (остановка), должна начаться следующая. Если анимация последнего элемента остановится, должен начаться первый.

Ниже приведен пример кода, с которым я работаю, я не могу понять, как остановить анимацию, если анимируется другой круг.

 .wrapper {
  display: flex;
}

.item {
  background: #000;
  width: 50px;
  height: 50px;
  margin: 20px;
  border-radius: 50%;
  position: relative;
}

.wrapper .item {
    animation: mymove 3s infinite;
}
.wrapper .item:nth-child(2) {
    animation: mymove 3s infinite 1s;
}
.wrapper .item:nth-child(3) {
    animation: mymove 3s infinite 2s;
}
.wrapper .item:nth-child(4) {
    animation: mymove 3s infinite 3s;
}
.wrapper .item:nth-child(5) {
    animation: mymove 3s infinite 4s;
}
.wrapper .item:nth-child(6) {
    animation: mymove 3s infinite 5s;
}
@keyframes mymove {
  0%   {top: 0px;}
  50%  {top: -15px;}
  100% {top: 0px;}
} 
 <div class='wrapper'>

<div class="item">

</div>
<div class="item">

</div>
<div class="item">

</div>
<div class="item">

</div>
<div class="item">

</div>

</div> 

Ответ №1:

Вот другая идея, использующая один элемент и фон. У нас есть 5 радиальных градиентов, размещенных в разных горизонтальных положениях ( calc(x*100%/4) ), и все они начинаются снизу ( 100% ), затем анимация перемещает их один за другим из 100% (снизу) в 0% (сверху)

 .wrapper {
  --c:radial-gradient(circle farthest-side, #000 97%,transparent 100%);

  display: flex;
  height:65px; /* this will define the area of movement (bigger than circle sizes) */
  width:350px;
  background:
    var(--c) calc(0*100%/4) 100%, /* circle X Y */
    var(--c) calc(1*100%/4) 100%,
    var(--c) calc(2*100%/4) 100%,
    var(--c) calc(3*100%/4) 100%,
    var(--c) calc(4*100%/4) 100%;
  background-size:50px 50px; /* width height of the circles */
  background-repeat:no-repeat;
  margin:10px;
  animation: mymove 5s infinite; 
}

@keyframes mymove {
  0%  {background-position: calc(0*100%/4) 100%, calc(1*100%/4) 100%, calc(2*100%/4) 100%, calc(3*100%/4) 100%, calc(4*100%/4) 100%;}
  10% {background-position: calc(0*100%/4)   0%, calc(1*100%/4) 100%, calc(2*100%/4) 100%, calc(3*100%/4) 100%, calc(4*100%/4) 100%;}
  20% {background-position: calc(0*100%/4) 100%, calc(1*100%/4) 100%, calc(2*100%/4) 100%, calc(3*100%/4) 100%, calc(4*100%/4) 100%;}
  30% {background-position: calc(0*100%/4) 100%, calc(1*100%/4)   0%, calc(2*100%/4) 100%, calc(3*100%/4) 100%, calc(4*100%/4) 100%;}
  40% {background-position: calc(0*100%/4) 100%, calc(1*100%/4) 100%, calc(2*100%/4) 100%, calc(3*100%/4) 100%, calc(4*100%/4) 100%;}
  50% {background-position: calc(0*100%/4) 100%, calc(1*100%/4) 100%, calc(2*100%/4)   0%, calc(3*100%/4) 100%, calc(4*100%/4) 100%;}
  60% {background-position: calc(0*100%/4) 100%, calc(1*100%/4) 100%, calc(2*100%/4) 100%, calc(3*100%/4) 100%, calc(4*100%/4) 100%;}
  70% {background-position: calc(0*100%/4) 100%, calc(1*100%/4) 100%, calc(2*100%/4) 100%, calc(3*100%/4)   0%, calc(4*100%/4) 100%;}
  80% {background-position: calc(0*100%/4) 100%, calc(1*100%/4) 100%, calc(2*100%/4) 100%, calc(3*100%/4) 100%, calc(4*100%/4) 100%;}
  90% {background-position: calc(0*100%/4) 100%, calc(1*100%/4) 100%, calc(2*100%/4) 100%, calc(3*100%/4) 100%, calc(4*100%/4)   0%;}
  100%{background-position: calc(0*100%/4) 100%, calc(1*100%/4) 100%, calc(2*100%/4) 100%, calc(3*100%/4) 100%, calc(4*100%/4) 100%;}
} 
 <div class='wrapper'>

</div> 

Или вы обновляете свой код, как показано ниже:

 .wrapper {
  display: flex;
}

.item {
  background: #000;
  width: 50px;
  height: 50px;
  margin: 20px;
  border-radius: 50%;
  position: relative;
}

.wrapper .item {
  animation: mymove-1 5s infinite;
}
.wrapper .item:nth-child(2) {animation-name: mymove-2;}
.wrapper .item:nth-child(3) {animation-name: mymove-3;}
.wrapper .item:nth-child(4) {animation-name: mymove-4;}
.wrapper .item:nth-child(5) {animation-name: mymove-5;}

@keyframes mymove-1 {
  0% {top: 0px;}
  10% {top: -15px;}
  20% {top: 0px;}
}
@keyframes mymove-2 {
  20% {top: 0px;}
  30% {top: -15px;}
  40% {top: 0px;}
}
@keyframes mymove-3 {
  40% {top: 0px;}
  50% {top: -15px;}
  60% {top: 0px;}
}
@keyframes mymove-4 {
  60% {top: 0px;}
  70% {top: -15px;}
  80% {top: 0px;}
}
@keyframes mymove-5 {
  80% {top: 0px;}
  90% {top: -15px;}
  100%{top: 0px;}
} 
 <div class='wrapper'>

  <div class="item">

  </div>
  <div class="item">

  </div>
  <div class="item">

  </div>
  <div class="item">

  </div>
  <div class="item">

  </div>

</div> 

Комментарии:

1. Это очень хорошая идея, но в моем случае я не могу ее использовать. На моих сайтах мои круги назначаются определенному контенту и не могут быть анимированы с помощью фона, их можно анимировать только с использованием их положения.

2. @matep05 проверьте обновление, добавлена еще одна идея

3. Обновленная версия будет полезна для моего проекта, большое спасибо. Дополнительно: можно ли остановить анимацию для всех кругов, кроме того, который наведен?

4. @matep05 это требует дополнительной работы. Я советую вам рассмотреть другой вопрос для этого, поскольку он выходит за рамки здесь, и вы получите лучшую помощь с новым вопросом