调整平移和旋转元素大小时如何计算顶部和左侧
How do I calculate top and left when resizing translated and rotated elements
我有一个可以拖动和调整 DIV 大小的系统。
你可以从顶部抓住它,它会从底部生长。从底部抓住它,它从顶部向下生长。与左、右和角相同。
这一切都是用 CSS width/height 和 translate(x,y) 完成的,效果很好。
现在我要添加旋转并使用类似这样的东西:
style="transform: translate(100px,100px) rotate(-30deg);width:100px;height:50px;"
再一次,这一切都很好。
但是当我更改宽度或高度时,元素会移动 up/down 或 left/right。
见下文。绿色的div是原来的,红色的加宽了。你可以看到它是如何变化的。
<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>
我知道我需要根据三角函数重新计算 top/left,但还没有找到正确的计算方法来让它工作。
另外,我想保持围绕中心的旋转轴,所以我不能只将轴点更改为其中一个角。
这里是包装器的解决方案
<div class="thing-wrapper">
<div class="thing left-top">expand right</div>
</div>
<div class="thing-wrapper">
<div class="thing right-top">expand left</div>
</div>
<div class="thing-wrapper">
<div class="thing left-bottom">expand top</div>
</div>
<div class="thing-wrapper">
<div class="thing right-bottom">expand bottom</div>
</div>
.thing-wrapper {
position: absolute;
}
.thing {
border: solid 1px #0f0;
width: 100px;
height: 100px;
position: absolute;
transform: translate(100px, 100px) rotate(-44deg);
transition: 2s;
}
.thing.expand-left:hover,
.thing.expand-right:hover{
width: 200px !important;
height: 100px !important;
}
.thing.expand-top:hover,
.thing.expand-bottom:hover{
width: 100px !important;
height: 200px !important;
}
.expand-left {
left: 0;
top: 0;
transform-origin: left top;
}
.expand-right {
right: 0;
top: 0;
transform-origin: right top;
}
.expand-top {
left:0;
bottom: 0;
transform: translate(300px, 300px) rotate(-44deg);
transform-origin: left bottom;
}
.expand-bottom {
left: 0;
right: 0;
transform: translate(300px, 300px) rotate(-44deg);
transform-origin: left top;
}
https://jsfiddle.net/dt7phfk9/32/
将事物定位在包装器中只适用于在一个方向上展开。
我会post在这里回答,以防其他人遇到这个问题。
找到这个 post 后:https://www.py4u.net/discuss/914662 数学更清楚了。
它首先获取对象的位置以及旋转,然后为新位置获取位置,然后计算差异。这是我的功能化版本:
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};
}
我敢肯定数学的大小可以减少,但这个例子以一种易于理解的方式将其布置在那里。
我有一个可以拖动和调整 DIV 大小的系统。 你可以从顶部抓住它,它会从底部生长。从底部抓住它,它从顶部向下生长。与左、右和角相同。
这一切都是用 CSS width/height 和 translate(x,y) 完成的,效果很好。
现在我要添加旋转并使用类似这样的东西:
style="transform: translate(100px,100px) rotate(-30deg);width:100px;height:50px;"
再一次,这一切都很好。
但是当我更改宽度或高度时,元素会移动 up/down 或 left/right。
见下文。绿色的div是原来的,红色的加宽了。你可以看到它是如何变化的。
<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>
我知道我需要根据三角函数重新计算 top/left,但还没有找到正确的计算方法来让它工作。
另外,我想保持围绕中心的旋转轴,所以我不能只将轴点更改为其中一个角。
这里是包装器的解决方案
<div class="thing-wrapper">
<div class="thing left-top">expand right</div>
</div>
<div class="thing-wrapper">
<div class="thing right-top">expand left</div>
</div>
<div class="thing-wrapper">
<div class="thing left-bottom">expand top</div>
</div>
<div class="thing-wrapper">
<div class="thing right-bottom">expand bottom</div>
</div>
.thing-wrapper {
position: absolute;
}
.thing {
border: solid 1px #0f0;
width: 100px;
height: 100px;
position: absolute;
transform: translate(100px, 100px) rotate(-44deg);
transition: 2s;
}
.thing.expand-left:hover,
.thing.expand-right:hover{
width: 200px !important;
height: 100px !important;
}
.thing.expand-top:hover,
.thing.expand-bottom:hover{
width: 100px !important;
height: 200px !important;
}
.expand-left {
left: 0;
top: 0;
transform-origin: left top;
}
.expand-right {
right: 0;
top: 0;
transform-origin: right top;
}
.expand-top {
left:0;
bottom: 0;
transform: translate(300px, 300px) rotate(-44deg);
transform-origin: left bottom;
}
.expand-bottom {
left: 0;
right: 0;
transform: translate(300px, 300px) rotate(-44deg);
transform-origin: left top;
}
https://jsfiddle.net/dt7phfk9/32/
将事物定位在包装器中只适用于在一个方向上展开。
我会post在这里回答,以防其他人遇到这个问题。
找到这个 post 后:https://www.py4u.net/discuss/914662 数学更清楚了。
它首先获取对象的位置以及旋转,然后为新位置获取位置,然后计算差异。这是我的功能化版本:
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};
}
我敢肯定数学的大小可以减少,但这个例子以一种易于理解的方式将其布置在那里。