How to Get Screen Position of CSS3-3D Transformed Elements

How to get screen position of CSS3-3d transformed elements?

Have you tried using getBoundingClientRect()?

I've used it successfully in the past to calculate the dimensions of elements that have been transformed with the transform property.

How to position element in the correct 3d position with css perspective

perspective needs to be added to the parent, not to the child. The rest are details:

span {  background: green;  width: 256px;  height: 176px;  position: absolute;  top: 0;  left: 0;  transform: rotateX(1deg) rotateY(-7deg) rotateZ(-1deg) skew(-11.25deg, 1.5deg) translate(233px, 37px);  opacity: 0.5;}
div { position: relative; perspective: 400px; width: 1200px;}
img { width: 500px; height: auto;}
body { overflow-x: hidden;}
<div>  <span></span>  <img src="https://i.stack.imgur.com/iL2xf.png" /></div>

How can I get the untransformed position/size of an element using 3D transforms?

You can try using the .data function in jquery, its pretty straight forward and pretty reliable as far as i know.

$(this).data("flatleft", $(this).position().left);

ref: http://api.jquery.com/data/

Getting the touched position in local coordinates of a transformed element

I am not entirely sure about the theory, I read about this while I was working on a similar problem, but here is what I found. The multiplication of the matrices (the matrix of the 3d transformation - homogeneous coordinates, and the position of the cursor) produces two more values apart from x and y. The first is z, and the other one is w which is used in order to project the 3d object on a 2d plane.

If you divide the x and y values of the vector by the w coordinate, you get the correct position/mapping of the cursor on the Cartesian plane.

So, I would replace the code in your fiddle, lines 69-70, with these:

var x = result.get([0]);
var y = result.get([1]);
var w = result.get([3]);
screenCrosshair.style.left = x / w + 'px';
screenCrosshair.style.top = y / w + 'px';

Here is the update fiddle:
https://jsfiddle.net/x3ruc3tL/1/

And then you don't need the offsetX and offsetY values of the browser in order to find the correct position.

Please read the following articles for more information:

https://en.wikipedia.org/wiki/3D_projection#Perspective_projection
http://deltaorange.com/2012/03/08/the-truth-behind-homogenous-coordinates/

How do I get the position of an element after css3 translation in JavaScript?

You can use getBoundingClientRect():

Imagine the following html block:

<div class="centralizer popup">
<div class="dragger"></div>
</div>

And the style:

body {
background:#ccc;
}
.centralizer {
position:absolute;
top:150px;
left:170px;
width:352px;
height:180px;
overflow:auto;
-webkit-transform: translateY(-50%) translateX(-50%);
-moz-transform: translateY(-50%) translateX(-50%);
-ms-transform: translateY(-50%) translateX(-50%);
transform: translateY(-50%) translateX(-50%);
}
.popup {
background:white;
box-shadow:0 0 0 2px rgba(0, 0, 0, 0.1), 0 0 15px rgba(0, 0, 0, 0.3);
border-radius:3px;
}
.dragger {
background:#eee;
height:35px;
border-radius:3px 3px 0 0;
border-bottom:1px solid #ccc;
}

Now you can use the following javascript to get the correct position:

var popup = document.querySelector('.popup');
var rect = popup.getBoundingClientRect();

console.log("popup.getBoundingClientRect(): \n" + "x: " + rect.left + "\ny: " + rect.top);

You can check the result in the jsfiddle:

I tested on FF, IE and chrome, and it worked on all my tests.

How to convert screen coordinates to coordinates on a z transformed element?

The toughest part here seems to be the conversion of the screen-space coordinates of a click to the transformed coordinates. One way you can do this is to use the getBoundingClientRect() function (which returns the dimensions/position of an object after all transformations are applied), and use its dimensions to calculate the ratio between the displayed dimensions of an element, and their "actual" dimensions.

Once you have this ratio, just multiply it with the click coordinates (after offsetting them to be relative to the element's displayed center coordinates) to get the transformed click coordinates.

I've added to your code to show how you can use this approach to move your CSS-transformed element to the mouse click position:

function getPosition(screenCoords){    var $transformedEl = $(".z-transformed-element");        // Calculating "actual" center of element    var elementCenter = {        x: $transformedEl.innerWidth() / 2,        y: $transformedEl.innerHeight() / 2    }        // Determining ratio of displayed dimensions to "actual" dimensions    var boundingRect = $transformedEl[0].getBoundingClientRect();    var dimRatio = $transformedEl.innerWidth() / boundingRect.width;        // Determining offset click coordinates (relative to displayed center of element)    var clickOffset = {        x: screenCoords.x - $transformedEl.offset().left - boundingRect.width / 2,        y: screenCoords.y - $transformedEl.offset().top - boundingRect.height / 2    }        // Calculating coordinates of click, relative to element's "actual" center and ratio of displayed to "actual" dimensions    var finalCoords = {     x: elementCenter.x + clickOffset.x * dimRatio,     y: elementCenter.y + clickOffset.y * dimRatio    }        return finalCoords;}
var $viewport = $(".viewport");var $marker = $(".marker"); $viewport.on("click", function(e){ e.preventDefault(); console.log(e.pageX, e.pageY); var newMarkerPosition = getPosition({x: e.pageX, y: e.pageY}); $marker.css({ left: newMarkerPosition.x + "px", top: newMarkerPosition.y + "px" }); });
html, body {        width: 100%;    height: 100%;    margin: 0;    padding: 0;    }
.viewport { width: 100%; height: 100%; overflow: hidden; perspective: 1000px; perspective-origin: 50% 50%;}
.z-transformed-element { width: 5000px; height: 3000px; transform-origin: 2500px 1500px; background-color: gray; position: relative; transform: translateX(-2500px) translateY(-1500px) translateZ(-10000px); }
.marker { left: 0; top: 0; width: 200px; height: 200px; margin-left: -100px; margin-top: -100px; background-color: red; border-radius: 100px; position: absolute; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div class="viewport">    <div class="z-transformed-element">        <div class="marker"></div>    </div></div>


Related Topics



Leave a reply



Submit