@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>
如我所知
transform: matrix(1, 0, 0, 1, 0, 0);
等于
transform: translate(10px, 10px) rotate(0deg) translate(-10px, -10px);
和
transform: matrix(-1, 0, 0, -1, 20, 20)
等于
transform: translate(10px, 10px) rotate(180deg) translate(-10px, -10px);
当我将以上CSS规则直接用于元素时,一切正常。
但是在关键帧中使用以上css规则后,事情就出错了。
灰色元素的旋转角度与浅蓝色元素的旋转角度不同。
我测试Chrome 71中的代码
最佳答案
问题是浏览器将如何处理插值。两个矩阵都很好,它们与定义的变换相同,但是两者之间的插值不相同。
使用forwards而不是infinite可以看到它们将以相同的状态开始和结束:
@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>
基本上,矩阵将首先分解为变换,然后进行插值。因此,第一个
matrix(1, 0, 0, 1, 0, 0)
是恒等式,将转换为空转换(例如scale(1,1)
或rotate(0)
),而不是您可能认为的translate(10px, 10px) rotate(0deg) translate(-10px, -10px)
。那么第二个matrix(-1, 0, 0, -1, 20, 20)
可以转换为scale(-1,-1) translate(-20px,-20px)
。同样,它不会是translate(10px, 10px) rotate(180deg) translate(-10px, -10px)
。现在很明显,两个动画的插值(中间状态)将不同。这是因为浏览器不会使用与定义矩阵相同的转换。从理论上讲,组合的数量是无限的,浏览器将使用它自己的算法来查找将要使用的算法,而不一定是您定义的算法。
您可以检查此链接以获取更多详细信息:https://drafts.csswg.org/css-transforms/#interpolation-of-transforms
这是一个示例,我们可以使两者相同:
@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 - 矩阵不等于在CSS变换动画中平移和旋转组合?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53956599/