在不重复或缩放的情况下,用背景图片填充SVG路径元素

22
我非常希望能够做类似于用背景图填充SVG路径元素的事情,但那里提供的解决方案会将图像平铺以填充整个背景区域。我不想要那样。如果图像没有填满整个高度或宽度,则我只想让它居中在路径形状内,就这样。如果我尝试通过更改高度/宽度属性来限制行为,则渲染会缩放图像,直到至少填充其中一个维度。
我想这种行为在某种程度上是有道理的,因为它使用了模式。我可以看出,我想要的实际上并不是一个“模式”。我只是想像现在这样把一张图片放在我的形状中间,而不是把它变成一个模式。然而,我确实希望由我的SVG路径定义形状边界来切断图像的渲染,无论图像的大小是否超出这些边界。除了在回答该问题时使用fill属性的模式外,我不知道还有什么其他方法可以获得这种行为。
在类似问题如何将.png背景图片添加到SVG圆形图形中中,最底部的用户似乎表明他使用了滤镜而不是图案来实现我想要实现的效果。然而,当我尝试时,在渲染过程中并没有考虑实际的形状。图像被呈现出来,而不考虑形状边界,这似乎几乎毫无用处。在SVG中是否有一种方式可以获得类似于图案的背景图像效果,但实际上不将图像平铺成图案?
2个回答

39
只需将图案的xywidthheight与路径的边界框相匹配。在这里,您可以只使用"0"、"0"、"1"和"1",因为patternUnits默认为objectBoundingBox,所以单位是相对于边界框来表示的。然后,使您模式中的图像也具有路径边界框的widthheight。不过,这一次您需要使用“真正”的尺寸。由于<image>preserveAspectRatio的默认值恰好符合您的要求,因此图像会自动居中在模式中。

<svg width="600" height="600">
  
  <defs>
      <pattern id="imgpattern" x="0" y="0" width="1" height="1">
        <image width="120" height="250"
               xlink:href="http://lorempixel.com/animals/120/250/"/>
      </pattern>
  </defs>
  
  
  
  <path fill="url(#imgpattern)" stroke="black" stroke-width="4"
        d="M 100,50 L 120,110 150,90 170,220 70,300 50,250 50,200 70,100 50,70 Z" />

</svg>


1
非常感谢。那个例子似乎是我想要的。我现在要开始修改我的项目,使用它并看看效果如何。 - Michael
1
在我的情境下运作得非常好。正是我所需要的。再次感谢! - Michael
实际上,尽管问题是关于不使用缩放或平铺,但答案是将其自动缩放到100%,并设置填充整个宽度/高度的瓷砖大小,以便您仅使用单个瓷砖。 - brichins
1
我该如何让它填满包含SVG的整个div? - Just A Question
@JustAQuestion 如果你想填充一个div而不是SVG元素,那么你应该使用类似于 div { background: url(myImage.jpg); background-size: cover; } 的东西。 - Paul LeBeau

-1

我尝试将我的第一个比例向量图形扩展文件实现到维护为页面的github存储库中。 我知道过山车要瞄准额外的线条,使其适应环境。但是我必须告诉你,不需要实现模式标语来避免自动模式。 在我的css文件夹中,我有一个名为gradientellipse.svg的文件,其中包含以下内容

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--?xml-stylesheet href="css/styles.css" type="text/css"?-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs> 
  <ellipse id="myEllipse"
           cx="200"
           cy="70"
           rx="85"
           ry="55">
</ellipse>
    <linearGradient id="grad1"
                    x1="0%"
                    y1="0%"
                    x2="0%"
                    y2="100%">
      
    <stop offset="0%"
          style="stop-color:rgb(255,0,0);stop-opacity:1" />
    <stop offset="100%"
          style="stop-color:rgb(255,255,0);stop-opacity:1" />
</linearGradient>
</defs>
  <use x="5" y="5" href="#myEllipse" fill="url('#grad1')" />
</svg>

网站上的标语 <use> 也经常和<defs>一起出现,该句子已被注意到:

元素从SVG文档内获取节点

我非常喜欢这个,因为它让我有机会去追求某些东西,而不是考虑XML服务器脚本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接