Màu nền của văn bản trong SVG


101

Tôi muốn tô màu nền của svg texttương tự như background-colortrong css

Tôi chỉ có thể tìm thấy tài liệu về fillnó tô màu văn bản

Nó thậm chí có thể?


Bạn có thể chia sẻ mã của bạn cho đến nay?
gotohales


stackoverflow.com/questions/12260370/… cũng cho biết cách thực hiện việc này bằng bộ lọc.
Erik Dahlström

1
@RobertLongson Đóng câu hỏi này là trùng lặp khi nó được hỏi 2 năm trước câu kia có vẻ sai, đặc biệt khi câu trả lời duy nhất ở đó là của bạn.
Balthazar

@ Aperçu: Độ tuổi của câu hỏi không phải là yếu tố chính khi chọn mục tiêu trùng lặp, hãy xem ví dụ ở đây .
bấm còi

Câu trả lời:


93

Không, điều này là không thể, các phần tử SVG không có background-... thuộc tính trình bày .

Để mô phỏng hiệu ứng này, bạn có thể vẽ một hình chữ nhật đằng sau thuộc tính văn bản với fill="green"hoặc một cái gì đó tương tự (bộ lọc). Sử dụng JavaScript bạn có thể làm như sau:

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);

8
Điều đó hoặc sử dụng bộ lọc svg (feFlood + feComposite) trên văn bản. Xem câu hỏi hơi tương tự stackoverflow.com/questions/12260370/… .
Erik Dahlström

3
Giải pháp sử dụng getBBox () này, mặc dù nó hoạt động tốt, có thể khá chậm khi cần thực hiện một số lượng lớn các phép tính. Vấn đề với việc sử dụng bộ lọc svg (feFlood + feComposite) là văn bản xuất hiện một chút răng cưa. Đã đưa ra một giải pháp đơn giản, nhưng khó hiểu dưới đây.
dbarton_uk

Tốt hơn nên sử dụng textElm = document.getElementById ("the-text") thay vì textElm = ctx.getElementById ("the-text")?
Simon Hi

Làm thế nào tôi sử dụng cùng một hàm getBBox trong nodeJS
Ali

77

Bạn có thể sử dụng bộ lọc để tạo nền.

<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" ở đây có nghĩa là gì? "Url (#solid)" có thực sự gây ra một truy cập web bổ sung không?
Ben Slade

7
văn bản bị mờ ở đây :(
teran

5
Bạn có thể cho phần đệm nền không?
vsync

2
Yêu thích giải pháp này trên lý thuyết, nhưng có thể khẳng định rằng văn bản bị mờ. Có vẻ như bộ lọc phá vỡ tính năng khử răng cưa.
paulmelnikow

2
Thêm operator="xor"vào feCompositeđể ngăn văn bản bị mờ. @RobertLongson @teran @paulmelnikow @bill
Saeid Zebardast

20

Giải pháp tôi đã sử dụng là:

<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>

Một mục văn bản trùng lặp đang được đặt, với các thuộc tính nét và độ rộng nét. Nét vẽ phải phù hợp với màu nền và chiều rộng nét vẽ phải vừa đủ lớn để tạo ra một "mảng sáng" để viết văn bản thực.

Một chút hack và có những vấn đề tiềm ẩn, nhưng phù hợp với tôi!


1
Tôi thấy giải pháp này là dễ nhất.
Morgan Wilde

Xác nhận đây là giải pháp dễ dàng nhất
scipper

Cũng in đẹp ở nơi vì dung dịch bộ lọc rất mờ khi in.
David Hunt

17

Không, bạn không thể thêm màu nền vào các phần tử SVG. Bạn có thể làm điều đó theo lập trình với d3 .

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
Điều này không hoạt động; nó chỉ thay đổi màu của văn bản, không phải màu nền.
David J.

Bao văn bản trong một div hoặc span và áp dụng kiểu cho bất kỳ phần nào trong hai phần cuối cùng mà bạn đã sử dụng.
Arif Burhan

Bài đăng này giải thích rõ về điều đó: cambridge-intelligence.com/…
trao đổi


4

Câu trả lời của Robert Longson (@RobertLongson) có sửa đổi:

<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>

và chúng tôi không có bluring và không có "getBBox" nặng :) Phần đệm được cung cấp bởi các khoảng trắng trong phần tử văn bản với bộ lọc. Nó làm việc cho tôi


2

đây là cách hack yêu thích của tôi (không chắc nó sẽ hoạt động). Nó tham chiếu đến một phần tử chưa được hiển thị và nó hoạt động khá tốt

<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

Bạn có thể kết hợp bộ lọc với văn bản.

<!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

Đối với những người tự hỏi làm thế nào để áp dụng đệm cho một phần tử văn bản khi nó có nền giống như trong câu trả lời của Robert , hãy làm như sau:

  <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>

Trong ví dụ trên, các vị trí xy của bộ lọc có thể được sử dụng như ý transform: translate(-10%, -10%)muốn và các giá trị chiều rộngchiều cao có thể được đọc là 120%120%. Vì vậy, chúng tôi đã làm cho nền lớn hơn 20% và bù trừ nó -10%, vì vậy nền bây giờ lớn hơn 10% ở mỗi bên của văn bản.


0

Các câu trả lời trước dựa vào việc tăng gấp đôi văn bản và thiếu đủ khoảng trắng.

Bằng cách sử dụng atop&nbsp;tôi đã có thể nhận được kết quả như mong muốn.

Ví dụ này cũng bao gồm các mũi tên, một trường hợp sử dụng phổ biến cho nhãn văn bản SVG:

<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

Bạn có thể thêm kiểu vào văn bản của mình:

  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;"

Màu trắng, trong ví dụ này. Không hoạt động trong IE :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.