我想颜色的背景 svgtext类似于在 CSS 中的 background-color
text
background-color
我只能找到关于 fill的文档,它会给文本本身着色
fill
这有可能吗?
不,这是不可能的,SVG 元素没有 background-... 表示属性。
background-...
为了模拟这种效果,您可以使用 fill="green"或类似的东西(过滤器)在 text 属性后面绘制一个矩形。使用 JavaScript 你可以做到以下几点:
fill="green"
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);
不能,您不能为 SVG 元素添加背景色。您可以使用 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");
您可以使用一个过滤器来生成背景。
<svg width="100%" height="100%"> <defs> <filter x="0" y="0" width="1" height="1" id="solid"> <feFlood flood-color="yellow" result="bg" /> <feMerge> <feMergeNode in="bg"/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter> </defs> <text filter="url(#solid)" x="20" y="50" font-size="50">solid background</text> </svg>
我使用的解决方案是:
<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>
正在放置具有笔划和笔划宽度属性的重复文本项。笔画应该与背景颜色相匹配,笔画宽度应该足够大,以创建一个“污点”,在上面写实际的文本。
有一点黑客和潜在的问题,但为我工作!
作者: Robert Longson (@RobertLongson):
<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>
而且我们没有模糊化,也没有重量级的“ getBBox”:) 带有过滤器的文本元素中的空格提供填充。 这招对我很管用
这是我最喜欢的黑客技术(不确定它是否有效)。它引用一个尚未显示的元素,并且工作得非常好
<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>
可以使用 <foreignObject>标记,而不是使用 <text>标记,它允许使用 CSS 处理 XHTML 内容。
<foreignObject>
<text>
你可以给你的文本添加样式:
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;"
白色,在这个例子中。 不在 IE 中工作:)
可以将过滤器与文本组合在一起。
<!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>
以前的答案依赖于将文本加倍,缺乏足够的空白。
通过使用 atop和 ,我能够得到我想要的结果。
atop
这个示例还包括箭头,这是 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"> 130 cm </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"> 60 cm </text> </g> </g> </svg>
对于那些想知道如何在文本元素具有类似于 罗伯特的回答的背景时应用填充的人,请执行以下操作:
<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>
在上面的例子中,过滤器的 X和 嘿位置可以作为 transform: translate(-10%, -10%)使用,而 宽度和 身高值可以作为 120%和 120%读取。所以我们把背景放大了20% ,抵消了它的 -10% ,所以现在文本的每一边背景都放大了10% 。
transform: translate(-10%, -10%)
120%
进一步使用@dbarton _ uk 回答,为了避免文本重复,你可以使用 paint-order=stroke风格:
paint-order=stroke
<svg> <line x1="100" y1="100" x2="350" y2="100" style="stroke:grey; stroke-width: 100"/> <text x="150" y="105" style="stroke:white; stroke-width:0.5em; fill:black; paint-order:stroke; stroke-linejoin:round">Hello World!</text> </svg>
注意 stroke-linejoin:round,这是必要的,以避免看到尖峰的 W 锐利的角度。
stroke-linejoin:round
对于 filter效果产生的模糊问题,一个明显的解决办法是将 <text>渲染两次: 一次用于背景(透明字符) ,一次用于字符(没有背景过滤器)。
filter
对我来说,这是在 Safari 中使文本可读的唯一方法。
<svg width="100%" height="100%"> <filter x="0" y="0" width="1" height="1" id="solid"> <feFlood flood-color="yellow" /> </filter> <g transform="translate(20, 50)" font-size="50"> <text aria-hidden="true" fill="none" filter="url(#solid)">solid background</text> <text fill="blue">solid background</text> </g> </svg>
如果用户使用屏幕阅读器,那么 aria-hidden="true"属性可以防止屏幕阅读器两次读取文本。
aria-hidden="true"