matrix not equal to translate and rotate combination in css transform animation?

房东的猫 提交于 2019-12-24 10:55:24

问题


@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


回答1:


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>


来源:https://stackoverflow.com/questions/53956599/matrix-not-equal-to-translate-and-rotate-combination-in-css-transform-animation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!