2017-05-25 73 views
2

通常爲了獲得SVG中任何元素的邊界框,我們使用getBoundingClientRect()或getBBox(),它給了我們頂部,底部,左側,右側,寬度,高度或x ,y,寬度,高度。但是,當旋轉文本時,這些值不足以獲得元素的緊密邊界框,因爲由這些值形成的框將具有水平和垂直邊緣,而不平行於文本。如何爲如下圖所示的旋轉文字選擇緊密邊界框。 (由鍍鉻突出顯示的文本檢查元素選擇。)如何獲得SVG文本元素的緊邊框

+0

一種測試代碼的例子是有用的。不太確定,如果你只是爲了顯示的意義,例如你不能只是旋轉邊界框?也許這個問題也是你想用它做什麼? – Ian

+0

簡而言之,我只需要邊界框的四個點(x,y)(不是x,y的寬度和高度),以便我可以知道我的文本在平面中的位置以及需要處理多少空間。 –

回答

0

如果您收到使用getBBox()一個<text>元素的邊框,那麼它通常是未旋轉的邊界框。這是因爲getBBox()在計算要返回的值時不包含元素transform

例如,看看下面的例子。比較文本BBox和其父組元素的BBox。

var text = document.getElementById("text"); 
 
var b = text.getBBox(); 
 
console.log("text bbox="+[b.x,b.y,b.width,b.height].join(' ')); 
 

 
var group = document.getElementById("group"); 
 
var b = group.getBBox(); 
 
console.log("group bbox="+[b.x,b.y,b.width,b.height].join(' '));
<svg width="300" height="300"> 
 

 
    <g id ="group"> 
 
    <text id="text" x="150" y="150" text-anchor="middle" font-size="30" 
 
      transform="rotate(45,150,150)">ROTATED</text> 
 
    </g> 
 

 
</svg>

1

我認爲,如果你想在4個點,你可能不得不改變他們的邊框具有相同轉化爲元素。如果僅用於顯示,只需將相同的變換應用於已顯示的邊界框即可。我認爲如果你想得到4分,那會更復雜一點,但可能有一個更簡單的方法。

無論如何,這可能是有用的。

我們抓住文本的邊界框。 我們抓住元素上的矩陣(在這種情況下是旋轉)。然後我們將它應用於我們從邊界框收集的所有點。 我已經添加了更多的代碼,只是爲了在點上創建圓圈來突出顯示它。

var text = document.querySelector('text'); 
 
var svg = document.querySelector('svg') 
 

 

 
function getTransformedPts(el) { 
 
    var m = el.getCTM(); 
 
    var bb = el.getBBox(); 
 
    var tpts = [ 
 
    matrixXY(m,bb.x,bb.y), 
 
    matrixXY(m,bb.x+bb.width,bb.y), 
 
    matrixXY(m,bb.x+bb.width,bb.y+bb.height), 
 
    matrixXY(m,bb.x,bb.y+bb.height) ] 
 
    
 
    return tpts; 
 
} 
 

 
function matrixXY(m,x,y) { 
 
      return { x: x * m.a + y * m.c + m.e, y: x * m.b + y * m.d + m.f }; 
 
} 
 

 
var pts = getTransformedPts(text); 
 

 
for(pt in pts) { 
 
    var c = document.createElementNS("http://www.w3.org/2000/svg","circle"); 
 
    c.setAttribute('cx', pts[pt].x); 
 
    c.setAttribute('cy', pts[pt].y); 
 
    c.setAttribute('r',3) 
 
    svg.append(c) 
 
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="800" height="800"> 
 
<text x="50" y="50" transform="rotate(10)" font-size="30">testing rotated text box points</text> 
 
</svg>