Чистая анимация вращения CSS прервана в бесконечном цикле - PullRequest
4 голосов
/ 20 июня 2019

Прошло много времени с тех пор, как я задал вопрос здесь. Извините, если я что-то не так делаю.

У меня проблема с CSS-анимацией . Я бы хотел, чтобы моя анимация продолжала повторяться самостоятельно, но без потери начальных эффектов . Однако похоже, что в моем коде или в поведении CSS-анимации есть ошибка.

После завершения первой 2 анимации поворота (вращение, вращение) определено. Цикл начинается, но новая анимация уже не такая, как раньше.

Моя цель состоит в том, чтобы создать анимацию поворота на 6 прямоугольниках в порядке , по одному за раз. Когда все ящики повернуты, они должны снова начать возвращаться в исходное состояние по порядку, один за другим.

Код:

/* -------------------------------------------------------- */
#loader {
  width: 240px;
  height: 100px;
}

.inner {
  position: relative;
  width: 100%;
  height: 100%;
  text-align: center;
  transition: transform 2s;
  transform-style: preserve-3d;
  background-color: transparent;
}

.front,
.back {
  position: absolute;
  width: 80px;
  height: 50px;
  backface-visibility: hidden;
}


/* -------------------------------------------------------- */

#loader1 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader1 .inner {
  animation: spin 10s ease 0s infinite, spinback 10s ease 10s infinite;
  -webkit-animation: spin 10s ease 0s infinite, spinback 10s ease 10s infinite;
}

#loader1 .front {
  background-color: #db9834;
}

#loader1 .back {
  background-color: #3498db;
  transform: rotateY(180deg);
}


/* -------------------------------------------------------- */

#loader2 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader2 .inner {
  animation: spin 10s ease 1s infinite, spinback 10s ease 11s infinite;
  -webkit-animation: spin 10s ease 1s infinite, spinback 10s ease 11s infinite;
}

#loader2 .front {
  background-color: #db8834;
}

#loader2 .back {
  background-color: #3488db;
  transform: rotateY(180deg);
}


/* -------------------------------------------------------- */

#loader3 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader3 .inner {
  animation: spin 10s ease 2s infinite, spinback 10s ease 12s infinite;
  -webkit-animation: spin 10s ease 2s infinite, spinback 10s ease 12s infinite;
}

#loader3 .front {
  background-color: #db7834;
}

#loader3 .back {
  background-color: #3478db;
  transform: rotateY(180deg);
}


/* -------------------------------------------------------- */

#loader4 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader4 .inner {
  animation: spin 10s ease 3s infinite, spinback 10s ease 13s infinite;
  -webkit-animation: spin 10s ease 3s infinite, spinback 10s ease 13s infinite;
}

#loader4 .front {
  background-color: #db6834;
}

#loader4 .back {
  background-color: #3468db;
  transform: rotateY(180deg);
}


/* -------------------------------------------------------- */

#loader5 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader5 .inner {
  animation: spin 10s ease 4s infinite, spinback 10s ease 14s infinite;
  -webkit-animation: spin 10s ease 4s infinite, spinback 10s ease 14s infinite;
}

#loader5 .front {
  background-color: #db5834;
}

#loader5 .back {
  background-color: #3458db;
  transform: rotateY(180deg);
}


/* -------------------------------------------------------- */

#loader6 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader6 .inner {
  animation: spin 10s ease 5s infinite, spinback 10s ease 15s infinite;
  -webkit-animation: spin 10s ease 5s infinite, spinback 10s ease 15s infinite;
}

#loader6 .front {
  background-color: #db4834;
}

#loader6 .back {
  background-color: #3448db;
  transform: rotateY(180deg);
}

@-webkit-keyframes spin {
  0% {
    -webkit-transform: rotateY(0deg);
  }
  16% {
    -webkit-transform: rotateY(180deg);
  }
  100% {
    -webkit-transform: rotateY(180deg);
  }
}

@keyframes spin {
  0% {
    -webkit-transform: rotateY(0deg);
  }
  16% {
    -webkit-transform: rotateY(180deg);
  }
  100% {
    -webkit-transform: rotateY(180deg);
  }
}

