如何使用SVG滤镜创建模糊的标签背景?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用SVG滤镜创建模糊的标签背景?相关的知识,希望对你有一定的参考价值。

我希望有一个很好的解决以下问题的方法:

在条形图上,条形填充有不同但未知的颜色,我希望将标签固定为黑色,以便于阅读。

我正在搜索的方法应该看起来像在图像窗口的标题栏中。标签为黑色,位于模糊的白色背景上,该背景位于任何颜色的条形顶部。

enter image description here

是否有使用SVG过滤器的方法?

下面是我尝试过的一些方法:

    .black 
      fill: black;
    
    .blue 
      fill: blue;
    
    .red 
      fill: red;
        
    .yellow 
      fill: yellow;
    
    .label
      fill: black;
      font-size: 14px;
    
    .label-background
      fill: white;
      font-size: 16px;
    
    .text-background
      paint-order: stroke;
      stroke: #fff;
      fill: black;
      stroke-width: 5px;
    
    .header
      font-size: 20px;
    
    .background
      fill: white;
      opacity: 0.6;
    
  <svg width="500" height="500">
    <defs>
      <filter x="-0.05" y="-0.1" width="1.08" height="1.2" id="solid">
        <feFlood flood-color="lightgrey"/>
        <feComposite in="SourceGraphic" operator="xor" />
      </filter>
    </defs>

    <g class="row-1" transform="translate(0,30)">
      <text class="header" x="20" y="-10">text label on top of bar </text>
      <g>
        <rect class="black" width=100 height=30></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(120,0)">
        <rect class="blue" width=100 height=30></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(240,0)">
        <rect class="red" width=100 height=30></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(360,0)">
        <rect class="yellow" width=100 height=30></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>
    </g>  
    
		<g class="row-2" transform="translate(0,100)">
      <text class="header" x="20" y="-10">text label on top of rect.background on top of bar </text>
      <g>
        <rect class="black" width=100 height=30></rect>
        <rect class="background" x=17 y=6 width=78 height=19></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(120,0)">
        <rect class="blue" width=100 height=30></rect>
        <rect class="background" x=17 y=6 width=78 height=19></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(240,0)">
        <rect class="red" width=100 height=30></rect>
        <rect class="background" x=17 y=6 width=78 height=19></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(360,0)">
        <rect class="yellow" width=100 height=30></rect>
        <rect class="background" x=17 y=6 width=78 height=19></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>
  	</g>
    
    <g class="row-3" transform="translate(0, 170)">
      <text class="header" x="20" y="-10">text label with filter #solid on top of bar </text>
      <g>
        <rect class="black" width=100 height=30></rect>
        <text class="label" filter="url(#solid)" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(120,0)">
        <rect class="blue" width=100 height=30></rect>
        <text class="label" filter="url(#solid)" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(240,0)">
        <rect class="red" width=100 height=30></rect>
        <text class="label" filter="url(#solid)" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(360,0)">
        <rect class="yellow" width=100 height=30></rect>
        <text class="label" filter="url(#solid)" x="20" y="20">my text label</text>
      </g>
    </g> 

    <g class="row-4" transform="translate(0, 240)">
      <text class="header" x="20" y="-10">text label on top of larger text label with background color on top of bar </text>
      <g>
        <rect class="black" width=100 height=30></rect>
        <text class="label-background" x="18" y="22">my text label</text>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(120,0)">
        <rect class="blue" width=100 height=30></rect>
        <text class="label-background" x="18" y="22">my text label</text>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(240,0)">
        <rect class="red" width=100 height=30></rect>
        <text class="label-background" x="18" y="22">my text label</text>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(360,0)">
        <rect class="yellow" width=100 height=30></rect>
        <text class="label-background" x="18" y="22">my text label</text>
        <text class="label" x="20" y="20">my text label</text>
      </g>
    </g> 
    
    <g class="row-5" transform="translate(0, 310)">
      <text class="header" x="20" y="-10">text label with paint-order: stroke on top of bar </text>
      <g>
        <rect class="black" width=100 height=30></rect>
        <text class="label text-background" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(120,0)">
        <rect class="blue" width=100 height=30></rect>
        <text class="label text-background" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(240,0)">
        <rect class="red" width=100 height=30></rect>
        <text class="label text-background" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(360,0)">
        <rect class="yellow" width=100 height=30></rect>
        <text class="label text-background" x="20" y="20">my text label</text>
      </g>
    </g> 
  </svg>
  
