2013-03-15 25 views
40

Kích thước hộp đã biết. Độ dài chuỗi văn bản không xác định. Khớp văn bản thành hộp mà không làm hỏng tỷ lệ khung hình của nó.Cách SVG thuần túy để vừa với văn bản thành một hộp

enter image description here

Sau một buổi tối googling và đọc spec SVG, tôi khá chắc chắn điều này là không thể mà không cần javascript. Gần nhất tôi có thể nhận được là sử dụng textLength và lengthAdjust các thuộc tính văn bản, nhưng chỉ kéo dài văn bản dọc theo một trục.

<svg width="436" height="180" 
    style="border:solid 6px" 
    xmlns="http://www.w3.org/2000/svg"> 
    <text y="50%" textLength="436" lengthAdjust="spacingAndGlyphs">UGLY TEXT</text> 
</svg> 

enter image description here

tôi biết SVG Scaling Text to fit containerfitting text into the box

+1

Tôi đã kết thúc lên một vòng lặp trong javascript làm tăng kích thước phông chữ cho đến khi getBBox cho thấy nó sẽ không còn phù hợp. Ugly, vì vậy vẫn hy vọng sẽ có một số cách khác. – Bemmu

+0

Tôi cũng đã cố gắng để có được chức năng tương tự này để hoạt động. Phương pháp tốt nhất tôi đã tìm thấy là một trong những bạn đã làm. Lặp qua JS và thay đổi phông chữ cho đến khi nó khớp. Nhưng ngay cả trong phông chữ vẫn còn một số khoảng trắng ở trên và dưới đây, do đó bạn dường như không thể làm cho nó vừa phải. – Chad

+0

Điều này hút, nó có vẻ giống như một điều cơ bản, nhưng spec là rõ ràng rằng nó chỉ trải dài nó theo một hướng.Sau khi chơi xung quanh, tôi đã có thể làm cho nó gần bằng cách thay đổi quy mô Y bằng cách sử dụng biến đổi, aka: 'transform =" scale (0,5) "' - http://jsfiddle.net/G5L8W/ – streetlogics

Trả lời

30

tôi không tìm thấy một cách để làm điều đó trực tiếp mà không Javascript, nhưng tôi tìm thấy một giải pháp JS khá dễ dàng, mà không cho lặp lại và không sửa đổi kích thước phông chữ và phù hợp với mọi kích thước, tức là văn bản sẽ tăng lên cho đến khi giới hạn của cạnh ngắn nhất.

Về cơ bản, tôi sử dụng thuộc tính transform, tính tỷ lệ đúng giữa kích thước mong muốn và kích thước hiện tại.

Đây là mã:

<?xml version="1.0" encoding="UTF-8" ?> 
<svg version="1.2" viewBox="0 0 1000 1000" width="1000" height="1000" xmlns="http://www.w3.org/2000/svg" > 
<text id="t1" y="50" >MY UGLY TEXT</text> 
<script type="application/ecmascript"> 

    var width=500, height=500; 

    var textNode = document.getElementById("t1"); 
    var bb = textNode.getBBox(); 
    var widthTransform = width/bb.width; 
    var heightTransform = height/bb.height; 
    var value = widthTransform < heightTransform ? widthTransform : heightTransform; 
    textNode.setAttribute("transform", "matrix("+value+", 0, 0, "+value+", 0,0)"); 

</script> 
</svg> 

Trong ví dụ trước văn bản phát triển cho đến khi width == 500, nhưng nếu tôi sử dụng một kích thước hộp width = 500height = 30, thì văn bản phát triển cho đến khi height == 30.

+6

Hoặc đơn giản là ... textNode.setAttribute ("transform", "scale (" + value + ")"); –

+2

Ghi chú nhanh - thuộc tính tỷ lệ cũng ảnh hưởng đến hệ tọa độ của mục hiện tại, vì vậy nếu bạn muốn phần tử ở cùng vị trí, sẽ cần chia cả vị trí x và y theo vô hướng để có cùng vị trí tương đối – MDragon00

9

trước hết là: chỉ thấy rằng câu trả lời không chính xác giải quyết nhu cầu của bạn - nó vẫn có thể là một lựa chọn, vì vậy ở đây chúng tôi go:

bạn đang quan sát đúng rằng svg không hỗ trợ trực tiếp gói từ. tuy nhiên, bạn có thể hưởng lợi từ các phần tử foreignObject đóng vai trò như một trình bao bọc cho các đoạn xhtml, nơi có sẵn gói từ.

có một cái nhìn tại bản demo khép kín này (có sẵn online):

<?xml version="1.0" encoding="utf-8"?> 
<!-- SO: http://stackoverflow.com/questions/15430189/pure-svg-way-to-fit-text-to-a-box --> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg xmlns="http://www.w3.org/2000/svg" 
    xmlns:xhtml="http://www.w3.org/1999/xhtml" 
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    version="1.1" 
    width="20cm" height="20cm" 
    viewBox="0 0 500 500" 
    preserveAspectRatio="xMinYMin" 
    style="background-color:white; border: solid 1px black;" 
> 
    <title>simulated wrapping in svg</title> 
    <desc>A foreignObject container</desc> 

    <!-- Text-Elemente --> 
    <foreignObject 
     x="100" y="100" width="200" height="150" 
     transform="translate(0,0)" 
    > 
     <xhtml:div style="display: table; height: 150px; overflow: hidden;"> 
     <xhtml:div style="display: table-cell; vertical-align: middle;"> 
      <xhtml:div style="color:black; text-align:center;">Demo test that is supposed to be word-wrapped somewhere along the line to show that it is indeed possible to simulate ordinary text containers in svg.</xhtml:div> 
     </xhtml:div> 
     </xhtml:div> 
    </foreignObject> 

    <rect x="100" y="100" width="200" height="150" fill="transparent" stroke="red" stroke-width="3"/> 
</svg> 
+0

Cảm ơn, nhưng không quan tâm đến việc gói từ. – Bemmu

+0

Tôi chỉ cần điều này :) –

0

Tôi không nghĩ giải pháp cho những gì bạn muốn làm nhưng bạn có thể sử dụng textlenght với tỷ lệ phần trăm ="100%" cho chiều rộng đầy đủ.

<svg width="436" height="180" 
    style="border:solid 6px" 
    xmlns="http://www.w3.org/2000/svg"> 
    <text x="0%" y="50%" textLength="100%">blabla</text> 
</svg> 

bạn cũng có thể thêm textanchor="middle" và thay đổi vị trí x để tập trung hoàn toàn văn bản của bạn

này sẽ không thay đổi fontsize và bạn sẽ có letterspacing không gian lạ ...

JSFIDDLE DEMO

Các vấn đề liên quan