@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/

10-13 02:42