@-webkit-keyframes spinback {
  0% {
    -webkit-transform: rotateY(180deg);
  }
  16% {
    -webkit-transform: rotateY(0deg);
  }
  100% {
    -webkit-transform: rotateY(0deg);
  }
}

@keyframes spinback {
  0% {
    -webkit-transform: rotateY(180deg);
  }
  16% {
    -webkit-transform: rotateY(0deg);
  }
  100% {
    -webkit-transform: rotateY(0deg);
  }
}
<div id="loader">
  <div id="loader1">
    <div class="inner">
      <div class="front">
      </div>
      <div class="back"> </div>
    </div>
  </div>
  <div id="loader2">
    <div class="inner">
      <div class="front"> </div>
      <div class="back"> </div>
    </div>
  </div>
  <div id="loader3">
    <div class="inner">
      <div class="front"> </div>
      <div class="back"> </div>
    </div>
  </div>
  <div id="loader4">
    <div class="inner">
      <div class="front"> </div>
      <div class="back"> </div>
    </div>
  </div>
  <div id="loader5">
    <div class="inner">
      <div class="front"> </div>
      <div class="back"> </div>
    </div>
  </div>
  <div id="loader6">
    <div class="inner">
      <div class="front"> </div>
      <div class="back"> </div>
    </div>
  </div>
</div>

Просто чтобы сделать его более понятным, я пытаюсь применить метод флипкарты css:

https://www.w3schools.com/howto/howto_css_flip_card.asp

На div для того, чтобы создать вид, будто что-то загружается ...

Анимация дает только время для запуска ключевых кадров в правильное время, тогда в ключевых кадрах я вращаю div и помещаю время ожидания, пока oter div не завершит свое вращение. Таким образом, формула составляет 6 блоков за 10 секунд, что должно быть где-то между (от 0% до 100%), так что (100/6 = 16,6), что я беру анимацию, как должно заканчиваться в 16% времени анимации.

Ответы [ 2 ]

5 голосов
/ 20 июня 2019

Сначала я бы упростил ваш код и использовал бы меньше HTML / CSS. Тогда я бы рассмотрел только одну анимацию, где у меня будут оба состояния.

Анимация будет такой: первый бросок, затем мы сохраняем первый цвет, затем второй снимок, затем мы сохраняем второй цвет. Он делится на 12 временных интервалов (1 + 5 + 1 + 5) (1+5 = 6, что является количеством делений)

Если длительность равна S, то задержка должна быть кратна одному интервалу S/12. Обратите внимание, что я использовал перспективу внутри преобразования, чтобы избежать лишнего элемента:

#loader {
  width: 240px;
  height: 100px;
  display: flex;
  flex-wrap: wrap;
}

#loader>div {
  width: calc(100%/3);
  position: relative;
  transform-style: preserve-3d;
  animation: spin 6s linear var(--delay, 0s) infinite;
}

#loader>div:before,
#loader>div:after {
  content: "";
  position: absolute;
  top:0;
  left:0;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  background-color: var(--front, #db9834);
}

#loader>div:after {
  background-color: var(--back, #3498db);
  transform: rotateY(180deg);
}


/* -------------------------------------------------------- */

#loader>div:nth-child(2) {
  --front: #db8834;
  --back: #3488db;
  --delay: 0.5s;
}

#loader>div:nth-child(3) {
  --front: #db7834;
  --back: #3478db;
  --delay: 1s;
}

#loader>div:nth-child(4) {
  --front: #db6834;
  --back: #3468db;
  --delay: 1.5s;
}

#loader>div:nth-child(5) {
  --front: #db5834;
  --back: #3458db;
  --delay: 2s;
}

#loader>div:nth-child(6) {
  --front: #db4834;
  --back: #3448db;
  --delay: 2.5s;
}


@keyframes spin {
  0% {
    transform:perspective(500px) rotateY(0deg);
  }
  8.33%,
  50%{
    transform:perspective(500px) rotateY(180deg);
  }
  58.33% {
    transform:perspective(500px) rotateY(0deg);
  }
}
<div id="loader">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

