矩阵不等于在CSS变换动画中平移和旋转组合? [英] matrix not equal to translate and rotate combination in css transform animation?

查看:67
本文介绍了矩阵不等于在CSS变换动画中平移和旋转组合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

< pre class = snippet-code-css lang-css prettyprint-override> @keyframes grey {0%{transform:matrix(1、0、0、1、0、0)} 100%{转换:matrix(-1,0,0,-1,20,20)}} @ keyframes lightblue {0%{转换:translation(10px,10px)rotation(0deg)translate(-10px,-10px); } 100%{transform:平移(10px,10px)rotation(180deg)平移(-10px,-10px); }}。gray {float:left;左边距:50px;宽度:20px;高度:20px;背景:灰色; transform-origin:0px 0px;动画:灰色线性1s无限;}。lightblue {float:left;左边距:50px;宽度:20px;高度:20px;背景:浅蓝色; transform-origin:0px 0px;动画:浅蓝色线性1s无限;}

 < div类=灰色>< / div> < div class = lightblue>< / div>  



我所知道的



转换:matrix(1、0、0、1、0、0);



等于



转换:translate(10px,10px)rotation(0deg )translate(-10px,-10px);





transform:matrix(-1,0,0,-1,20,20)



等于



转换:translate(10px,10px)rotation(180deg)translate(-10px,-10px);



当我将以上css规则直接用于element时,一切正常。
,但是在关键帧中使用以上css规则后,事情就出错了。
灰色元素的旋转角度不同于浅蓝色。



我在chrome 71中测试代码

解决方案

问题是浏览器将如何处理插值。这两个矩阵都很好,它们与定义的变换相同,但是两者之间的插值不相同。



使用正向而不是无限的方式来查看两者都会开始并以相同的状态结束:



  @keyframes grey {0%{transform: matrix(1,0,0,1,0,0)} 100%{变换:matrix(-1,0,0,-1,20,20)}} @ keyframes lightblue {0%{变换:translation(10px ,10px)rotation(0deg)平移(-10px,-10px); } 100%{transform:平移(10px,10px)rotation(180deg)平移(-10px,-10px); }}。gray {float:left;左边距:50px;宽度:20px;高度:20px;背景:灰色; transform-origin:0px 0px;动画:灰色线性2秒0.5秒向前; border-right:2px solid;}。lightblue {float:left;左边距:50px;宽度:20px;高度:20px;背景:浅蓝色; transform-origin:0px 0px;动画:淡蓝色线性2s 0.5s向前; border-right:2px solid;}  

 < div类=灰色>< / div> < div class = lightblue>< / div>  



基本上,矩阵将首先分解为变换,然后进行插值。所以第一个 matrix(1、0、0、1、0、0)就是恒等式将被转换为null转换(例如标度(1,1) rotate(0))而不是 translate(10px,10px)rotation(0deg)像您想象的那样翻译(-10px,-10px)。那么第二个 matrix(-1,0,0,-1,20,20)可以转换为 scale(-1,-1 )translate(-20px,-20px)。同样,它不会翻译(10px,10px)旋转(180deg)平移(-10px,-10px)



现在很明显,两种动画的插值(中间状态)都不相同。这是因为浏览器不会使用与定义矩阵相同的转换。从理论上讲,组合的数量是无限的,浏览器将使用它自己的算法来找到将要使用的算法,而不一定是您定义的算法。



您可以检查此链接以获取更多详细信息: https://drafts.c​​sswg。 org / css-transforms /#interpolation-of-transforms



下面是一个示例,说明如何使两者相同:



  @keyframes grey {0%{transform:matrix(1、0、0、1、0、0 }} 100%{变换:matrix(-1,0,0,-1,20,20)}} @ keyframes淡蓝色{0%{变换:scale(1,1)} 100%{变换:scale(-1 ,-1)translate(-20px,-20px); }}。gray {float:left;左边距:50px;宽度:20px;高度:20px;背景:灰色; transform-origin:0px 0px;动画:灰色线性2s 0.5s无限; border-right:2px solid;}。lightblue {float:left;左边距:50px;宽度:20px;高度:20px;背景:浅蓝色; transform-origin:0px 0px;动画:淡蓝色线性2s 0.5s无限; border-right:2px solid;}  

 < div类=灰色>< / div> < div class = lightblue>< / div>  


