SVG'deki metnin arka plan rengi


103

Ben svg arka planını renklendirmek istiyorum textbenzer background-colorcss içinde

Sadece fillmetnin hangi renklerle ilgili belgeleri bulabildim

Hatta mümkün mü?


Şimdiye kadar kodunuzu paylaşabilir misiniz?
gotohales


stackoverflow.com/questions/12260370/… ayrıca bunun filtreler kullanılarak nasıl yapılacağını da gösterir.
Erik Dahlström

1
@RobertLongson Bu soruyu diğerinden 2 yıl önce sorulduğunda mükerrer olarak kapatmak yanlış görünüyor, özellikle de tek cevap sizin olduğu zaman.
Balthazar

@ Aperçu: Yinelenen bir hedef seçerken sorunun yaşı ana faktör değildir, örneğin buraya bakınız .
honk

Yanıtlar:


95

Hayır, bu mümkün değildir, SVG öğelerinin background-... sunum nitelikleri yoktur .

Bu efekti simüle etmek için text niteliğinin arkasına ile fill="green"veya benzer bir şeyle (filtreler) bir dikdörtgen çizebilirsiniz . JavaScript kullanarak şunları yapabilirsiniz:

var ctx = document.getElementById("the-svg"),
textElm = ctx.getElementById("the-text"),
SVGRect = textElm.getBBox();

var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
    rect.setAttribute("x", SVGRect.x);
    rect.setAttribute("y", SVGRect.y);
    rect.setAttribute("width", SVGRect.width);
    rect.setAttribute("height", SVGRect.height);
    rect.setAttribute("fill", "yellow");
    ctx.insertBefore(rect, textElm);

9
Bu veya metin üzerinde bir svg filtresi (feFlood + feComposite) kullanın. Biraz benzer soruya bakın stackoverflow.com/questions/12260370/… .
Erik Dahlström

3
GetBBox () kullanan bu çözüm, gayet iyi çalışmasına rağmen, çok sayıda hesaplama yapılması gerektiğinde oldukça yavaş olabilir. Bir svg filtresi (feFlood + feComposite) kullanmanın sorunu, metnin biraz pürüzlü çıkmasıdır. Aşağıda basit ama hilekâr bir çözüm önerdik.
dbarton_uk

TextElm = ctx.getElementById ("the-text") yerine textElm = document.getElementById ("the-text") kullanmak daha mı iyidir?
Simon Hi

NodeJS'de aynı getBBox işlevini nasıl kullanırım
Ali

78

Arka planı oluşturmak için bir filtre kullanabilirsiniz.

<svg width="100%" height="100%">
  <defs>
    <filter x="0" y="0" width="1" height="1" id="solid">
      <feFlood flood-color="yellow"/>
      <feComposite in="SourceGraphic" operator="xor" />
    </filter>
  </defs>
<text filter="url(#solid)" x="20" y="50" font-size="50">solid background</text>
</svg>


1
"SourceGraphic" burada ne anlama geliyor? "Url (#solid)" aslında fazladan bir web erişimine neden olur mu?
Ben Slade

