How to Get the Position of Element Transformed with CSS Rotate

How to get the position of element transformed with css rotate

Per your current Question and your requested confirmation of:

var x = termin.top + Math.cos(angle) * div.height;
var y = div.left + Math.sin(angle) * div.height;

The solution can be found in this other SO Answer for a different question, enhanced here:

// return an object with full width/height (including borders), top/bottom coordinates
var getPositionData = function(el) {
return $.extend({
width: el.outerWidth(false),
height: el.outerHeight(false)
}, el.offset());
};

// get rotated dimensions
var transformedDimensions = function(el, angle) {
var dimensions = getPositionData(el);
return {
width: dimensions.width + Math.ceil(dimensions.width * Math.cos(angle)),
height: dimensions.height + Math.ceil(dimensions.height * Math.cos(angle))
};
};



Here's an interactive jsFiddle that provides real-time updates for getPositionData(); function.
You'll be able to see the top and left values at the end of the CSS3 Rotation process you control.

Reference:   jsFiddle

Status Update: The above jsFiddle works great for 0-90deg and can be approved upon for all angles and different units such as rad, grad, and turn.

CSS use transform-origin to position a rotated element

One method to achieve the expected output would be to do the following:

  • Put the button within div2 and position it at the right edge.
  • Absolutely position the div2 at the bottom of the parent container.
  • Rotate the div2 in counter clockwise direction (-90deg) with the transform origin at left bottom.
  • After rotation, the div2 would entirely go outside of the container and hence we need to add an extra translateY(100%) to the transform stack.
  • The text is aligned to the right and an extra padding-right (greater than the width of the button) is added to keep the text away from the button.
  • The button would also get rotated by -90 degree because it is a child of div2 and to counter that (that is to make the button text get displayed properly), we need to apply counter rotation.

Now, in this approach the only drawback is that if the text length increases beyond what can be fit in a single line then it would wrap around to the next line (have a look at the second sample in snippet).

.div1 {  position: relative;  height: 120px;  width: 120px;  float: left;  margin: 20px;  border: solid 1px #000;  overflow: hidden;}button {  position: absolute;  display: inline-block;  bottom: 0;  right: 0;  width: 48px;  height: 48px;  border: 0;  margin: 0;  padding: 0;  transform: rotate(90deg);}.div2 {  position: absolute;  box-sizing: border-box;  bottom: 0px;  height: 48px;  width: 100%;  padding-right: 60px;  line-height: 48px;  background-color: #999;  text-align: right;  transform: rotate(-90deg) translateY(100%);  transform-origin: left bottom;}
<div class="div1">  <div class="div2">HELLO    <button>></button>  </div></div>
<div class="div1"> <div class="div2">HELLO WORLD!!!!! <button>></button> </div></div>

How to position rotated element to the right edge

getBoundingClientRect is a good approach, the problem is that when you set css left, it positions it without the rotation calculated. The order in which you set it doesn't change the fact the the rotation is applied in relation to the css, not in relation to the current position of the rotated div. So when you calculate dimensions using getBoundingClientRect you're taking into account the rotation, then you use it on a css that doesn't take it into account.

One easy way to get proper coordinates, would be to calculate the x difference between before rotation and after and adjust you left accordingly. You'll have prevDimension.x - dimension.x giving you the difference in x that the rotation is creating, which allows you to adjust newLeft.

Like this:

$('#rotate-align').click(function () {
var prevDimensions = $('.element')[0].getBoundingClientRect();
$('.element').css('transform', 'rotate(0.99923rad)');
var dimensions = $('.element')[0].getBoundingClientRect();
var newLeft = $('#bounds').width() - dimensions.width - dimensions.x + prevDimensions.x;
$('.element').css('left', newLeft);
});

http://jsfiddle.net/jgcynwmp/3/

Another approach would be to calculate the x difference based on the width difference between the non rotated element and the rotated element. This can be done using offsetWidth (which doesn't take the rotation into account) and the getBoundingClientRect. The difference between the 2 will tell you how much width is lost with the rotation. Note that for this calculation, the transform origin is important. For example, with a centered rotation, you'll need to divide by 2 the width difference to get the x difference, but with another origin it would be something else.

Like this:

$('#rotate-align').click(function () {
$('.element').css('transform', 'rotate(0.99923rad)');
var dimensions = $('.element')[0].getBoundingClientRect();
var newLeft = $('#bounds').width() - $('.element')[0].offsetWidth + (($('.element')[0].offsetWidth - dimensions.width) / 2);
$('.element').css('left', newLeft);
});

http://jsfiddle.net/jgcynwmp/4/

Getting CSS left and top when div is rotated

Okay, thanks to the comment left above, I managed to throw together an answer.

Basically using:

newleft = parseInt(div.style.top) + Math.cos(90) * parseInt(div.style.height);
newtop = parseInt(div.style.left) + Math.sin(90) * parseInt(div.style.height);

after the div had been rotated.

I've updated my jsfiddle aswell, because the one in the comment above uses jQuery, but this way uses only javascript.

How to transform: translate more elements to same position?

for simplest answer, use CSS variables with a calc() function.

one time all the elements!! easy and fast

I commented on the code if you want...



  1. the first element has a --i var with 0, so it will be 0 position x

  2. the second element has a --i var with 1, so it will be -100 position x

  3. the third element has a --i var with 2, so it will be -200 position x

the amazing part about this, is if you want to add more images, it will be easy for you, because the formula is calculated by CSS (not you)

here the fixed code:

* {
margin: 0;
padding: 0;
box-sizing: border-box;
/* here the trick */
--end-position: calc(-100px * var(--i));
}

img {
width: 100px;
height: 100px;
}

.container {
background-color: red;
height: 400px;
width: 100%;
display: flex;
justify-content: center;
}

/* use the DRY method (Dont Repeat Yourself) */

.container img:hover {
transition: 3s;
/* one time for all, that's easy! and fast*/
transform: translate(var(--end-position), 200px);
}
<div class="container">
<img style="--i: 0;" class="img-test1" src="https://avatars.githubusercontent.com/u/87947051?v=4" alt="Sample Image">
<img style="--i: 1;" class="img-test2" src="https://avatars.githubusercontent.com/u/87947051?v=4" alt="Sample Image">
<img style="--i: 2;" class="img-test3" src="https://avatars.githubusercontent.com/u/87947051?v=4" alt="Sample Image">
</div>


Related Topics



Leave a reply



Submit