Связанные вопросы для более подробной информации о разнице между perspective и perspective()

CSS 3d-преобразование не работает, если в конце свойства установлена ​​перспектива

перспектива и перемещениеZ по диагонали


Мы можем упростить еще больше, если изменим окраску div при вращении вместо двух элементов. Изменение должно быть сделано в половине слота, где мы делаем переворот (первый и шестой) без какого-либо перехода, чтобы создать иллюзию:

#loader {
  width: 240px;
  height: 100px;
  display: flex;
  flex-wrap: wrap;
}

#loader>div {
  width: calc(100%/3);
  animation: 
    spin   6s linear var(--delay, 0s) infinite,
    colors 6s linear var(--delay, 0s) infinite;
  background-color: var(--front, #db9834);
}


/* -------------------------------------------------------- */

#loader>div:nth-child(2) {
  --front: #db8834;
  --back: #3488db;
  --delay: 0.5s;
}

#loader>div:nth-child(3) {
  --front: #db7834;
  --back: #3478db;
  --delay: 1s;
}

#loader>div:nth-child(4) {
  --front: #db6834;
  --back: #3468db;
  --delay: 1.5s;
}

#loader>div:nth-child(5) {
  --front: #db5834;
  --back: #3458db;
  --delay: 2s;
}

#loader>div:nth-child(6) {
  --front: #db4834;
  --back: #3448db;
  --delay: 2.5s;
}


@keyframes spin {
  0% {
    transform:perspective(500px) rotateY(0deg);
  }
  8.33%,
  50%{
    transform:perspective(500px) rotateY(180deg);
  }
  58.33% {
    transform:perspective(500px) rotateY(0deg);
  }
}
@keyframes colors {
  0%,4.15% {
    background-color: var(--front, #db9834);
  }
  4.16% {
    background-color: var(--back, #3498db);
  }
  54.15% {
    background-color: var(--back, #3498db);
  }
  54.16% {
    background-color: var(--front, #db9834);
  }
}
<div id="loader">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

Еще одно упрощение можно сделать с помощью фильтра, учитывая тот факт, что вы хотите, чтобы цвета были одинаковыми:

#loader {
  width: 240px;
  height: 100px;
  display: flex;
  flex-wrap: wrap;
}

#loader>div {
  width: calc(100%/3);
  animation: 
    spin   6s linear var(--delay, 0s) infinite,
    colors 6s linear var(--delay, 0s) infinite;
  background: 
    linear-gradient(#db9834 50%, #3498db 0);
  background-size: 100% 200%;
}


/* -------------------------------------------------------- */

#loader>div:nth-child(2) {
  filter: brightness(0.9);
  --delay: 0.5s;
}

#loader>div:nth-child(3) {
  filter: brightness(0.8);
  --delay: 1s;
}

#loader>div:nth-child(4) {
  filter: brightness(0.7);
  --delay: 1.5s;
}

#loader>div:nth-child(5) {
  filter: brightness(0.6);
  --delay: 2s;
}

#loader>div:nth-child(6) {
  filter: brightness(0.5);
  --delay: 2.5s;
}


@keyframes spin {
  0% {
    transform:perspective(500px) rotateY(0deg);
  }
  8.33%,
  50%{
    transform:perspective(500px) rotateY(180deg);
  }
  58.33% {
    transform:perspective(500px) rotateY(0deg);
  }
}
@keyframes colors {
  4.15% {
    background-position: top;
  }
  4.16%,
  54.15% {
    background-position:bottom;
  }
  54.16% {
    background-position: top;
  }

}
<div id="loader">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

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

0 голосов
/ 22 июня 2019

Подобная проблема уже была описана в SO: Как сделать так, чтобы объект не возвращался в исходное положение после запуска анимации? Проблема в том, что в начале анимации объект возвращается кего первоначальное состояние.Но я решил проблему по-другому: я просто объединил обе анимации в одну, и теперь оба обращения описываются одной функцией.Если вам определенно нужны обе анимации, то переделайте их, как указано в вопросе, на который я дал ссылку.Вот мой код:

