SVG <img/>元素

时间:2017-11-20 19:39:36

标签: html svg

我的情况是我有一个SVG图形,其宽度是视口的百分比,其高度是固定的。在图形内部,我有一个SVG image element,我希望它总是填充它的直接容器而不会扭曲,就像使用CSS background-size: fill一样。

如何使用我的SVG实现这一目标?

以下是问题的最小设置(and a codepen):

<svg width=100% height=300>
  <rect width=100% height=300 stroke="blue" stroke-width=30 fill="transparent" />
  <image xlink:href="//unsplash.it/500/300" width=100% height=100% />
</svg>

在上面的代码片段中,无论视口宽度如何,我都需要图像来填充整个容器而不会扭曲(在这种情况下,容器是根SVG)。

我无法切换到常规HTML,因为我正在处理的图形有一个应用于image元素的SVG剪贴蒙版。

我发现了这个问题,这似乎与我提出的问题很接近,但我认为没有回答我的问题:

How can I make my embedded svg image stetch to fill a container?

希望避免the XY problem,这里是the actual SVG graphic I'm working on。和我想要实现的(固定高度,可变宽度)结果:

enter image description here

3 个答案:

答案 0 :(得分:2)

Svg缩放图像

如果您向svg添加一个视图框,则svg知道如何缩放 现在添加与svg相同的viewBox比率使得svg将始终具有与图像相同的比例。
您始终可以将图像缩放到viewBox内部 然后它将始终与svg一起扩展。

svg {
  border: 2px solid black;
}
<svg width="100%" height="100%" viewBox="0 0 500 300">
  <image width="500" height="300" xlink:href="//unsplash.it/500/300"/>
</svg>

答案 1 :(得分:1)

要保持图像高度不变,请设置视口高度的固定值和preserveAspectRatio = "none"

&#13;
&#13;
<svg width="100%" height="300" viewBox="0 0 500 300" preserveAspectRatio = "none">
  <image width="500" height="300" xlink:href="//unsplash.it/500/300"/>
</svg>
&#13;
&#13;
&#13;    

UPD

使用preserveAspectRatio="xMinYMin slice"

时,图片的比例不会改变,高度保持不变

&#13;
&#13;
<svg width="100%" height="300" viewBox="0 0 500 300" preserveAspectRatio="xMinYMin slice">

  <image width="100%" height="300" xlink:href="//unsplash.it/500/300" />
</svg>
&#13;
&#13;
&#13;

UPD2

我看了your codepen就像这个想法一样。我已征得您的同意。修改了一些参数

&#13;
&#13;
<svg width="100%" height="400" preserveAspectRatio="xMinYMin slice">
  <defs>
    <mask id="clipping">
      <rect width="100%" height="400" fill="white"/>
      <ellipse cx="50%" cy="120%" rx="75%" ry="37%"/>
    </mask>
    <linearGradient id="Gradient1" x1="0" x2="0" y1="0" y2="1">
      <stop offset="0%" stop-color="white"/>
      <stop offset="100%" stop-color="blue"/>
    </linearGradient>
  </defs>

  <rect   width="100%" height="400" fill="orange" mask="url(#clipping)" transform="translate(-20 12) rotate(-2.5)" />
  <image xlink:href="https://unsplash.it/1000/500" width="100%" height="400" mask="url(#clipping)" transform="translate(0 -10)" />
  <rect  width="100%" height="400" fill="url(#Gradient1)" mask="url(#clipping)" transform="translate(0 -10)" opacity="0.25" /> 
  
  </svg>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

我最终使用了两个SVG和一个图像,该图像使用第一个SVG中定义的剪切蒙版将其剪切下来。我只能通过定义一个视图而不是宽度和高度来缩放SVG。我选择使用固定的宽高比而不是固定的高度,百分比宽度,正如我原先计划的那样。

body > * {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
}

img {
  clip-path: url(#clipper);
}
<svg viewBox="0 0 1000 500">
  <defs>
    <symbol id="arch" viewBox="0 0 1000 400">
      <path d="M0 0 H 1000 V 400 Q 500 300, 0 400" />
    </symbol>
    
    <clipPath id="clipper" clipPathUnits="objectBoundingBox">
      <path d="M0 0 H 1 V 1 Q .5 .75, 0 1" />
    </clipPath>
    
    <linearGradient id="Gradient1" x1="0" x2="0" y1="0" y2="1">
      <stop offset="0%" stop-color="#87AFBF"/>
      <stop offset="100%" stop-color="#002855"/>
    </linearGradient>
  </defs>
  
  <use href="#arch" width="100%" y="-40" fill="#F9B000" transform="translate(-20 12) rotate(-2.5)" />
</svg>

<img src="//unsplash.it/1000/400" alt="">

<svg viewBox="0 0 1000 500">
  <use href="#arch" y="-50" fill="url(#Gradient1)" opacity="0.75" />
</svg>

CodePen