我正在尝试找到获取屏幕像素中任意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/
然而,正如测试所示,当变换中包含旋转时,这种方法似乎失败 - 看起来边界框是在旋转前计算的,因此获取旋转边界框的角不起作用。
如何正确计算转换元素的非旋转边界框?
答案 0 :(得分:4)
经过一番研究,以下是我发现的最佳选择:
getBoundingClientRect()
似乎适用于现代浏览器中的SVG元素,并且速度非常快,但结果可能因平台而有所不同(特别是如果你有足够的笔画宽度)。但是,对于@Sergiu来说,这并没有考虑到形状的变化,并且给出了旋转的边界框的边界,而不是实际的路径或对象,所以它可能非常不精确 - see criticism here。示例小提琴:http://jsfiddle.net/stevenbenner/6M5zf/
我的主要目标是获得边界矩形的位置角和中点,最后我决定使用旋转的边界框甚至可能优于旋转形状的“真实”边界框。我能够使用上面的方法做到这一点,然后循环点以尽可能接近N,S,E,W位置。你可以在这里看到我的例子:http://jsfiddle.net/nrabinowitz/sPtzV/
答案 1 :(得分:3)
我不认为这是可能的,因为歪斜和旋转涉及轮廓变化,或者两个轴上的形状投影看起来如何。
你可以计算忽略CTM旋转部分的变换矩阵,但是你不能保证新的BBox仍然会围绕你的旋转元素。例如,如果您有一个圆,则旋转不会影响边界框的尺寸。另一方面,如果你有一个钻石作为基本路径,并将它旋转45度,那么最后它只是一个正方形,边界框是不同的:最初你是测量对角线,现在你必须得到一个测量边长的边界框。无论您如何使用CTM,都无法考虑形状的变化。
所以,轮换实际上非常重要,忽略它不是一个选择;但只是局部边界框和变换矩阵没有说明形状轮廓在旋转时如何变化。