#loader {
  width: 240px;
  height: 100px;
}

.inner {
  position: relative;
  width: 100%;
  height: 100%;
  text-align: center;
  transition: transform 2s;
  transform-style: preserve-3d;
  background-color: transparent;
}

.front,
.back {
  position: absolute;
  width: 80px;
  height: 50px;
  backface-visibility: hidden;
}

#loader1 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader1 .inner {
  animation: spin 20s ease 0s infinite;
  -webkit-animation: spin 20s ease 0s infinite;
}

#loader1 .front {
  background-color: #db9834;
}

#loader1 .back {
  background-color: #3498db;
  transform: rotateY(180deg);
}

/* -------------------------------------------------------- */

#loader2 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader2 .inner {
  animation: spin 20s ease 1s infinite;
  -webkit-animation: spin 20s ease 1s infinite;
}

#loader2 .front {
  background-color: #db8834;
}

#loader2 .back {
  background-color: #3488db;
  transform: rotateY(180deg);
}


/* -------------------------------------------------------- */

#loader3 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader3 .inner {
  animation: spin 20s ease 2s infinite;
  -webkit-animation: spin 20s ease 2s infinite;
}

#loader3 .front {
  background-color: #db7834;
}

#loader3 .back {
  background-color: #3478db;
  transform: rotateY(180deg);
}


/* -------------------------------------------------------- */

#loader4 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader4 .inner {
  animation: spin 20s ease 3s infinite;
  -webkit-animation: spin 20s ease 3s infinite;
}

#loader4 .front {
  background-color: #db6834;
}

#loader4 .back {
  background-color: #3468db;
  transform: rotateY(180deg);
}


/* -------------------------------------------------------- */

#loader5 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader5 .inner{ 
  animation: spin 20s ease 4s infinite;
  -webkit-animation: spin 20s ease 4s infinite;
}

#loader5 .front {
  background-color: #db5834;
}

#loader5 .back {
  background-color: #3458db;
  transform: rotateY(180deg);
}


/* -------------------------------------------------------- */

#loader6 {
  float: left;
  width: 80px;
  height: 50px;
  perspective: 1000px;
  background-color: transparent;
}

#loader6 .inner {
  animation: spin 20s ease 5s infinite;
  -webkit-animation: spin 20s ease 5s infinite;
}

#loader6 .front {
  background-color: #db4834;
}

#loader6 .back {
  background-color: #3448db;
  transform: rotateY(180deg);
}


@-webkit-keyframes spin {
  0% {
    -webkit-transform: rotateY(0deg);
  }
  8% {
    -webkit-transform: rotateY(180deg);
  }
  50% {
    -webkit-transform: rotateY(180deg);
  }
  
  58% {
    -webkit-transform: rotateY(0deg);
  }
  
  100% {
    -webkit-transform: rotateY(0deg);
  }
}

@keyframes spin {
  0% {
    -webkit-transform: rotateY(0deg);
  }
  8% {
    -webkit-transform: rotateY(180deg);
  }
  50% {
    -webkit-transform: rotateY(180deg);
  }
  
  58% {
    -webkit-transform: rotateY(0deg);
  }
  
  100% {
    -webkit-transform: rotateY(0deg);
  }
}
<div id="loader">
  <div id="loader1">
    <div class="inner">
      <div class="front">
      </div>
      <div class="back"> </div>
    </div>
  </div>
  <div id="loader2">
    <div class="inner">
      <div class="front"> </div>
      <div class="back"> </div>
    </div>
  </div>
  <div id="loader3">
    <div class="inner">
      <div class="front"> </div>
      <div class="back"> </div>
    </div>
  </div>
  <div id="loader4">
    <div class="inner">
      <div class="front"> </div>
      <div class="back"> </div>
    </div>
  </div>
  <div id="loader5">
    <div class="inner">
      <div class="front"> </div>
      <div class="back"> </div>
    </div>
  </div>
  <div id="loader6">
    <div class="inner">
      <div class="front"> </div>
      <div class="back"> </div>
    </div>
  </div>
</div>
...