7
burada metin bulanık :(
teran

5
Arka plan dolgusu verebilir misiniz?
vsync

2
Bu çözümü teoride sevin, ancak metnin bulanık olduğunu doğrulayabilir. Görünüşe göre filtre kenar yumuşatmayı bozuyor.
paulmelnikow

2
Metnin bulanık olmasını önlemek operator="xor"için ekleyin feComposite. @RobertLongson @teran @paulmelnikow @bill
Saeid

20

Kullandığım çözüm:

<svg>
  <line x1="100" y1="100" x2="500" y2="100" style="stroke:black; stroke-width: 2"/>    
  <text x="150" y="105" style="stroke:white; stroke-width:0.6em">Hello World!</text>
  <text x="150" y="105" style="fill:black">Hello World!</text>  
</svg>

Kontur ve kontur genişliği nitelikleriyle yinelenen bir metin öğesi yerleştiriliyor. Kontur arka plan rengiyle eşleşmeli ve kontur genişliği, üzerine gerçek metnin yazılacağı bir "ayrılma" oluşturmaya yetecek kadar büyük olmalıdır.

Biraz hile ve olası sorunlar var, ancak benim için çalışıyor!


1
Bu çözümü en kolayı olarak buldum.
Morgan Wilde

Bunu en kolay çözüm olarak doğruladı
scipper

Ayrıca, filtre çözümü yazdırıldığında çok bulanık olduğu için güzel bir şekilde yazdırır.
David Hunt

18

Hayır, SVG öğelerine arka plan rengi ekleyemezsiniz. Bunu d3 ile programlı olarak yapabilirsiniz .

var text = d3.select("text");
var bbox = text.node().getBBox();
var padding = 2;
var rect = self.svg.insert("rect", "text")
    .attr("x", bbox.x - padding)
    .attr("y", bbox.y - padding)
    .attr("width", bbox.width + (padding*2))
    .attr("height", bbox.height + (padding*2))
    .style("fill", "red");

3
Bu çalışmıyor; arka plan rengini değil, yalnızca metnin rengini değiştirir.
David J.

1
İçine alın metni bir de div veya yayılma ve son iki kullandığınız hangisi için stil geçerlidir.
Arif Burhan

Bu gönderi bunu iyi açıklıyor: cambridge-intelligence.com/…
değişim


4

Robert Longson (@RobertLongson) tarafından değişikliklerle cevap:

<svg width="100%" height="100%">
  <defs>
    <filter x="0" y="0" width="1" height="1" id="solid">
      <feFlood flood-color="yellow"/>
      <feComposite in="SourceGraphic" operator="xor"/>
    </filter>
  </defs>
  <text filter="url(#solid)" x="20" y="50" font-size="50"> solid background </text>
  <text x="20" y="50" font-size="50">solid background</text>
</svg>

ve hiçbir bulanıklık ve ağır bir "getBBox" yok :) Dolgu, filtreli metin öğesindeki beyaz boşluklarla sağlanır. Benim için çalıştı


2

bu benim en sevdiğim hack (çalışacağından emin değilim). Henüz görüntülenmemiş bir öğeye atıfta bulunuyor ve oldukça iyi çalışıyor

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 620 40" preserveAspectRatio="xMidYMid meet">
    <defs>
        <filter x="-0.02" y="0" width="1.04" height="1.1" id="removebackground">
            <feFlood flood-color="#00ffff"/>
        </filter>
    </defs>

    <!--Draw the text--> 
    <use xlink:href="#mygroup" filter="url(#removebackground)" />
    <g id="mygroup">
        <text id="text1" x="9" y="20" style="text-anchor:start;font-size:14px;">custom text with background</text>  
        <line x1="200" y1="18" x2="200" y2="36" stroke="#000" stroke-width="5"/> 
        <line x1="120" y1="27" x2="203" y2="27" stroke="#000" stroke-width="5"/> 
    </g>
</svg>


2

Filtreyi metinle birleştirebilirsiniz.

<!DOCTYPE html>
<html>
  <head>
    <meta charset=utf-8 />
    <title>SVG colored patterns via mask</title>
  </head>
  <body>
    <svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <filter x="0" y="0" width="1" height="1" id="bg-text">
          <feFlood flood-color="white"/>
          <feComposite in="SourceGraphic" operator="xor" />
        </filter>
      </defs>
	  <!-- something has already existed -->
    <rect fill="red" x="150" y="20" width="100" height="50" />
    <circle cx="50"  cy="50" r="50" fill="blue"/>
      
      <!-- Text render here -->
      <text filter="url(#bg-text)" fill="black" x="20" y="50" font-size="30">text with color</text>
      <text fill="black" x="20" y="50" font-size="30">text with color</text>
    </svg>
  </body>
</html> 


1

Robert'ın cevabında olduğu gibi bir arka plana sahip bir metin öğesine nasıl dolgu uygulanacağını merak edenler için şunları yapın :

  <svg>
    <defs>
      <filter x="-0.1" y="-0.1" width="1.2" height="1.2" id="solid">
        <feFlood flood-color="#171717"/>
        <feComposite in="SourceGraphic" operator="xor" />
      </filter>
    </defs>
    <text filter="url(#solid)" x="20" y="50" font-size="50">Hello</text>
  </svg>

Yukarıdaki örnekte, süzgeç x ve y pozisyonları olarak kullanılabilir transform: translate(-10%, -10%)ediyorum ve genişlik ve yüksekliği değerleri olarak okunabilir 120%ve 120%. Böylece arka planı% 20 büyüttük ve onu -% 10 dengeledik, böylece arka plan artık metnin her iki tarafında% 10 daha büyük.


