应用 CSS3 动画时失去透视

Lost perspective when applying CSS3 animation

我正在尝试将 CSS3 变换应用于某些 HTML 元素,并注意到每当我尝试将关键帧动画应用于元素时,perspective 就会消失。

我放了两个屏幕,一个在添加动画之前 (1),另一个在添加动画之后 (2)。

添加动画前:

ul {
  width: 500px;
  list-style: none;
  padding: 0;
  margin: 0 auto;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -o-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-perspective: 300px;
  -moz-perspective: 300px;
  -o-perspective: 300px;
  perspective: 300px;
  transform: none;
}
ul li {
  display: inline-block;
  width: 60px;
  height: 200px;
  background: #333;
  margin: 0;
  padding: 0;
  -webkit-transform: rotate3d(1, 0, 0, 60deg);
  -moz-transform: rotate3d(1, 0, 0, 60deg);
  -o-transform: rotate3d(1, 0, 0, 60deg);
  transform: rotate3d(1, 0, 0, 60deg);
  box-shadow: 0px 0px 25px #666;
  z-index: 2
}
li:nth-child(1),
li:nth-child(3) {
  background: #666;
  width: 200px;
}
<ul>
  <li></li>
  <li></li>
  <li></li>
</ul>

Demo - Before animation is added

添加动画后:

ul {
  width: 500px;
  list-style: none;
  padding: 0;
  margin: 0 auto;
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  -o-transform-style: preserve-3d;
  transform-style: preserve-3d;
  -webkit-perspective: 300px;
  -moz-perspective: 300px;
  -o-perspective: 300px;
  perspective: 300px;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  -o-backface-visibility: hidden;
  backface-visibility: hidden;
  transform: none;
}
ul li {
  display: inline-block;
  width: 60px;
  height: 200px;
  background: #333;
  margin: 0;
  padding: 0;
  -webkit-transform: rotate3d(1, 0, 0, 60deg);
  -moz-transform: rotate3d(1, 0, 0, 60deg);
  -o-transform: rotate3d(1, 0, 0, 60deg);
  transform: rotate3d(1, 0, 0, 60deg);
  box-shadow: 0px 0px 25px #666;
  z-index: 2
}
li:nth-child(1),
li:nth-child(3) {
  background: #666;
  width: 200px;
}
li:nth-child(1) {
  -webkit-transform-origin: right center;
  -moz-transform-origin: right center;
  -o-transform-origin: right center;
  transform-origin: right center;
  -webkit-animation: wing1 1s infinite;
  -moz-animation: wing1 1s infinite;
  -o-animation: wing1 1s infinite;
  animation: wing1 1s infinite;
}
li:nth-child(3) {
  -webkit-transform-origin: left center;
  -moz-transform-origin: left center;
  -o-transform-origin: left center;
  transform-origin: left center;
  -webkit-animation: wing2 1s infinite;
  -moz-animation: wing2 1s infinite;
  -o-animation: wing2 1s infinite;
  animation: wing2 1s infinite;
}
@-webkit-keyframes wing1 {
  0% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
  50% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
  100% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
}
@-webkit-keyframes wing2 {
  0% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
  50% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
  100% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
}
@-moz-keyframes wing1 {
  0% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
  50% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
  100% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
}
@-moz-keyframes wing2 {
  0% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
  50% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
  100% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
}
@-o-keyframes wing1 {
  0% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
  50% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
  100% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
}
@-o-keyframes wing2 {
  0% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
  50% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
  100% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
}
@keyframes wing1 {
  0% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
  50% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
  100% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
}
@keyframes wing2 {
  0% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
  50% {
    -webkit-transform: rotate3d(0, 1, 0, -20deg);
    -moz-transform: rotate3d(0, 1, 0, -20deg);
    -o-transform: rotate3d(0, 1, 0, -20deg);
    transform: rotate3d(0, 1, 0, -20deg);
  }
  100% {
    -webkit-transform: rotate3d(0, 1, 0, 20deg);
    -moz-transform: rotate3d(0, 1, 0, 20deg);
    -o-transform: rotate3d(0, 1, 0, 20deg);
    transform: rotate3d(0, 1, 0, 20deg);
  }
}
<ul>
  <li></li>
  <li></li>
  <li></li>
</ul>

Demo - After animation is added

这里可能有什么问题?有哪位请推荐一下。

您看到的问题不是因为透视丢失或未应用,而是因为您的原始变换被动画关键帧中指定的值覆盖。

最初使用 rotate3d() 将元素(无动画)沿 X 轴旋转 60 度,但添加动画后,在 keyframes 中指定的唯一变换是旋转在 Y 轴上。与任何 CSS 属性 的情况一样,后续设置不会添加到原始设置,但它实际上会覆盖它,因此当应用动画时,X 轴的旋转无效。

为了克服这个问题,应该修改 keyframes 中的 transform 属性,使 X 轴旋转在整个动画过程中保持不变,而 Y 轴旋转单独随着产生像动画一样拍打翅膀的帧。

下面的代码片段应该是您所需要的。

ul {
  width: 500px;
  list-style: none;
  padding: 0;
  margin: 0 auto;
  transform-style: preserve-3d;
  perspective: 300px;
  backface-visibility: hidden;
  transform: none;
}
ul li {
  display: inline-block;
  width: 60px;
  height: 200px;
  background: #333;
  margin: 0;
  padding: 0;
  transform: rotate3d(1, 0, 0, 60deg);
  box-shadow: 0px 0px 25px #666;
  z-index: 2
}
li:nth-child(1),
li:nth-child(3) {
  background: #666;
  width: 200px;
}
li:nth-child(1) {
  transform-origin: right center;
  animation: wing1 1s infinite;
}
li:nth-child(3) {
  transform-origin: left center;
  animation: wing2 1s infinite;
}
@keyframes wing1 {
  0% {
    transform: rotate3d(1, 0, 0, 60deg) rotate3d(0, 1, 0, -60deg);
  }
  50% {
    transform: rotate3d(1, 0, 0, 60deg) rotate3d(0, 1, 0, 60deg);
  }
  100% {
    transform: rotate3d(1, 0, 0, 60deg) rotate3d(0, 1, 0, -60deg);
  }
}
@keyframes wing2 {
  0% {
    transform: rotate3d(1, 0, 0, 60deg) rotate3d(0, 1, 0, 60deg);
  }
  50% {
    transform: rotate3d(1, 0, 0, 60deg) rotate3d(0, 1, 0, -60deg);
  }
  100% {
    transform: rotate3d(1, 0, 0, 60deg) rotate3d(0, 1, 0, 60deg);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<ul>
  <li></li>
  <li></li>
  <li></li>
</ul>