通过JavaScript计算旋转元素的边界框的X,Y,高度和宽度

Cam*_*eln 24 javascript css geometry rotation bounding-box

基本上我是在问JavaScript这个问题:从旋转的矩形计算边界框坐标

图

在这种情况下:

  • iX =旋转(蓝色)HTML元素的宽度
  • iY =旋转(蓝色)HTML元素的高度
  • bx =边界框宽度(红色)
  • by =边界框高度(红色)
  • x =边界框的X坐标(红色)
  • y =边界框的Y坐标(红色)
  • iAngle/t = HTML元素的旋转角度(蓝色;未显示但在下面的代码中使用),仅供参考:在此示例中它是37度(不是对于示例而言重要)

如何通过JavaScript计算旋转的HTML元素(给定其宽度,高度和旋转角度)周围的边界框(所有红色数字)的X,Y,高度和宽度?一个棘手的问题是将旋转的HTML元素(蓝色框)的原始X/Y坐标用作某种方式的偏移(这在下面的代码中没有表示).这可能需要查看CSS3的变换原点来确定中心点.

我有一个部分解决方案,但X/Y坐标的计算不正常...

var boundingBox = function (iX, iY, iAngle) {
    var x, y, bx, by, t;

    //# Allow for negetive iAngle's that rotate counter clockwise while always ensuring iAngle's < 360
    t = ((iAngle < 0 ? 360 - iAngle : iAngle) % 360);

    //# Calculate the width (bx) and height (by) of the .boundingBox
    //#     NOTE: See https://stackoverflow.com/questions/3231176/how-to-get-size-of-a-rotated-rectangle
    bx = (iX * Math.sin(iAngle) + iY * Math.cos(iAngle));
    by = (iX * Math.cos(iAngle) + iY * Math.sin(iAngle));

    //# This part is wrong, as it's re-calculating the iX/iY of the rotated element (blue)
    //# we want the x/y of the bounding box (red)
    //#     NOTE: See https://stackoverflow.com/questions/9971230/calculate-rotated-rectangle-size-from-known-bounding-box-coordinates
    x = (1 / (Math.pow(Math.cos(t), 2) - Math.pow(Math.sin(t), 2))) * (bx * Math.cos(t) - by * Math.sin(t));
    y = (1 / (Math.pow(Math.cos(t), 2) - Math.pow(Math.sin(t), 2))) * (-bx * Math.sin(t) + by * Math.cos(t));

    //# Return an object to the caller representing the x/y and width/height of the calculated .boundingBox
    return {
        x: parseInt(x), width: parseInt(bx),
        y: parseInt(y), height: parseInt(by)
    }
};
Run Code Online (Sandbox Code Playgroud)

我觉得自己如此接近,但到目前为止......

非常感谢您提供的任何帮助!

帮助非JAVASCRIPTERS ...

旋转HTML元素后,浏览器返回"矩阵变换"或"旋转矩阵",似乎是这样:rotate(Xdeg) = matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0); 有关详细信息,请参阅此页面.

我有一种感觉,这将启发我们如何仅根据旋转元素的宽度,高度和角度(蓝色)获得边界框(红色)的X,Y.

新信息

嗯...有趣......

在此输入图像描述

每个浏览器似乎都以不同于X/Y的角度处理旋转!FF完全忽略它,IE和Opera绘制边界框(但它的属性没有暴露,即:bx&by)并且Chrome和Safari旋转矩形!除FF外,所有都正确报告X/Y. 所以...只有FF存在X/Y问题!多奇怪啊!

另外值得注意的是,$(document).ready(function () {...});对于旋转的X/Y来说,似乎太早了(这是我原来问题的一部分!).我在X/Y询问调用之前直接旋转元素,$(document).ready(function () {...});但它们似乎直到(!?)之后的某个时间才更新.

当我得到更多的时间时,我会用一个例子来折腾jFiddle,但我使用的是"jquery-css-transform.js"的修改形式,所以我在jFiddle之前做了一点点的修补......

那么......什么事,FireFox?那不酷,伙计!

情节变厚......

好吧,FF12似乎解决了FF11的问题,现在就像IE和Opera一样.但现在我回到X/Y的方方面面,但至少我想我知道为什么现在...

似乎即使浏览器正确地报告旋转对象的X/Y,在未旋转的版本上仍然存在"重影"X/Y. 似乎这是操作的顺序:

  • 从未旋转的元素开始,X,Y为20,20
  • 旋转所述元素,导致X,Y报告为15,35
  • 将所述元素通过JavaScript/CSS移动到X,Y 10,10
  • 浏览器逻辑上将元素旋转回20,20,移动到10,10然后重新旋转,得到X,Y为5,25

所以...我希望元素在旋转后的10,10处结束,但是由于元素(看似)在移动后重新旋转,因此得到的X,Y与集合X,Y不同.

这是我的问题!因此我真正需要的是获取所需目标坐标(10,10)的功能,并从那里向后工作以获得将导致元素旋转到10,10的起始X,Y坐标.至少我知道我现在的问题是什么,感谢浏览器的内部工作原理,似乎旋转元素10 = 5!

Ósc*_*ios 16

我知道这有点晚了,但我在HTML5画布上为这个问题编写了一个小提琴:

http://jsfiddle.net/oscarpalacious/ZdQKg/

我希望有人觉得它很有用!

我实际上并没有计算容器左上角的x,y.它是作为偏移的结果计算的(来自小提琴示例的代码):

this.w = Math.sin(this.angulo) * rotador.h + Math.cos(this.angulo) * rotador.w;
this.h = Math.sin(this.angulo) * rotador.w + Math.cos(this.angulo) * rotador.h;
// The offset on a canvas for the upper left corner (x, y) is
// given by the first two parameters for the rect() method:
contexto.rect(-(this.w/2), -(this.h/2), this.w, this.h);
Run Code Online (Sandbox Code Playgroud)

干杯


Die*_*cKy 7

你尝试过使用getBoundingClientRect()吗?

考虑到旋转,此方法返回具有"底部,高度,左,右,顶部,宽度"的当前值的对象

  • 在大多数浏览器中,该功能不能转换.请参阅https://developer.mozilla.org/en-US/docs/DOM/element.getBoundingClientRect (2认同)

Ign*_*ams 1

将四个角从中心变为向量,旋转它们,并从中获取新的最小/最大宽度/高度。

编辑:

我明白你现在遇到问题的地方了。当您需要使用距旋转中心的偏移量进行计算时,您正在使用整个侧面进行计算。是的,这会产生四个旋转点(奇怪的是,这与您开始时的点数量完全相同)。它们之间有一个最小 X、一个最大 X、一个最小 Y 和一个最大 Y。这些就是您的界限。