旋转结合平移如何在CSS动画中起作用? [英] How does rotation combined with translation work inside CSS animation?

查看:62
本文介绍了旋转结合平移如何在CSS动画中起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在codepen上看到了这个动画,我不知道为什么用这种方式编写动画来产生这种效果,但是我认为它将具有顺时针旋转360deg,逆时针旋转360deg的效果,而不是上下弹跳或左右

我特别对这些关键帧动画感到困惑

  @关键帧移动{从 {变换:rotate(360deg)translateX(1.125em)rotate(-360deg);}至 {变换:rotate(-360deg)translateX(1.125em)rotate(360deg);}} 

结果如下

现在,如果我们考虑相反的变换,则在视觉上什么也不会发生:

  .container {宽度:50像素;高度:50px;边距:50px;边框:2px实线;}.盒子 {宽度:50像素;高度:50px;背景:红色;边界半径:50%;动画:将2s线性无限移动;}@keyframes移动{从 {变换:translateX(1.125em)旋转(-360deg);}至 {变换:translateX(1.125em)旋转(360deg);}}  

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

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

  .container {宽度:50像素;高度:50px;边距:50px;边框:2px实线;}.盒子 {宽度:50像素;高度:50px;背景:红色;动画:将2s线性无限移动;}@keyframes移动{从 {变换:translateX(1.125em)旋转(-360deg);}至 {变换:translateX(1.125em)旋转(360deg);}}  

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

这是您的初始动画以正方形显示的样子:

  .container {宽度:50像素;高度:50px;边距:50px;边框:2px实线;}.盒子 {宽度:50像素;高度:50px;背景:红色;动画:将2s线性无限移动;}@keyframes移动{从 {transform:rotate(360deg)平移X(1.125em)rotate(-360deg);}至 {transform:rotate(-360deg)平移X(1.125em)rotate(360deg);}}  

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

我们先旋转坐标系,先平移元素,然后再旋转元素,就像在一个较大的元素内旋转元素一样,该元素也朝相反的方向旋转.

如果您将计时功能更改为线性以外的其他功能,则您将具有相同的旋转度,但不会是线性的,那么它将在一定间隔内变慢/变快:

  .container {宽度:50像素;高度:50px;边距:50px;边框:2px实线;}.盒子 {宽度:50像素;高度:50px;背景:红色;动画:将2s缓入无限移动;}@keyframes移动{从 {transform:rotate(360deg)平移X(1.125em)rotate(-360deg);}至 {transform:rotate(-360deg)平移X(1.125em)rotate(360deg);}}  

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


这是一个简化的说明,如果您想了解有关我们如何处理转换内的多重功能以及顺序如何重要的更多详细信息,请检查此答案:https://i.stack.imgur.com/9oWnw.gif

解决方案

From the specification we can see how the broswer should deal with interpolation between transform values. In this case we use this:

If from- and to-transform have the same number of transform functions, each transform function pair has either the same name, or is a derivative of the same primitive: Interpolate each transform function pair as described in Interpolation of transform functions. The computed value is the resulting transform function list.

So the browser will change the first rotate from 360deg to -360deg and the same for the last rotate while translateX will kept the same. We will then have the following steps:

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);

Now we need to understand how rotate(-adeg) translateX(b) rotate(adeg) works. First you may notice that the rotation won't have any visual effect on the element since we deal with a circle, it will simply affect how the translation will work and more precisely it's the first rotation that is important (the one in the left).

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

As you can see both animation are equivalent visually.

Now the effect is as follow: each time we rotate the X-axis and then we translate our element consider the new rotated axis. It's like we rotate the coordinate system then we translate OR its like we do the translation once (since it's the same) then we keep rotating the coordinate system thus we have a rotation at the end.

Now if we consider the opposite transform nothing will happen visually:

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

In this case we translate the coordinate system by the same translation then we rotate our circle. If we change it to a square we will see the effect

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

And here is how your initial animation will look with a square:

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

We rotate the coordinate system, we translate our element then we rotate the element so it's like we rotate our the element inside a bigger one that is also rotating in the opposite direction.

If you change the timing function to something else than linear you will have the same rotation but it won't be linear, it will be slower/faster in some interval:

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


This is a simplified explanation, you may check this answer if you want more details about how we deal with multiple function inside transform and how the order is important: Simulating transform-origin using translate

这篇关于旋转结合平移如何在CSS动画中起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