element upward 100% when transform changed by 1px

会有一股神秘感。 提交于 2019-12-05 02:47:56

As you suspected, It has to do with the perspective of the viewpoint. By increasing of the value for the 1st translateZ, you are bringing the rectangle closer to you. Eventually it is so close, it has passed the point of the camera. From that point on, the shape, un-rotated, stood behind your eyes.

Then you did a rotateX(-90deg). what happens there is the rectangle fell down forwards (towards the positive Z direction, but behind the camera.). Now, since the tunnel of the view is of a trapezoid shape, hence you get what we see in this screenshot:

With the rectangle behind the camera, as the it rotates, part of it is pivoted back into view.

So the getBoundingClientRect() is actually giving you the bottom of the shape's bound! Now that the shape is flipped, and it doesn't understand 3D.

I hope that made sense to you. I want to get to you first :) Ask me before down-voting, I can explain in more details.

so, it is by design. You probably want to restrict the translateZ value to be smaller than perspective.

EDIT:

sorry I have been busy. I meant to give a more detailed response. Thanks for whoever gave me the bounty.

A updated demo

Play around the numbers, you will make the following observations:

  1. when translateZ = perspective - 150px, the bounding box is abnormally small and in wrong position

  2. when perspective - 150px < translateZ < perspective + 150px, the bounding box is on the opposite side of where it should be, and the size is abnormally large

  3. when tranlateZ = perspective + 150px, the bounding box is abnormally small again and higher in position in case 1)

  4. the above is not affected by perspective-origin

  5. 150px is half of the width/height of the square

  6. when tranlateZ > perspective + 150px, the bounding box is normal again!

Why is that?

  • in case 1) one of the edges just intersects with the plane that the camera/perspective is located.
  • in case 2) the square intersects with the camera plane
  • in case 3) the edge opposite to the edge in case 1) now intersects with camera/perspective plane.
  • in case 6) all of the square has passed the camera plane

The projection algorithm used to convert 3D coordinates to on screen 2D coodinates does not take into account of the fact that two corners are infront of the camera, and two other corners are behind, hence creating a wrong projection, and hence wrong size.

That was what I meant by "it doesn't understand 3D". That was vague as it can be I realize, Sorry. When all the shape is passed the camera plane, it works again.

Firefox, and Chrome both have this problem, but have different representations, numerically. Probably because different projections matrix are used. So I don't want to figure out what exactly went wrong. Fire a bug report to them :)

Realistically though, you might need to work around it.

I'm not sure how to explain it, and it could be off base, but when you comment out the the perspective css you get the same values down the whole table. I'm not sure what perspective does to the math...

#main3DWrapper{
  /*
  -webkit-perspective: 1500px;
  -moz-perspective: 1500px;
  perspective:1500px;
  -webkit-perspective-origin: 50% 1%;
  perspective-origin:50% 1%;
  */
  -webkit-transform: translate3d(0,0,0,0);
  transform:translate3d(0,0,0,0);
  display: block;
  height: 100%;
  left: -121.96603393554688px;
  position: absolute;
  top: 409.5150146484375px;
  width: 100%;
}

Also, why are you setting the translateZ() value twice in the js?

container.style.webkitTransform='translateZ('+dist+'px) rotateX(-90deg) rotateY(180deg) translateZ(429.001px)';
container.style.transform='translateZ('+dist+'px) rotateX(-90deg) rotateY(180deg) translateZ(429.001px)';

Shouldn't is just be?:

container.style.webkitTransform='translateZ('+dist+'px) rotateX(-90deg) rotateY(180deg)';
container.style.transform='translateZ('+dist+'px) rotateX(-90deg) rotateY(180deg)';
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!