Soru Bir SVG dikdörtgeninde metin nasıl yerleştirilir ve ortalanır?


Aşağıdaki dikdörtgene sahibim ...

<rect x="0px" y="0px" width="60px" height="20px"/>

İçinde "Kurgu" kelimesini ortalamak istiyorum. Diğer dikdörtgenler için, svg word wrap onların içinde kalmak için mi? Hem yatay hem de dikey olarak ortalanmış ve kelime sarmayı biçimlendiren şekiller içinde metin ekleme konusunda hiçbir şey bulamıyorum. Ayrıca, metin dikdörtgeni bırakamaz.

Bakıyor http://www.w3.org/TR/SVG/text.html#TextElement Örnek, metin öğesinin x ve y'nin dikdörtgen x ve y'den farklı olması nedeniyle yardımcı olmaz. Metin öğeleri için genişlik ve yükseklik yok gibi görünüyor. Buradaki matematikten emin değilim.

(Benim html tablomuz çalışmayacak.)


76
2018-04-05 02:00


Menşei




Cevaplar:


SVG 1.2 Minik metin ekleme, ancak tarayıcıda (Opera hariç) bulacağınız SVG'nin çoğu uygulaması bu özelliği uygulamamıştır. Metni el ile konumlandırmak genellikle geliştiricinize bağlıdır.

SVG 1.1 belirtimi, bu sınırlama ve bunun üstesinden gelmek için olası çözümler hakkında iyi bir genel bakış sağlar:

Her "metin" öğesi tek bir neden olur   işlenecek metin dizesi. SVG   otomatik satır kesme yapmaz veya   sarma kelimesi. Etkisi elde etmek   Birden fazla metin satırından birini kullanın   aşağıdaki yöntemler:

  • Yazar veya yazar paketi ihtiyacı   satır sonlarını önceden hesaplamak ve kullanmak için   Birden çok "metin" öğesi (her biri için bir tane   metin satırı).
  • Yazar veya yazar   Paket hattın önceden hesaplanması gerekiyor   tek bir ‘metin’ öğesi kırılır ve kullanılır   bir veya daha fazla ‘tspan’ çocuğuyla   uygun değerlere sahip öğeler   ‘x’, ‘y’, ‘dx’ ve ‘dy’ özelliklerini a   bunlar için yeni başlangıç ​​pozisyonları belirle   yeni satırlar başlatan karakterler.   (Bu yaklaşım kullanıcı metnine izin verir   çoklu hatlar arasında seçim   metin - bkz. Metin seçimi ve   panoya işlemleri.)
  • İfade etmek   başka bir XML'de oluşturulacak metin   XHTML [XHTML] gibi ad alanı   içinde satır içi gömülü   ‘ForeignObject’ öğesi. (Not:   Bu yaklaşımın kesin semantiği   bu zamanda tam olarak tanımlanmadı.)

http://www.w3.org/TR/SVG11/text.html#Introduction

İlkel olarak, metin özniteliği ve tspan elemanları kullanılarak simüle edilebilir ve özelliklerde belirtildiği gibi, bazı araçlar bunu otomatikleştirebilir. Örneğin, Inkscape'de, istediğiniz şekli ve istediğiniz metni seçin ve Metin -> Akışa Çerçeve'yi kullanın. Bu, metninizi, şeklin sınırlarına göre sarılacak olan sarma ile yazmanıza olanak tanır. Ayrıca, Inkscape'e SVG 1.1 ile uyumluluğu korumak için bu talimatları uyguladığınızdan emin olun: http://wiki.inkscape.org/wiki/index.php/FAQ#What_about_flowed_text.3F

Ayrıca, metin kaydırma işlemlerini dinamik olarak otomatikleştirmek için kullanılabilecek bazı JavaScript kitaplıkları vardır: http://www.carto.net/papers/svg/textFlow/

CSVG'nin bir şekli bir metin öğesine (ör. "Düğme" örneğine bakın) sarma çözümüne dikkat etmek ilginçtir, ancak bunların uygulanmasının söz konusu olduğundan bahsetmek önemlidir. değil bir tarayıcıda kullanılabilir: http://www.csse.monash.edu.au/~clm/csvg/about.html

Ben bundan bahsetmiyorum, çünkü ben henüz yayınlamamış olsa da, benzer şeyler yapmanıza ve web tarayıcılarında çalışmanıza izin veren bir CSVG esinli kitaplık geliştirdim.


34
2018-04-05 04:10