@keyframes gray {
  0% { transform: matrix(1, 0, 0, 1, 0, 0) }
  100% { transform: matrix(-1, 0, 0, -1, 20, 20) }
}
@keyframes lightblue {
  0% { transform: translate(10px, 10px) rotate(0deg) translate(-10px, -10px); }
  100% { transform: translate(10px, 10px) rotate(180deg) translate(-10px, -10px); }
}
.gray {
  float: left;
  margin-left: 50px;
  width: 20px;
  height: 20px;
  background: gray;
  transform-origin: 0px 0px;
  animation: gray linear 1s infinite;
}
.lightblue {
  float: left;
  margin-left: 50px;
  width: 20px;
  height: 20px;
  background: lightblue;
  transform-origin: 0px 0px;
  animation: lightblue linear 1s infinite;
}

  <div class="gray"></div>
  <div class="lightblue"></div>

As I known

transform: matrix(1, 0, 0, 1, 0, 0);

is equal to

transform: translate(10px, 10px) rotate(0deg) translate(-10px, -10px);

and

transform: matrix(-1, 0, 0, -1, 20, 20)

is equal to

transform: translate(10px, 10px) rotate(180deg) translate(-10px, -10px);

when I use above css rule directly to element, anything works fine. but after I use above css rule in keyframes, things goes wrong. the gray element's rotate angle is different from the lightblue one.

I test the code in chrome 71

解决方案

The issue is how the browser will handle interpolation. Both matrix are fine and they are the same as the transform defined but the interpolation between both is not the same.

Use forwards instead of infinite to see that both will start and end at the same state:

@keyframes gray {
  0% { transform: matrix(1, 0, 0, 1, 0, 0) }
  100% { transform: matrix(-1, 0, 0, -1, 20, 20) }
}
@keyframes lightblue {
  0% { transform: translate(10px, 10px) rotate(0deg) translate(-10px, -10px); }
  100% { transform: translate(10px, 10px) rotate(180deg) translate(-10px, -10px); }
}
.gray {
  float: left;
  margin-left: 50px;
  width: 20px;
  height: 20px;
  background: gray;
  transform-origin: 0px 0px;
  animation: gray linear 2s 0.5s forwards;
  border-right:2px solid;
}
.lightblue {
  float: left;
  margin-left: 50px;
  width: 20px;
  height: 20px;
  background: lightblue;
  transform-origin: 0px 0px;
  animation: lightblue linear 2s 0.5s forwards;
  border-right:2px solid;
}

<div class="gray"></div>
  <div class="lightblue"></div>

Basically, the matrix will first get decomposed into transformation then will get interpolated. so the first one matrix(1, 0, 0, 1, 0, 0) which is the indentity will get transformed to a null transformation (ex scale(1,1) or rotate(0)) and not translate(10px, 10px) rotate(0deg) translate(-10px, -10px) like you may think. then the second one matrix(-1, 0, 0, -1, 20, 20) can be transformed to scale(-1,-1) translate(-20px,-20px). Again it won't be translate(10px, 10px) rotate(180deg) translate(-10px, -10px).

Now it's clear that the interpolation (the intermediate states) will not be the same for both animation. This is due to the fact that the browser will not use the same transformations you used to define the matrix. In theory, There is a infinite number of combination and the browser will use it's own algorithm to find the one he will use which will not necessarily be the one you defined.

You can check this link for more details : https://drafts.csswg.org/css-transforms/#interpolation-of-transforms

Here is an example how we can make both the same:

@keyframes gray {
  0% { transform: matrix(1, 0, 0, 1, 0, 0) }
  100% { transform: matrix(-1, 0, 0, -1, 20, 20) }
}
@keyframes lightblue {
  0% { transform: scale(1,1) }
  100% { transform:scale(-1,-1) translate(-20px, -20px)  ; }
}
.gray {
  float: left;
  margin-left: 50px;
  width: 20px;
  height: 20px;
  background: gray;
  transform-origin: 0px 0px;
  animation: gray linear 2s 0.5s infinite;
  border-right:2px solid;
}
.lightblue {
  float: left;
  margin-left: 50px;
  width: 20px;
  height: 20px;
  background: lightblue;
  transform-origin: 0px 0px;
  animation: lightblue linear 2s 0.5s infinite;
  border-right:2px solid;
}

<div class="gray"></div>
  <div class="lightblue"></div>

这篇关于矩阵不等于在CSS变换动画中平移和旋转组合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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