【问题标题】:How do I calculate top and left when resizing translated and rotated elements调整平移和旋转元素的大小时如何计算顶部和左侧
【发布时间】:2021-10-20 14:32:20
【问题描述】:

我有一个可以拖动 DIV 并调整其大小的系统。 您可以从顶部抓取,它会从底部生长。从底部抓起,它从顶部向下生长。与左、右和角相同。

这一切都是用 CSS 宽度/高度和 translate(x,y) 完成的,效果很好。

现在我正在添加旋转并使用如​​下内容:

style="transform: translate(100px,100px) rotate(-30deg);width:100px;height:50px;"

再一次,这一切都很好。

但是当我改变宽度或高度时,元素会向上/向下或向左/向右移动。

请参阅以下内容。绿色的 div 是原始的,红色的 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>

我知道我需要根据三角函数重新计算顶部/左侧,但还没有找到正确的计算方法。

另外,我想保持围绕中心的旋转枢轴,所以我不能只将枢轴点更改为角落之一。

【问题讨论】:

    标签: html trigonometry css-transforms


    【解决方案1】:

    这里有一个带有包装的解决方案

    <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/

    将事物定位在包装器中仅用于向一个方向扩展。

    【讨论】:

    • 嗯...实际上它似乎有相同的结果。 jsfiddle.net/Lufy4pwk
    • 你说得对,对不起.. 我可以让它工作的唯一方法是将变换原点设置为左上角。但这不是你想要的我猜
    • 谢谢,如果从中心调整大小,您的示例有效。但我最初的目标是从左到右调整大小。这说明以您的示例为基础更好。 jsfiddle.net/xnk9zujv
    • 所以,我真正要寻找的是在调整大小以保持位置相同但向右(或向左)拉伸时确定 translate(x,y) 的新 x 和 y 的数学运算,或顶部或底部,具体取决于我的应用中的用户输入)。
    • 谢谢,您的解决方案通过移动变换原点来工作,以便从它扩展大小。但是在我的应用程序中,我需要将原点保持在中心,因为我允许用户抓取和旋转东西。我可以在调整大小操作之前移动原点,但这会导致对象移动,并暴露需要补偿的原始问题,因此它似乎保持固定。我在这里找到了数学:py4u.net/discuss/914662
    【解决方案2】:

    我会在这里发布一个答案,以防其他人遇到这个问题。

    找到这个帖子后: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};
    }
    

    我确信数学可以减少,但这个例子以一种易于理解的方式展示了它。

    【讨论】:

      猜你喜欢
      • 2018-03-31
      • 2013-08-11
      • 1970-01-01
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多