I have a system where I'm able to drag and resize DIVs. You can grab from the top and it will grow from the bottom. Grab from the bottom and it grows down from the top. Same with left, right, and corners.
This is all done with CSS width/height and translate(x,y) and works well.
Now I'm adding rotation and using something like this:
style="transform: translate(100px,100px) rotate(-30deg);width:100px;height:50px;"
Again, this is all good.
But when I change the width or height, the element shifts up/down or left/right.
See the following. The green div is the original, and the red one has the width expanded. You can see how it shifts.
<html>
<head>
<style>
body {
position: relative;
}
.thing {
position:absolute;
border: solid 1px #0f0;
transform: translate(100px, 100px) rotate(-30deg);
}
.thing2 {
position:absolute;
border: solid 1px #f00;
transform: translate(100px, 100px) rotate(-30deg);
}
</style>
</head>
<body>
<div class="thing" style="width:100px;height:50px;"></div>
<div class="thing2" style="width:150px;height:50px;"></div>
</body>
</html>
I know I need to recalculate the top/left based on trig, but haven't found the right calculations to make it work.
Also, I'd like to keep the rotation pivot around the center, so I can't just change the pivot point to one of the corners.
I'll post an answer here in case anyone else hits this problem.
After locating this post: https://www.py4u.net/discuss/914662 the math is a little more clear.
It first grabs the location of the object along with the rotation, then for the new position it gets the location and then calculates the diff. Here's my functionalized version:
function calcNewPos(curr_x, curr_y, curr_w, curr_h, new_w, new_h, angle) {
// convert angle to radians
angle = angle * Math.PI / 180
//initial position.
let pos = {left: curr_x, top: curr_y};
//Get position after rotation with original size
let x = -curr_width/2;
let y = curr_height/2;
let new_x = y * Math.sin(angle) + x * Math.cos(angle);
let new_y = y * Math.cos(angle) - x * Math.sin(angle);
let p1 = {left: new_x - x, top: new_y - y};
//Get position after rotation with new size
x = -new_w/2;
y = new_h/2;
new_x = y * Math.sin(angle) + x * Math.cos(angle);
new_y = y * Math.cos(angle) - x * Math.sin(angle);
let p2 = {left: new_x - x, top: new_y - y};
//Get the difference between the two positions
let offset = {left: p2.left - p1.left, top: p2.top - p1.top};
//Calculate the correction
return {left: pos.left - offset.left, top: pos.top + offset.top};
}
I'm sure the math could be reduced in size, but this example lays it out there in an easy to understand way.