Ve beni yaratmaya neyin dahil olduğuna dair beni başlatma. düzenlenebilir Metin... - jbeard4
Cevabınız için teşekkürler ... ama ACK! O zaman svg dökmek zorunda kalacak gibi görünüyor. Geliştiricilerin üzerinde düşünmesi gereken ilk şeylerden biri, şekilleri biçimlendiren metinleri (kullanıcıların istediği şekilde biçimlendirilmiş) eklemekti! Daha önce onunla birlikte hareket etmeden önce onları bekleyeceğim. Windows Paint'te yeniden çizmeyi deneyeceğim ve bunun yapılıp yapılmayacağını göreceğim. (Yalnızca tabloyu doğru bir şekilde görüntülemek için tarayıcıları alabilirdim.) - Lady Aleena
Svg'de düzenlenebilir metin hakkında, Opera, yalnızca bir özellik ekleyerek düzenlenebilir metin elde etmeyi mümkün kılan SVG 1.2 Tiny'den düzenlenebilir özniteliği destekler. editable="true" metin veya textArea öğesine. - Erik Dahlström
@Erik, bir kez daha Opera eğrinin önünde. - jbeard4
@Lady Aleena, neden sadece mürekkebim Inkscape çözümünü kullanmıyorsun? Sadece statik bir görüntüse (ör. Dinamik davranış yoksa, dinamik bir metin içeriği güncellenmiyorsa), bu iyi çalışmalıdır. Ayrıca, Boya raster grafikler ürettikçe boyamayacak, ölçeklenebilir olacaktır. Son olarak, Paint'in herhangi bir düzeyde metin sarmayı desteklediğine inanmıyorum. - jbeard4


SVG'de metni yatay ve dikey olarak ortalamak için kolay bir çözüm:

  1. Metnin konumunu mutlak merkez ortalamak istediğiniz öğenin

    • Ebeveynse, yapabilirsin x="50%" y ="50%".
    • Eğer başka bir elementse x olurdu x bu elemanın + yarısının genişliği (ve benzeri için y ama yüksekliği ile).
  2. Kullan text-anchor Metni yatay olarak değerle ortalamak middle:

    orta

    İşlenen karakterler, sonuçta ortaya çıkan metnin geometrik ortası ilk geçerli metin konumunda olacak şekilde hizalanır.

  3. Kullan alignment-baseline metni dikey olarak değerle ortalamak için özellik middle (ya da nasıl görünmesini istediğinize bağlı olarak, yapmak isteyebilirsiniz central)

İşte basit bir demo:

<svg width="200" height="100">
  <rect x="0" y="0" width="200" height="100" stroke="red" stroke-width="3px" fill="white"/>
  <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">TEXT</text>    
</svg>


103
2017-07-20 16:50



Bu kadar basit bir çözüm için her yere bakıyordum - başka hiçbir şey benim için çalışmıyordu. Bunu radyal ilerleme çubuğunda bir sayıyı ortalamak için kullandım - anthonytherockjohnson
Benim durumumda, dominant-baseline işi yapan mülk değil, alignment-baseline. - pintoch
Ne yazık ki, bu çözüm dikdörtgen konturunu sarar. Kırpmayı engelleyen bir çözüm için aşağıdaki örneğe bakın: stackoverflow.com/a/44857272/3795219 - Austin D
Bunu düzenli olarak yapacaksanız, aşağıdakileri de ekleyebilirsiniz: <style type="text/css"><![CDATA[ text { alignment-baseline: middle; text-anchor:middle; } ]]></style>. Çözüm için teşekkürler. - Manngo


Önceki cevaplar yuvarlatılmış köşeleri kullanırken zayıf sonuç verdi veya stroke-width bu> 1. Örneğin, aşağıdaki kodun yuvarlatılmış bir dikdörtgen oluşturmasını beklersiniz, ancak köşeler ebeveyn tarafından kırpılır. svg bileşen:

<svg width="200" height="100">
  <!--this rect should have rounded corners-->
  <rect x="0" y="0" rx="5" ry="5" width="200" height="100" stroke="red" stroke-width="10px" fill="white"/>
  <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">CLIPPED BORDER</text>    
</svg>

Bunun yerine, text içinde svg ve sonra bu yeni yerleştirme svg ve rect birlikte bir g öğe, aşağıdaki örnekte olduğu gibi:

<!--the outer svg here-->
<svg width="400px" height="300px">

  <!--the rect/text group-->
  <g transform="translate(50,50)">
    <rect rx="5" ry="5" width="200" height="100" stroke="green" fill="none" stroke-width="10"/>
    <svg width="200px" height="100px">
      <text x="50%" y="50%" alignment-baseline="middle" text-anchor="middle">CORRECT BORDER</text>      
    </svg>
  </g>

  <!--rest of the image's code-->
</svg>

Bu, yukarıdaki yanıtlarda oluşan kırpma sorununu düzeltir. Ayrıca rect / text grubunu transform="translate(x,y)" Bunun, rect / text'i ekranda konumlandırmak için daha sezgisel bir yaklaşım sağladığını gösterme özniteliği.


7
2017-07-01 04:16





