我的情况是我有一个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。和我想要实现的(固定高度,可变宽度)结果:
答案 0 :(得分:2)
如果您向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"
<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;
UPD
使用preserveAspectRatio="xMinYMin slice"
<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;
UPD2
我看了your codepen就像这个想法一样。我已征得您的同意。修改了一些参数
<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;
答案 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>