调整平移和旋转元素大小时如何计算顶部和左侧

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};
}

我敢肯定数学的大小可以减少,但这个例子以一种易于理解的方式将其布置在那里。