纯CSS旋转动画在无限循环中损坏

时间:2019-06-20 08:59:22

标签: html css css-animations

自从我在这里问了问题已经有一段时间了。如果我做错任何事,请原谅。

我遇到 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 flipcard方法:

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

在div上以创建看起来像正在加载的外观...

动画仅给出了在正确的时间触发关键帧的时间,然后在关键帧中我旋转了div,并等待了一段时间,直到其他div完成其旋转。所以公式是10秒钟内有6个方框,它介于(0%到100%)之间,所以(100/6 = 16,6)可以让我选择动画,因为动画应在动画时间的16%处结束。

2 个答案:

答案 0 :(得分:5)

首先,我将简化您的代码并使用更少的HTML / CSS。然后,我将只考虑一个同时具有两种状态的动画。

动画将是:第一个翻转,然后我们保留第一种颜色,然后第二个filp,然后我们保留第二种颜色。它分为12个时隙(1 + 5 + 1 + 51+5 = 6,它是div的数量)

如果持续时间为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>


有关perspectiveperspective()之间区别的更多问题的相关问题

CSS 3d transform doesn't work if perspective is set in the end of property

perspective and translateZ moves diagonally


如果我们在旋转时更改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>

此结果与我使用随机过滤器并不完全相同,但是您可以轻松地尝试另一种过滤以获得所需的结果。

答案 1 :(得分:0)

在SO上已经描述了类似的问题:How to have the object not revert to its initial position after animation has run?问题是,在动画开始时,对象返回到其原始状态。但是我以不同的方式解决了这个问题:我将两个动画简单地组合为一个,现在两个反转都由一个函数描述。如果您确实需要两个动画,请重做它,如我给出的链接所述。这是我的代码:

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