【问题标题】:How does rotation combined with translation work inside CSS animation?旋转和平移如何在 CSS 动画中发挥作用?
【发布时间】:2019-03-10 20:27:30
【问题描述】:

我在codepen上看到了这个动画,不知道为什么要这样写才能有这个效果,但是我觉得它会产生顺时针旋转360度,逆时针旋转360度的效果,而不是上下弹跳或者左右

我对这些关键帧动画特别不解

@keyframes move{
    from {
       transform: rotate(360deg) translateX(1.125em) rotate(-360deg);
    }
    to {
       transform: rotate(-360deg) translateX(1.125em) rotate(360deg);
    }
}

结果如下

https://i.stack.imgur.com/9oWnw.gif

【问题讨论】:

  • 你预期的效果是什么?
  • 请澄清您的具体问题或添加其他详细信息以准确突出您的需要。正如目前所写的那样,很难准确地说出你在问什么。
  • 欢迎来到 SO。请使用tourhelp centre 来查看how to ask a good question
  • 我为那些对修补感兴趣的人做了a fiddle

标签: css css-animations css-transforms


【解决方案1】:

the specification 我们可以看到浏览器应该如何处理transform 值之间的插值。在这种情况下,我们使用这个:

如果 from- 和 to-transform 具有相同数量的变换函数, 每个变换函数对具有相同的名称,或者是 相同原语的导数:对每个变换函数进行插值 对,如变换函数的插值中所述。这 计算值是生成的变换函数列表。

因此,浏览器会将第一个 rotate360deg 更改为 -360deg,最后一个 rotate 相同,而 translateX 将保持不变。然后我们将有以下步骤:

transform: rotate(360deg) translateX(1.125em) rotate(-360deg);
transform: rotate(350deg) translateX(1.125em) rotate(-350deg);
transform: rotate(340deg) translateX(1.125em) rotate(-340deg);
....
transform: rotate(0) translateX(1.125em) rotate(0);
....
....
transform: rotate(-360deg) translateX(1.125em) rotate(360deg);

现在我们需要了解rotate(-adeg) translateX(b) rotate(adeg) 的工作原理。首先,您可能会注意到旋转不会对元素产生任何视觉效果,因为我们处理的是一个圆圈,它只会影响平移的工作方式,更准确地说,它是第一次旋转很重要(左边那个)。

.container {
  width: 50px;
  height: 50px;
  margin: 50px;
  border:2px solid;
}

.box {
  width: 50px;
  height: 50px;
  background: red;
  border-radius: 50%;
  animation: move 2s linear infinite;
}

.alt {
  animation: move-alt 2s linear infinite;
}

@keyframes move {
  from {
    transform: rotate(360deg) translateX(1.125em) rotate(-360deg);
  }
  to {
    transform: rotate(-360deg) translateX(1.125em) rotate(360deg);
  }
}

@keyframes move-alt {
  from {
    transform: rotate(360deg) translateX(1.125em);
  }
  to {
    transform: rotate(-360deg) translateX(1.125em);
  }
}
<div class="container">
  <div class="box">

  </div>
</div>
<div class="container">
  <div class="box alt">

  </div>
</div>

如您所见,两个动画在视觉上是等效的。

现在效果如下:每次我们旋转 X 轴然后我们平移我们的元素时考虑新的旋转轴。这就像我们旋转坐标系然后我们平移,或者就像我们进行一次平移(因为它是相同的)然后我们继续旋转坐标系,因此我们在最后有一个旋转。

现在,如果我们考虑相反的变换,视觉上不会发生任何事情:

.container {
  width: 50px;
  height: 50px;
  margin: 50px;
  border: 2px solid;
}

.box {
  width: 50px;
  height: 50px;
  background: red;
  border-radius: 50%;
  animation: move 2s linear infinite;
}

@keyframes move {
  from {
    transform: translateX(1.125em) rotate(-360deg);
  }
  to {
    transform: translateX(1.125em) rotate(360deg);
  }
}
<div class="container">
  <div class="box">

  </div>
</div>

在这种情况下,我们通过相同的平移平移坐标系,然后旋转我们的圆。如果我们将其更改为正方形,我们将看到效果

.container {
  width: 50px;
  height: 50px;
  margin: 50px;
  border: 2px solid;
}

.box {
  width: 50px;
  height: 50px;
  background: red;
  animation: move 2s linear infinite;
}

@keyframes move {
  from {
    transform: translateX(1.125em) rotate(-360deg);
  }
  to {
    transform: translateX(1.125em) rotate(360deg);
  }
}
<div class="container">
  <div class="box">

  </div>
</div>

这是您的初始动画在正方形中的外观:

.container {
  width: 50px;
  height: 50px;
  margin: 50px;
  border: 2px solid;
}

.box {
  width: 50px;
  height: 50px;
  background: red;
  animation: move 2s linear infinite;
}

@keyframes move {
  from {
    transform:rotate(360deg) translateX(1.125em) rotate(-360deg);
  }
  to {
    transform:rotate(-360deg) translateX(1.125em) rotate(360deg);
  }
}
<div class="container">
  <div class="box">

  </div>
</div>

我们旋转坐标系,平移元素,然后旋转元素,就像我们在一个更大的元素中旋转元素,该元素也在相反的方向旋转。

如果您将计时功能更改为线性以外的其他功能,您将拥有相同的旋转,但它不会是线性的,它会在某个时间间隔内变慢/变快:

.container {
  width: 50px;
  height: 50px;
  margin: 50px;
  border: 2px solid;
}

.box {
  width: 50px;
  height: 50px;
  background: red;
  animation: move 2s ease-in-out infinite;
}

@keyframes move {
  from {
    transform:rotate(360deg) translateX(1.125em) rotate(-360deg);
  }
  to {
    transform:rotate(-360deg) translateX(1.125em) rotate(360deg);
  }
}
<div class="container">
  <div class="box">

  </div>
</div>

这是一个简化的解释,如果您想了解更多关于我们如何处理变换内部的多个函数以及顺序如何重要的详细信息,您可以查看此答案:Simulating transform-origin using translate

【讨论】:

    猜你喜欢
    • 2011-08-21
    • 2019-02-05
    • 2021-08-15
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    • 2013-08-02
    相关资源
    最近更新 更多