为什么此关键帧动画形成此动画效果 [英] why this keyframe animation form this animation effect

查看:61
本文介绍了为什么此关键帧动画形成此动画效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这些关键帧动画让我特别困惑

  @关键帧移动{
from {
transform:旋转(360deg)翻译X(1.125em)旋转(-360deg);
}
到{
转换:rotate(-360deg)translateX(1.125em)rotation(360deg);
}
}

结果如下





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



  .container {width:50px;高度:50px;边距:50px; border:2px solid;}。box {width:50px;高度:50px;背景:红色;边界半径:50%;动画:移动2s线性无限;} @关键帧移动{from {变换:translateX(1.125em)rotation(-360deg); }到{转换:translateX(1.125em)rotation(360deg); }}  

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



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



  .container {width:50px;高度:50px;边距:50px; border:2px solid;}。box {width:50px;高度:50px;背景:红色;动画:移动2s线性无限;} @关键帧移动{from {变换:translateX(1.125em)rotation(-360deg); }到{转换:translateX(1.125em)rotation(360deg); }}  

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



这是



  .container {宽度:50像素;高度:50px;边距:50px; border:2px solid;}。box {width:50px;高度:50px;背景:红色;动画:移动2s线性无限;} @关键帧移动{from {transform:rotate(360deg)translateX(1.125em)rotation(-360deg); }到{transform:rotate(-360deg)translateX(1.125em)rotation(360deg); }}  

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



我们旋转坐标系统,我们先转换元素,然后旋转元素,就好像我们将元素旋转到更大的元素中一样,该元素也朝相反的方向旋转。



将计时函数更改为线性函数之外的其他函数,您将具有相同的旋转度,但不会是线性的,在某些时间间隔内会变慢/变快:



< pre class = snippet-code-css lang-css prettyprint-override> .container {width:50px;高度:50px;边距:50px; border:2px solid;}。box {width:50px;高度:50px;背景:红色;动画:移动2s缓入无限;} @关键帧移动{from {transform:rotate(360deg)transformX(1.125em)rotation(-360deg); }到{transform:rotate(-360deg)translateX(1.125em)rotation(360deg); }}

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






这是一个简化的说明,如果您想了解有关我们如何处理转换中的多功能函数以及顺序如何重要的更多详细信息,可以检查此答案:使用翻译模拟转换原点


I saw this animation on codepen, and I don't know why it's written this way to have this effect, but I think it's going to have the effect of rotating 360deg clockwise, 360deg counterclockwise, instead of bouncing up and down or left and right

I'm particularly puzzled with these Keyframe animation

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

Results the following

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

这篇关于为什么此关键帧动画形成此动画效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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