关键帧的奇怪行为

strange behavior of keyframes

情况是这样的,当立方体需要沿X轴旋转时(从-40deg到40deg),由于某种原因它跳了起来,在动画结束时我做了相反的事情(从40deg到- 40deg),立方体正常旋转。 请告诉我,可能是什么原因!代码如下所示....

.container {
  position: relative;
  top: 500px;
}

.box {
  position: absolute;
  font-size: 4em;
  width: 2em;
  height: 2em;
  margin: 1.5em auto;
  perspective: 10000px;
  transform-style: preserve-3d;
  transform: rotateX(-40deg) rotateY(44deg);
}

.box11 {
  animation: rot11 12s linear infinite;
}

.side {
  position: absolute;
  width: 2em;
  height: 2em;
  background: linear-gradient(#e66465, #9198e5);
  color: white;
}

.top {
  transform: rotateX( 90deg) translateZ(1em);
  background: linear-gradient(153deg, #e66465, #9198e5);
  animation: topUCol 24s linear infinite;
}

.right {
  transform: translateZ(1em);
  animation: rightUCol 24s linear infinite;
}

.left {
  transform: rotateY(-90deg) translateZ(1em);
  background: linear-gradient(127deg, #c45a5b, #6f76b2);
}

.bottom {
  transform: rotateX(-90deg) translateZ(1em);
  animation: bottomUCol 24s linear infinite;
}

@keyframes rot11 {
  0% {
    transform: rotateX(-40deg) rotateY(44deg);
  }
  10% {
    transform: rotateX(-40deg) rotateY(44deg) translate3d(0, -507px, 0);
  }
  40% {
    transform: rotateX(-40deg) rotateY(44deg) translate3d(0, -507px, 0);
  }
  50% {
    transform: rotateX(-40deg) rotateY(44deg) translate3d(0, -507px, 0);
  }
  60% {
    transform: rotateX(40deg) rotateY(44deg) translate3d(0, -507px, 0);
  }
  70% {
    transform: rotateX(40deg) rotateY(44deg) translate3d(0, -507px, 0);
  }
  80% {
    transform: rotateX(40deg) rotateY(44deg) translate3d(0, -507px, 0);
  }
  90% {
    transform: rotateX(40deg) rotateY(44deg);
  }
  100% {
    transform: rotateX(-40deg) rotateY(44deg);
  }
}
<div class='container'>
  <div class='box box11'>
    <div class='left side '></div>
    <div class='right side'></div>
    <div class='top side'></div>
    <div class='bottom side'></div>
  </div>
</div>

请问是什么原因!代码如下所示....

MDN translateX() documentation 写了关于 translateX()

The rotateX() CSS function defines a transformation that rotates an element around the abscissa (horizontal axis) without deforming it. Its result is a data type.

The axis of rotation passes through an origin, defined by the transform-origin CSS property.

什么是'the origin'?

MDN transform-origin documentation 写了关于 transform-origin:

The transformation origin is the point around which a transformation is applied. For example, the transformation origin of the rotate() function is the center of rotation. (This property is applied by first translating the element by the negated value of the property, then applying the element's transform, then translating by the property value.)

总结一下。

  • 浏览器检查与我们正在处理的元素相对应的来源。
  • 浏览器通过该点绘制一条虚构的水平线(水平轴)。
  • 当您应用 rotateX() 元素时,它会围绕该轴旋转。

translate3d()如何影响我的旋转。

translate3d() 沿其原点的 x、y 和 z-axis 移动元素。如果你沿着它的 y-axis 移动一个元素(你在 x-axis 和元素之间创建了一个距离),旋转将在创建的距 x-axis 的距离处旋转元素。要查看实际效果,请参阅代码示例。

补充阅读

如果您真的对它在幕后的工作原理感兴趣,您可能想要阅读矩阵。矩阵也在幕后用于其他操作(例如 SVG 中的各种滤镜效果)。您可以阅读 MDN documentation: Matrix math for the web

既然你问了我没有使用你的代码的原因,而是做了这个例子来说明会发生什么:

这里有一个link到my codePen of the same code(可能更容易看)。

// don't pay attention to the javascript, it doesn't do anything aside from changing the text.
function setDescription (newText, timeout){ 
 setTimeout(() => {
  document.getElementById('description').innerText = newText;
  }, timeout);
}

setDescription ('Rotating around X-axis', 0);
setDescription ('Rotating around Y-axis', 7000);
setDescription ('Move along the Y-axis', 14000);
setDescription ('Rotating around X-axis', 16000);
setDescription ('Returning to starting position', 22000);
setDescription ('Reload to replay', 24000);
#container{
  position: relative;
  height: 500px;
  width: 500px;
  border: 1px solid grey;
}
#description{
  position: absolute;
  left: 0px;
  right: 0px;
  top: 0px;
  text-align: center;
}
#x-axis{
  position: absolute;
  left: 50px;
  top: calc(50% - 1px);
  width: 400px;
  height: 0px;
  border: 1px solid grey;
}
#y-axis{
  position: absolute;
  left: calc(50px - 1px);
  top: 50%;
  width: 400px;
  height: 0px;
  border: 1px solid red;
  transform: rotateZ(90deg);
}

#object{
  position: absolute;
  left: calc(50% - 20px);
  top: calc(50% - 20px);
  width: 40px;
  height: 40px;
  background-color: black;
  animation: 
    rotateAroundX 3s linear 0s 2, /*0 - 6s*/
    rotateAroundY 3s linear 7s 2, /*7 - 13s*/
    moveAlongY 2s linear 14s, /*14 - 16s*/
    rotateAroundXAndTranslateY 3s linear 16s 2, /* 16 - 22s*/
    moveBackAlongY 2s linear 22s; /* 22 - 24s*/
}

@keyframes rotateAroundX{
  0%{
    transform: rotateX(0deg);
  }
  100%{
    transform: rotateX(360deg);
  }
}
@keyframes rotateAroundY{
  0%{
    transform: rotateY(0deg);
  }
  100%{
    transform: rotateY(360deg);
  }
}
@keyframes rotateAroundXAndTranslateY{
  0%{
    transform: rotateX(0deg) translate3d(0, 50px, 0);
  }
  100%{
    transform: rotateX(360deg) translate3d(0, 50px, 0);
  }
}
@keyframes moveAlongY{
  0%{
    transform: translate3d(0, 0px, 0);
  }
  50%{
    transform: translate3d(0, 50px, 0);
  }
  100%{
    transform: translate3d(0, 50px, 0);
  }
}
@keyframes moveBackAlongY{
  0%{
    transform: translate3d(0, 50px, 0);
  }
  100%{
    transform: translate3d(0, 0px, 0);
  }
}
<div id="container">
<h3 id="description"></h3>
  <div id="x-axis"></div>
  <div id="y-axis"></div>
  <div id="object"></div>
</div>