5
votes

I'm currently dealing with an issue on how to find the initial point before an element has been rotated.

In my project, I have two divs that can't be in the same container as one another which leads to the issue I'm having.

I'm trying to calculate the initial point of an element that has already been rotated so I can correctly place another element on top of it and then apply the same rotation degrees. To make sure I have the right coordinates to work with, I have a div that stamps a little square each time the rotation occurs. The blue square for the initial point and the red square for the center point where the element is being rotated on. I thought I had the formula in the Javascript but there seems to be something off. The further I am from either 0 degrees or 180 degrees, the further away my other element drifts from where it's supposed to be. Below is the formula I currently have.

var angle = (integer passed in to the function. Example: 45)
var rotatedX = blueBox.getBoundingClientRect().left;
var rotatedY = blueBox.getBoundingClientRect().top;
var centerX = redBox.getBoundingClientRect().left;
var centerY = redBox.getBoundingClientRect().top;

var dx = rotatedX - centerX;
var dy = rotatedY - centerY;

var toRadians = (Math.PI / 180);
var dx2 = dx * Math.cos(toRadians * angle) - dy * Math.sin(toRadians * angle);
var dy2 = dx * Math.sin(toRadians * angle) + dy * Math.cos(toRadians * angle);

var initialX = dx2 + centerX;
var initialY = dy2 + centerY;

elementToRotate.style.top = initialX + "px";
elementToRotate.style.left = initialY + "px";

//This just applies the CSS transform:rotate(45deg) to the element
elementToRotate.rotateDegrees(angle);

I originally was working off of the formula here: HTML5 Canvas: Calculating a x,y point when rotated

but am having a terrible time getting my project to work properly. Any help on this is greatly appreciated. Please let me know if I need to provide any additional info.

http://jsfiddle.net/aSr7J/1/ This is the JS Fiddle of the issue. The goal is to calculate the aqua box inside the black-outlined box. The calculation works for 0 degrees and 180 degrees and is very incorrect at 45 degrees.

2
It would help if this could be reproduced in a jsfiddle.Matt
Thanks for the suggestion. I just posted the js fiddle for the problem.My Stack Overfloweth
@Ant just for future reference I think it's a little bit obnoxious to post fiddles with only webkit-prefixed properties in general questions like this. transform is unprefixed in IE10+ and FF way back to 16.Jeremy

2 Answers

5
votes

The source of the discrepancy is how the vertical Y coordinate is measured. In the html coordinates, positive Y is downward, whereas in the mathematics, it is assumed to be upward.

To account for this, just change these two lines:

var dy = rotatedY - centerY;

to

var dy = centerY - rotatedY;

and change

var initialY = dy2 + centerY;

to

var initialY = centerY - dy2;

Here is the JSFiddle.

1
votes

I tried a different approach, but maybe it can help you. I didn't really calculated the rotation, I just applied the same transform to the other div and calculated the offsets. Here is my jsfiddle demo.

Note1: I wasn't sure you're using jQuery, so I didn't use it. But it would make the transform copy more easy.
Note2: I used -webkit- prefixes in my demo, so maybe you need to change those, if you use other browsers. The javascript code handles the other prefixes too.

The code is:

function alignRedToBlue() {
    var blue = document.getElementById("blue"),
        blueStyle = window.getComputedStyle(blue, null),
        red = document.getElementById("red"),
        props = ["transform", "-moz-transform","-webkit-transform", "-ms-transform", "-o-transform"],
        index, prop;
    for (index in props) {
        prop = props[index];
        red.style[prop] = blueStyle.getPropertyValue(prop);
    }
    red.style.top = blue.offsetTop + (blue.offsetHeight - red.offsetHeight) / 2 + "px";
    red.style.left = blue.offsetLeft + (blue.offsetWidth - red.offsetWidth) / 2 + "px";
}