2011-05-30 24 views
34

我有一個g元素,其中包含一個或多個path元素。正如我在another question中提到的那樣,我通過計算transform屬性來縮放和翻譯g元素,以便它適合畫布另一部分中的網格。如何計算getBBox()SVGRect?

計算是通過使用兩個矩形之間的差值,來自g元素的getBBox()和網格周圍的矩形完成的。

這裏的問題 - 畢竟我做的變換,我更新g元素的內容,並再次呼籲getBBox()沒有去除transform。得到的矩形似乎在不考慮transform的情況下進行計算。我預料它會反映這種變化。這種行爲是否與SVG規範一致?如何獲得變換矩形的邊界框?

這是BTW,它在Firefox 4中運行的HTML 5文檔中,如果這有什麼區別的話。

更新:顯然這種行爲似乎很明顯違反了規範。從文本here at w3c

SVGRect getBBox()

返回當前用戶空間緊張的邊框(即應用程序的「變換」屬性,如果有的話)之後所有的幾何包含圖形元素,不包括撫摸,裁剪,蒙版和過濾效果)。請注意,getBBox必須在調用方法時返回實際的邊界框,即使元素尚未呈現。

我正確地讀這個嗎?如果是這樣的話,這似乎是Firefox使用SVG實施的一個錯誤;我沒有機會嘗試任何其他的。如果有人能指出我的位置,我會提交一份錯誤報告。

+1

10年後,瀏覽器中的SVG支持仍然是一個惹人注目的事情。 (更不用說SMIL ...... :() – 2011-06-05 11:01:11

回答

14

您所看到的行爲是正確的,並與規範相一致。 應用變換,然後以「當前用戶單位」(即當前用戶空間)計算bbox。所以如果你想看到元素轉換的結果,你需要查看一個父節點或類似的bbox。 這有點令人困惑,但在SVG Tiny 1.2 spec for SVGLocatable 中有更好的解釋,其中包含了很多可以闡明它應該做什麼的例子。

+2

感謝您的回答 - SVG 1.1規範至少在這個問題上有點混亂。 – AlanObject 2011-06-10 20:49:06

4

顯然getBBox()不考慮轉換。

我可以在這裏點你,可惜我不能讓它工作:http://tech.groups.yahoo.com/group/svg-developers/message/22891

+1

顯然這似乎違反了規範 - 請參閱我上面的更新 – AlanObject 2011-06-04 21:14:30

+0

它確實將轉換考慮在內,但元素必須放在''標籤內正在轉換 – 2015-07-24 18:56:54

+0

只適用於寬度和高度,不給x和y座標 反正很好謝謝 – atilkan 2015-11-11 14:41:18

6

至少有2點簡單但有點哈克的方式做你問什麼......如果有更好的(少哈克)的方式,我還沒有找到他們沒有

EASY哈克#1:
a)設置與「未轉換」bbox相匹配的矩形,即group.getBBox()返回
b)將該組的「未應用轉換」應用於該矩形c)rect。getBBox()現在應該回到你正在尋找的BBOX

EASY哈克#2:(僅適用於Chrome測試)
一)使用element.getBoundingClientRect(),它返回足夠的信息,爲您構建BBOX你'尋找

+0

getBoundingClientRect()非常適合我在縮放後獲取有關我的形狀的新大小信息。謝謝! – 2012-12-21 16:51:34

3

SVG組有惡劣的做法 - 不積累所有的轉換。我有辦法解決這個問題。我使用自己的屬性來存儲當前的轉換數據,這些數據包含在進一步的轉換中。使用XML兼容的屬性,如alttext,value,name ....或者只是x和y用於存儲累積值作爲屬性。

實施例:

<g id="group" x="20" y"="100" transform="translate(20, 100)"> 
<g id="subgroup" alttext="45" transform="rotate(45)"> 
<line...etc... 

因此,當我正在轉換我正在那些手工屬性值,和寫入它,當回,我正在寫兩個變換和相同的值具有屬性我發只是爲了保持所有累計值。

實施例進行旋轉:

function symbRot(evt) { 

evt.target.ondblclick = function() { 

stopBlur(); 
var ptx=symbG.parentNode.lastChild.getAttribute("cx"); 
var pty=symbG.parentNode.lastChild.getAttribute("cy"); 
var currRot=symbG.getAttributeNS(null, "alttext"); 

var rotAng; 
if (currRot == 0) { rotAng = 90 } else if (currRot == 90) { rotAng = 180 } else if (currRot == 180) { rotAng = 270 } else if (currRot == 270) { rotAng = 0 }; 
symbG.setAttributeNS(null, "transform", "rotate(" + rotAng + "," + ptx + ", " + pty + ")"); 
symbG.setAttributeNS(null, "alttext", rotAng); 
}; 
} 
13

的人經常通過getBBox和getBoundingClientRect的行爲差異混淆。

getBBox是SVG元素的本地方法,等同於查找HTML DOM元素的偏移量/客戶端寬度。寬度和高度爲即使元素旋轉也不會改變。它不能用於HTML DOM元素。

getBoundingClientRect對於HTML和SVG元素都很常見。當元素旋轉或更多元素被分組時,bounded rectangle寬度和高度將會改變。