答案

未经充分测试,但使用多个值构建text-shadow具有所需的效果:

    svg text 
      text-shadow: 0px 0px 2px white,
                   0px 0px 4px white,
                   0px 0px 6px white,
                   0px 0px 8px white,
                   0px 0px 10px white;
    

工作示例:

    .black 
      fill: black;
    
    .blue 
      fill: blue;
    
    .red 
      fill: red;
        
    .yellow 
      fill: yellow;
    
    .label
      fill: black;
      font-size: 14px;
    

svg g.row-1 text 
  text-shadow: 0px 0px 2px white,
               0px 0px 4px white,
               0px 0px 6px white,
               0px 0px 8px white,
               0px 0px 10px white;
<svg width="500" height="500">
    <defs>
      <filter x="-0.05" y="-0.1" width="1.08" height="1.2" id="solid">
        <feFlood flood-color="lightgrey"/>
        <feComposite in="SourceGraphic" operator="xor" />
      </filter>
    </defs>

    <g class="row-1" transform="translate(0,30)">
      <g>
        <rect class="black" width=100 height=30></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(120,0)">
        <rect class="blue" width=100 height=30></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(240,0)">
        <rect class="red" width=100 height=30></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>

      <g transform="translate(360,0)">
        <rect class="yellow" width=100 height=30></rect>
        <text class="label" x="20" y="20">my text label</text>
      </g>
    </g>  
</svg>
  
另一答案

由于您正在寻求SVG过滤器解决方案:

  1. SourceAlpha开始,为您提供元素(即文本)的黑色轮廓,然后用feGaussianBlur将其模糊以创建柔和的阴影。
  2. 此阴影将为黑色,因此请使用feColorMatrix将其变为白色。
  3. 最后,使用feBlend将原始文本放在阴影上方。

参考:

.black 
  fill: black;

.blue 
  fill: blue;

.red 
  fill: red;
    
.yellow 
  fill: yellow;

.label 
  fill: black;
  font-size: 14px;
<svg width="500" height="80">
  <defs>
    <filter id="shadow">
      <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur" />
      <feColorMatrix in="blur" type="matrix" values="0  0  0  0  1
                                                     0  0  0  0  1
                                                     0  0  0  0  1
                                                     0  0  0  8  0" result="white" />
      <feColorMatrix in="white" type="matrix" values="1  0  0  0  0
                                                      0  1  0  0  0
                                                      0  0  1  0  0
                                                      0  0  0 .8  0" result="dim" />
      <feBlend in="SourceGraphic" in2="dim" mode="normal" />
    </filter>
  </defs>

  <g class="row-1" transform="translate(10,30)">
    <text class="header" x="0" y="-10">feGaussianBlur on SourceAlpha</text>
    <g>
      <rect class="black" width=100 height=30></rect>
      <text class="label" x="20" y="20" filter="url(#shadow)">my text label</text>
    </g>
    <g transform="translate(120,0)">
      <rect class="blue" width=100 height=30></rect>
      <text class="label" x="20" y="20" filter="url(#shadow)">my text label</text>
    </g>
    <g transform="translate(240,0)">
      <rect class="red" width=100 height=30></rect>
      <text class="label" x="20" y="20" filter="url(#shadow)">my text label</text>
    </g>
    <g transform="translate(360,0)">
      <rect class="yellow" width=100 height=30></rect>
      <text class="label" x="20" y="20" filter="url(#shadow)">my text label</text>
    </g>
  </g>  
</svg>

以上是关于如何使用SVG滤镜创建模糊的标签背景?的主要内容,如果未能解决你的问题,请参考以下文章

CSS filter 有哪些神奇用途

如何使用 SVG 滤镜创建透明渐变蒙版

将带有滤镜效果的 SVG 渲染为 PNG

如何仅在 Vue.js 中模糊 svg 背景?

请教CSS,在有背景图的背景层上使用模糊滤镜,把内层的文字也模糊了,求不模糊文字的方法?

使用 CSS 模糊背景滤镜元素的边缘