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.
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:
when translateZ = perspective - 150px
, the bounding box is abnormally small and in wrong position
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
when tranlateZ = perspective + 150px
, the bounding box is abnormally small again and higher in position in case 1)
the above is not affected by perspective-origin
150px is half of the width/height of the square
when tranlateZ > perspective + 150px
, the bounding box is normal again!
Why is that?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With