Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

element upward 100% when transform changed by 1px

I am using css 3d transforms in my project. I am trying to apply a new transform on the containing element of several other elements. I am also trying to use getBoundingClientRect on one of its child elements. That container also has other elements in it. When the container has this value for the transform css property:

translateZ(1026px) rotateX(-90deg) rotateY(180deg) translateZ(439.001px)

here's what element.getBoundingClientRect().top for that certain child element is: 77.953109741210944 according to chrome's developer tools but when I use the elements tab to change the `transform property to this:

translateZ(1027px) rotateX(-90deg) rotateY(180deg) translateZ(439.001px)

here's what element.getBoundingClientRect().top is: -75048.6484375 what would possibly cause this? I'm not posting any code because this occurs even when I modify the values through the console. And when I make the first translateZ something like 1000px, it is still about 77. Even when it is at 0 the top of the bounding rect is about 50-100 somewhere. But when it goes beyond 1026px, the elment seems to jump to top -80000 or so. Visually, however, the element look like it should and doesn't "jump" randomly at 1027px. Can somebody say a situation that might cause this?

in case it is a browser bug or something, I'm using chrome 32.0.1687.2 dev-m Aura

EDIT:

here is a jsfiddle link:

http://jsfiddle.net/a6KxQ/2/

It'll generate a table of all translateZ values and the resulting elt.getBoundingClientRect().top values. The code's messy, but in the outputted table, if you look over it carefully, you'll find that, at some point, the top value will randomly jump far, far down. And then it'll quickly recover to come back to it's previous value. Weird.

The fiddle might take a long time to load.

like image 625
markasoftware Avatar asked Nov 01 '13 02:11

markasoftware


1 Answers

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:

enter image description here

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.

like image 174
Viele Avatar answered Oct 27 '22 00:10

Viele