我想用 svg 填充视口(viewport),并向该 svg 中的路径添加填充。
当我将 preserveAspectRatio="xMinYMin slice"
设置为图像模式时,它会很好地保持纵横比,但路径不会缩放。
如果我随后将 preserveAspectRatio="none"
添加到 svg 元素,整个元素将适合视口(viewport),但我的图像将无法正确缩放。
我忽略了什么?
<svg height="100%" width="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1400 750" preserveAspectRatio="none">
<defs>
<pattern id='home' width="1" height="1" preserveAspectRatio="xMinYMin slice">
<image xlink:href='https://i.imgur.com/4AiXzf8.jpg' width="100%" height="100%" preserveAspectRatio="xMinYMin slice"></image>
</pattern>
</defs>
<path id="bg" class="cls-1" d="M0,0V622.58S250,711,683,711s683-88.42,683-88.42V0Z"style="fill: url(#home)"></path>
</svg>
最佳答案
如果将整个 SVG 设置为 preserveAspectRatio="none"
,然后 SVG 中的所有内容都会拉伸(stretch)并且无法抵消它。所以你必须用不同的方式来做。
我们要做的是删除 viewBox
和 preserveAspectRatio
并设置 width
SVG 到 100%
和 height
到我们的高度<path>
(711px
)。这样,SVG 视口(viewport)会填充页面的宽度,并将其高度保持在我们想要的大小。
下一步是移动 <image>
来自 <pattern>
, 使其宽度和高度 100% x 100%
并设置 preserveAspectRatio="xMinYMin slice"
.所以它现在可以缩放以填充我们的宽 SVG,并保持其纵横比。
最后一步是申请 <clipPath>
给图像赋予我们想要的形状。使剪辑路径自动适合 <image>
, 我们需要使用 clipPathUnits="objectBoundingBox"
.
objetBoundingBox 单位的事情是 (0,0) 代表它所应用到的元素的左上角,而 (1,1) 对应于它所应用到的元素的右下角。但我们的道路远不止于此。它的宽度和高度为 1366x711。
要解决这个问题,我们需要缩放路径,使其大小仅为 1x1,而不是 1366x711。所以我们申请一个transform
并按 1/1366
缩放它在 X 中,和 1/711
在 Y 中。
transform="transform="scale(0.000732, 0.001406)"
最终结果是这样的:
body {
margin: 0;
padding: 0;
}
<svg width="100%" height="711px" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="clip" clipPathUnits="objectBoundingBox">
<path d="M0,0V622.58S250,711,683,711s683-88.42,683-88.42V0Z"
transform="scale(0.000732, 0.001406)"></path>
</clipPath>
</defs>
<image xlink:href='https://i.imgur.com/4AiXzf8.jpg' width="100%" height="100%" preserveAspectRatio="xMinYMin slice"
clip-path="url(#clip)"></image>
</svg>
关于css - 如何将 svg 缩放到视口(viewport),但在填充图像上保持纵横比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48926387/