【问题标题】:Get the bounds of a rotated SVG element in screen pixels?以屏幕像素为单位获取旋转的 SVG 元素的边界?
【发布时间】:2012-08-25 13:15:39
【问题描述】:

我正在尝试找到以屏幕像素为单位获取任意 SVG 元素边界框的最佳方法,以便正确覆盖 HTML 元素。到目前为止,我的方法是使用.getBBox().getCTM() 检索对象的边界框和变换矩阵,然后将变换应用于边界框点,如this question 接受的答案中所述。

// get the element
var el = $(selector)[0],
    pt = $(selector).closest('svg')[0].createSVGPoint();

// get the bounding box and matrix
var bbox = el.getBBox(),
    matrix = el.getScreenCTM();

pt.x = bbox.x;
pt.y = bbox.y;
var nw = pt.matrixTransform(matrix);
pt.x += bbox.width;
pt.y += bbox.height;
var se = pt.matrixTransform(matrix);

// make a div in the screen space around the object
var $div = $('<div class="bbox"/>').css({
        left: nw.x,
        top: nw.y,
        width: se.x - nw.x,
        height: se.y - nw.y
    })
    .appendTo('body');

你可以在这里看到我的测试:http://jsfiddle.net/nrabinowitz/zr2jX/

但是,正如测试所示,当变换中包含旋转时,这种方法似乎会失败 - 看起来边界框是在旋转前计算的,因此获取旋转边界框的角不起作用。

如何正确计算转换后元素的非旋转边界框?

【问题讨论】:

    标签: javascript svg bounding-box


    【解决方案1】:

    经过一些研究,以下是我发现的最佳选择:

    • getBoundingClientRect() 似乎适用于现代浏览器中的 SVG 元素,并且速度非常快,但结果可能因平台而异(尤其是如果您的笔画宽度很大)。但是,就@Sergiu 而言,这并没有考虑到形状的变化,而是为您提供了旋转边界框的边界,而不是实际的路径或对象,因此它可能非常不精确-see criticism here。小提琴示例:http://jsfiddle.net/stevenbenner/6M5zf/

    • 我的主要目标是获取边界矩形的位置角和中点,最后我决定使用旋转的边界框甚至可能比旋转形状的“真实”边界框更可取。我能够使用上述方法做到这一点,然后循环点以尽可能接近 N、S、E、W 位置。你可以在这里看到我的小提琴示例:http://jsfiddle.net/nrabinowitz/sPtzV/

    【讨论】:

      【解决方案2】:

      我认为这是不可能的,因为倾斜和旋转涉及轮廓变化,或者形状在两个轴上的投影看起来如何。

      您可以计算忽略 CTM 旋转部分的转换矩阵,但是您无法保证新的 BBox 仍将围绕您的旋转元素。例如,如果您有一个圆形,则旋转不会影响边界框的尺寸。另一方面,如果您有一个菱形作为基本路径,并将其旋转 45 度,最终它只是一个正方形,那么边界框就不同了:最初您测量的是对角线,而现在您必须获得一个测量边长的边界框。无论如何使用CTM,都无法考虑到形状的变化。

      所以,轮换实际上非常重要,忽略它不是一种选择;但是只有局部边界框和变换矩阵并不能说明形状轮廓在旋转时如何变化。

      【讨论】:

      • 这是一个很好的观点,但是 a) 如果我能得到旋转边界框的基本边界,那将是最好的,b) 我希望 SVG 中有一些我不知道的东西API 可以根据转换后的形状为我提供一个新的边界框。
      • 理论上您可以使用checkEnclosure 对完全包围您的元素的最小矩形进行一种二分搜索。不幸的是it's not implemented in Firefox yet
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-25
      • 2012-03-18
      • 1970-01-01
      • 2011-08-15
      • 2019-01-05
      • 1970-01-01
      相关资源
      最近更新 更多