【问题标题】:Center Object based on rotation基于旋转的中心对象
【发布时间】:2020-12-29 17:58:53
【问题描述】:

我需要根据对象的旋转在画布中使对象居中。我无法弄清楚数学。

我有什么信息?

  • 左上角的x、y坐标(见图片红圈)
  • 对象的宽度和高度
  • 以度为单位的旋转值

到目前为止我尝试了什么?

// center horizontally 
if (curretElement === null) return;
curretElement.x((canvas.width() / 2) - ((curretElement.width() * curretElement.scaleX()) / 2));
canvas.draw();

// center vertically
curretElement.y((canvas.height() / 2) - ((curretElement.height() * curretElement.scaleY()) / 2));
canvas.draw();

这会在图像未旋转时居中。

currentElement 是选中的对象。

canvas 是对象应该居中的房间。

【问题讨论】:

  • 我假设左上角的 x,y 坐标是您要计算的信息,而不是您拥有的信息?也就是说,物体的位置锚点是左上角,不管角度如何?
  • 对,所以要做到这一点,首先需要计算从对象中心到其左上角的向量。这是(-width * scale / 2, -height * scale / 2),您已经计算过了。将其添加到画布中心,您将获得角度 = 0 的坐标,就像您已经做的那样。对于不同的角度,您需要做的就是在将矢量添加到画布中心之前旋转矢量。您可以为此使用2D rotation matrix
  • 这看起来你正在使用 FabricJs ......你能发布一个完整但最小的项目代码 sn-p
  • 我正在使用 konvajs

标签: javascript math canvas geometry


【解决方案1】:

你可以这样计算坐标:

  1. 假设您的对象位于画布的中心
  2. 计算左上角相对于画布中心的坐标
  3. 围绕画布中心旋转对象并计算左上角相对于画布中心的位置
  4. 将左上角的相对坐标转换回绝对坐标

这是一个计算函数:

function calculateXY(canvasWidth, canvasHeight, width, height, angle) {
    //calculate where the top left corner of the object would be relative to center of the canvas
    //if the object had no rotation and was centered
    const x = -width / 2;
    const y = -height / 2;

    //rotate relative x and y coordinates by angle degrees
    const sinA = Math.sin(angle * Math.PI / 180);
    const cosA = Math.cos(angle * Math.PI / 180);
    const xRotated = x * cosA - y * sinA;
    const yRotated = x * sinA + y * cosA;

    //translate relative coordinates back to absolute
    const canvasCenterX = canvasWidth / 2;
    const canvasCenterY = canvasHeight / 2;
    const finalX = xRotated + canvasCenterX;
    const finalY = yRotated + canvasCenterY;

    return { x: finalX, y: finalY };
}

【讨论】:

  • 这行得通。我的错误是我没有取对象的中间,而是左上角的 x 和 y 坐标(见图)非常感谢!
【解决方案2】:

更新:第一次尝试真的很糟糕,所以我更新了代码。这实际上可以将您的左角保持在容器的中心,只需填充角度输入

我想发表评论并提出更多问题,但我不能,这件事(赏金)很诱人

不重依赖java脚本。可能是你需要第二次尝试的。

Corner 是之前的容器和内容。旋转,但它仍然存在。有帮助吗?发表评论。

    <!DOCTYPE html>
    <html lang="en">
    <body>
        <style>
        body{
          margin:0;
        }
        #container{
          display :flex;
          position: absolute;
          width:100%;
          height:100%;
        }
        #ram{
          display:flex;
          background-color:black;
          position:absolute;
          margin:auto;
          top:50%;
          right:50%;
        }
        #ram::before{
          content: "";
          position:absolute;
          height:40px;
          width:400px;
          background-color: #000;
        }
        </style>
        <input type="number" id="a" onchange = "forf()">
        <div id = "container">
        <div id = "ram">
        </div>
        </div>
        <script>
        function forf(){
          var a = document.getElementById("a").value;
        document.getElementById("ram").style.transform = "rotate(" + a + "deg)";
        }
        </script>
    </body>
    </html>

【讨论】:

  • 不幸的是,这对我没有帮助。但无论如何感谢您的努力。
猜你喜欢
  • 2013-08-01
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 2016-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多