Doğrudan kullanabilirsiniz text-anchor = "middle" özelliği. Dikdörtgen ve metin üzerinde bir sarıcı svg öğesi oluşturmanızı öneriyorum. Bu şekilde bir css seçici kullanarak tüm elemanı kullanabilirsiniz. Metnin 'x' ve 'y' özelliklerini% 50 olarak seçtiğinizden emin olun.

<svg class="svg-rect" width="50" height="40">
        <rect x="0" y="0" rx="3" ry="3" width="50" height="40" fill="#e7e7e7"></rect>
        <text x="50%" y="50%" text-anchor="middle" stroke="black" stroke-width="1px" dy=".3em">N/A</text>
    </svg>

4
2017-08-11 21:10



düzenlendi. Teşekkürler. - Nalin Agrawal


Tam Detay Blog:http://blog.techhysahil.com/svg/how-to-center-text-in-svg-shapes/

<svg width="600" height="600">
  <!--   Circle -->
  <g transform="translate(50,40)">
    <circle cx="0" cy="0" r="35" stroke="#aaa" stroke-width="2" fill="#fff"></circle>
    <text x="0" y="0" alignment-baseline="middle" font-size="12" stroke-width="0" stroke="#000" text-anchor="middle">HueLink</text>
  </g>
  
  <!--   In Rectangle text position needs to be given half of width and height of rectangle respectively -->
  <!--   Rectangle -->
  <g transform="translate(150,20)">
    <rect width="150" height="40" stroke="#aaa" stroke-width="2" fill="#fff"></rect>
    <text x="75" y="20" alignment-baseline="middle" font-size="12" stroke-width="0" stroke="#000" text-anchor="middle">HueLink</text>
  </g>
  
  <!--   Rectangle -->
  <g transform="translate(120,140)">
    <ellipse cx="0" cy="0" rx="100" ry="50" stroke="#aaa" stroke-width="2" fill="#fff"></ellipse>
    <text x="0" y="0" alignment-baseline="middle" font-size="12" stroke-width="0" stroke="#000" text-anchor="middle">HueLink</text>
  </g>
  
  
</svg>


4
2017-11-15 23:50



Diğer çözümler ise firefox merkezli değil. codepen.io/anon/pen/oEByYr - tgf
Firefox 58.0.1 üzerinde test ettim (64-bit), çalışıyor. Bunun sizin için çalışmadığı sürümü söyleyebilir misiniz? - Sahil Gupta
Firefox 58.0.2 64bit. Metin olması gerekenden biraz daha yüksektir. İlk başta kolayca fark edilmeyebilir, ancak kutunuz çok yakına geliyorsa, daha belirgin olur; yüksekliği azaltmayı deneyin. - tgf


SVG kullanarak ortalanmış bir şey elde etmek için zaman geçirdim, kendi küçük işlevimi yuvarladım. Umarım size yardımcı olmalıdır. Sadece SVG öğeleri için çalıştığını unutmayın.

function centerinparent(element) { //only works for SVG elements
    var bbox = element.getBBox();
    var parentwidth = element.parentNode.width.baseVal.value;
    var parentheight = element.parentNode.height.baseVal.value;
    var newwidth = ((parentwidth / 2) - (bbox.width / 2)) - 2; //i start everything off by 2 to account for line thickness
    var newheight = ((parentheight / 2) - (bbox.height / 2)) - 2;
    //need to adjust for line thickness??

    if (element.classList.contains("textclass")) { //text is origined from bottom left, whereas everything else origin is top left
        newheight += bbox.height; //move it down by its height
    }

    element.setAttributeNS(null, "transform", "translate(" + newwidth + "," + newheight + ")");
    // console.log("centering BOXES:  between width:"+element.parentNode.width.baseVal.value + "   height:"+parentheight);
    // console.log(bbox);
}

1
2017-11-02 04:02





Bir dikdörtgenin içine metin eklemenin bir yolu, rect nesnesinin içinde DIV olan yabancı bir nesneyi yerleştirmektir.

Bu şekilde, metin DIV'nin sınırlarına uygun olacaktır.

var g = d3.select("svg");
					
g.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width","100%")
.attr("height","100%")
.attr("fill","#000");


var fo = g.append("foreignObject")
 .attr("width","100%");

fo.append("xhtml:div")
  .attr("style","width:80%;color:#FFF;margin-right: auto;margin-left: auto;margin-top:40px")
  .text("Mussum Ipsum, cacilds vidis litro abertis Mussum Ipsum, cacilds vidis litro abertis Mussum Ipsum, cacilds vidis litro abertis");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.js"></script>
<svg width="200" height="200"></svg>


1
2018-06-20 14:52



Yığın Taşması'na Hoş Geldiniz! Lütfen çekinmeyin tur sitenin ve siteyle ilgili ek yardıma ihtiyacınız varsa, kontrol edin bu dışarı. Oh, ve yardım sayfasının kapsamadığı sorunlarla karşılaşırsanız, sormaya çekinmeyin. meta. - Isiah Meadows