0

Önceki cevaplar metni ikiye katlamaya dayanıyordu ve yeterli boşluk yoktu.

Kullanarak atopve &nbsp;istediğim sonuçları alabildim.

Bu örnek, SVG metin etiketleri için yaygın bir kullanım durumu olan okları da içerir:

<svg viewBox="-105 -40 210 234">
<title>Size Guide</title>
<defs>
    <filter x="0" y="0" width="1" height="1" id="solid">
        <feFlood flood-color="white"></feFlood>
        <feComposite in="SourceGraphic" operator="atop"></feComposite>
    </filter>
    <marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
        <path d="M 0 0 L 10 5 L 0 10 z"></path>
    </marker>
</defs>
<g id="garment">
    <path id="right-body" fill="none" stroke="black" stroke-width="1" stroke-linejoin="round" d="M0 0 l30 0 l0 154 l-30 0"></path>
    <path id="right-sleeve" d="M30 0 l35 0 l0 120 l-35 0" fill="none" stroke-linejoin="round" stroke="black" stroke-width="1"></path>
    <use id="left-body" href="#right-body" transform="scale(-1,1)"></use>
    <use id="left-sleeve" href="#right-sleeve" transform="scale(-1,1)"></use>
    <path id="collar-right-top" fill="none" stroke="black" stroke-width="1" stroke-linejoin="round" d="M0 -6.5 l11.75 0 l6.5 6.5"></path>
    <use id="collar-left-top" href="#collar-right-top" transform="scale(-1,1)"></use>
    <path id="collar-left" fill="white" stroke="black" stroke-width="1" stroke-linejoin="round" d="M-11.75 -6.5 l-6.5 6.5 l30 77 l6.5 -6.5 Z"></path>
    <path id="front-right" fill="white" stroke="black" stroke-width="1" d="M18.25 0 L30 0 l0 154 l-41.75 0 l0 -77 Z"></path>
    <line x1="0" y1="0" x2="0" y2="154" stroke="black" stroke-width="1" stroke-dasharray="1 3"></line>
    <use id="collar-right" href="#collar-left" transform="scale(-1,1)"></use>
</g>
<g id="dimension-labels">
    <g id="dimension-sleeve-length">
        <line marker-start="url(#arrow)" marker-end="url(#arrow)" x1="85" y1="0" x2="85" y2="120" stroke="black" stroke-width="1"></line>
        <text font-size="10" filter="url(#solid)" fill="black" x="85" y="60" class="dimension" text-anchor="middle" dominant-baseline="middle"> 120 cm</text>
    </g>
    <g id="dimension-length">
        <line marker-start="url(#arrow)" marker-end="url(#arrow)" x1="-85" y1="0" x2="-85" y2="154" stroke="black" stroke-width="1"></line>
        <text font-size="10" filter="url(#solid)" fill="black" x="-85" y="77" text-anchor="middle" dominant-baseline="middle" class="dimension"> 154 cm</text>
    </g>
    <g id="dimension-sleeve-to-sleeve">
        <line marker-start="url(#arrow)" marker-end="url(#arrow)" x1="-65" y1="-20" x2="65" y2="-20" stroke="black" stroke-width="1"></line>
        <text font-size="10" filter="url(#solid)" fill="black" x="0" y="-20" text-anchor="middle" dominant-baseline="middle" class="dimension">&nbsp;130 cm&nbsp;</text>
    </g>
    <g title="Back Width" id="dimension-back-width">
        <line marker-start="url(#arrow)" marker-end="url(#arrow)" x1="-30" y1="174" x2="30" y2="174" stroke="black" stroke-width="1"></line>
        <text font-size="10" filter="url(#solid)" fill="black" x="0" y="174" text-anchor="middle" dominant-baseline="middle" class="dimension">&nbsp;60 cm&nbsp;</text>
    </g>
</g>
</svg>

-1

Metninize stil ekleyebilirsiniz:

  style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); 
    text-shadow: rgb(255, 255, 255) -2px -2px 0px, rgb(255, 255, 255) -2px 2px 0px, 
     rgb(255, 255, 255) 2px -2px 0px, rgb(255, 255, 255) 2px 2px 0px;"

Beyaz, bu örnekte. IE'de çalışmıyor :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.