2012-08-30 134 views
5

我試圖找到最好的方法來獲取屏幕像素中任意SVG元素的邊界框,以便正確地覆蓋HTML元素。到目前爲止,我的方法是使用.getBBox().getCTM()來檢索對象的邊界框和變換矩陣,然後將該變換應用到邊界框點,如this question的接受答案中所述。獲取屏幕像素中旋轉的SVG元素的邊界?

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

然而,隨着測試表明,這種做法似乎當有包含在變換旋轉失敗 - 它看起來像邊界框計算預旋轉,因此旋轉邊界框的拐角不起作用。

如何正確計算轉換元素的非旋轉邊界框?

回答

4

經過一番研究,這裏是我發現最好的選擇:

  • getBoundingClientRect()似乎也爲現代瀏覽器SVG元素的工作,而且是相當快的,但結果可能會與平臺有所不同,以平臺(特別是如果你有一個相當大的筆畫寬度)。但是,對於@ Sergiu來說,這並不能解釋形狀的變化,並且給出了旋轉邊界框的邊界,而不是實際的路徑或對象,所以它可能相當不精確 - see criticism here。示例小提琴:http://jsfiddle.net/stevenbenner/6M5zf/

  • 我的主要目標是獲取邊界矩形的位置角點和中點,最後我決定使用旋轉的邊界框甚至可能比旋轉的「真實」邊界框更可取形狀。我能夠使用上述方法做到這一點,然後循環點以儘可能接近N,S,E,W位置。你可以看到我的例子小提琴這裏:http://jsfiddle.net/nrabinowitz/sPtzV/

3

我不認爲這是可能的,因爲歪斜和旋轉涉及配置文件更改或兩個軸上的形狀投影的外觀。

您可以計算忽略CTM旋轉部分的變換矩陣,但是您不能保證新的BBox仍然會圍繞旋轉的元素。例如,如果您有一個圓,則旋轉不會影響邊界框的尺寸。另一方面,如果你有一個鑽石作爲基本路徑,並且將它旋轉45度,那麼最終它只是一個正方形,邊界框是不同的:原本你在測量對角線,現在您必須獲得測量邊長的邊界框。無論您如何使用CTM,都無法考慮形狀的變化。

所以,輪換其實很重要,忽略它不是一種選擇;但是局部邊界框和變換矩陣不會告訴任何有關旋轉時形狀輪廓如何變化的信息。

+0

這是一個很好的點,而是一個),這將是最好的,如果我能得到旋轉邊框的基本界限,和b)我希望有什麼東西我不知道在SVG API中可以給我一個基於轉換形狀的新邊界框。 – nrabinowitz

+0

理論上,您可以使用[checkEnclosure](http://www.w3.org/TR/SVG11/struct.html#__svg__SVGSVGElement__checkEnclosure)對完全包含元素的最小矩形進行二分法搜索。不幸的是[它尚未在Firefox中實現](https://bugzilla.mozilla.org/show_bug.cgi?id=501421)。 –