【问题标题】:Create responsive SVG clip path / Making SVG <path> responsive创建响应式 SVG 剪辑路径 / 使 SVG <path> 响应式
【发布时间】:2019-05-06 04:33:07
【问题描述】:

我正在尝试使用 &lt;path&gt; SVG 元素创建响应式 SVG 剪辑路径。但是,我无法让它工作。

我已经使用更基本的形状(例如&lt;circle&gt;)让它工作,但不是&lt;path&gt; 元素。我还使用带有 &lt;path&gt; 元素的静态尺寸使其工作。

我使用此处的说明作为参考:https://www.smashingmagazine.com/2015/05/creating-responsive-shapes-with-clip-path/。我还查看了有关 StackOverflow 和其他示例的类似问题,但它们主要处理基本形状而不是路径变量。

我使用的 SVG 形状是从 Adob​​e Illustrator 导出的雨滴形状。

这是我的代码:

HTML

<svg id="raindropSVG" viewBox="0 0 810 1012">
    <defs>
        <clipPath id="raindropClipPath" clipPathUnits="objectBoundingBox">
            <path d="M0,604.4C0,523.7,30.7,408.8,97.5,320,217,160.9,409.2,0,409.2,0S597.2,167.8,717,331c63,85.7,93,196.4,93,274,0,224.5-181.3,407-405,407S0,829.5,0,604.4Z"/>
        </clipPath>
    </defs>
</svg>

<img src="clipped-image.jpg" alt="" class="clipped-img">

CSS

.clipped-img {
    clip-path: url(#raindropClipPath);
    width: 100%;
    height: auto;
}

#raindropSVG {
    width: 0;
    height: 0;
}

这个想法是改变.clipped-img的宽度(或高度)应该相应地缩放雨滴形状。

使用clipPathUnits="objectBoundingBox" 是使clipPath 响应的必要条件。但是,一旦我添加了这个,剪辑的图像就会消失。

我认为我哪里出错了

我怀疑 path 元素指定的路径不是相对单位,但是我不知道如何将单位更改为相对单位。


提前感谢所有回复!

【问题讨论】:

  • objectBoundingBox 单位范围从 0 到 1。M0,604.4 太大了。想象一下,您将单位从 3 英寸更改为 3 公里,您不会期望这是相同的距离。
  • @RobertLongson 感谢您的回复。我如何将这些单位更改为相对单位?处理基本形状时,这很简单,但是如何使用示例中的更复杂的形状来完成此操作?
  • 当图像的纵横比发生变化时,有两种方法可以实现:剪辑路径的纵横比适应图像的纵横比(扭曲形状),或者剪辑路径保持不变它的纵横比,但不会拉伸到图像的所有边框。您希望它以哪种方式工作?
  • @ccprog 我会选择第一种方式,因为这是我所期望的。不过,无论哪种方式都很好。

标签: svg clip-path


【解决方案1】:

这个答案会扭曲剪辑路径的形状,使其始终跨越整个图像,无论其纵横比如何。

使用clipPathUnits="objectBoundingBox",只有介于 0 和 1 之间的坐标会位于图像的边界矩形内。为此,您必须缩小路径。

幸运的是,路径的 viewBox 命名了它的维度。不幸的是,您不能将缩放的计算留给渲染器,而必须直接进行转换:scale(1 / 810, 1 / 1012)。有关&lt;clipPath&gt; 的内容元素,请参阅restrictions

SVG 1.1 和 SVG 2 规范名称 transform 作为 &lt;clipPath&gt; 本身的可能属性,但都没有定义它应该应用的坐标系。为了浏览器兼容性,它可能更好不用管它,并在 &lt;path&gt; 元素上使用转换,即使我可以看到在 Firefox 中结果没有区别。

.clipped-img {
    clip-path: url(#raindropClipPath);
    width: 100%;
    height: auto;
}

#raindropSVG {
    width: 0;
    height: 0;

}
<svg id="raindropSVG">
    <defs>
        <clipPath id="raindropClipPath" clipPathUnits="objectBoundingBox">
            <path transform="scale(0.0012345, 0.00098814)" d="M0,604.4C0,523.7,30.7,408.8,97.5,320,217,160.9,409.2,0,409.2,0S597.2,167.8,717,331c63,85.7,93,196.4,93,274,0,224.5-181.3,407-405,407S0,829.5,0,604.4Z"/>
        </clipPath>
    </defs>
</svg>

<img src="https://i.stack.imgur.com/zubYX.png" alt="" class="clipped-img">

【讨论】:

  • 您自己已经在上面写过,会出现比例失真,但如果这适合问题的作者,那么您的决定是最好的
  • 我同意他对我的问题的评论。但你是对的,我应该在后验性的答案中说明这一点。
  • 感谢您的回答。我选择这个作为接受的答案,因为它更完整地回答了我的问题。 @Alexandr_T,你的回答也很有启发性。
【解决方案2】:

如果仅指定 viewBox,SVG 将始终响应。

Svg 保存图片比例 除非指定了值 `preserveAspectRatio ="none"。

因此,path formativeclip-path 也将响应。

使用&lt;image&gt; 标签添加到 SVG 的图片也将自适应并保持其比例。

#raindropSVG {
    width: 75%;
    height: 75%;
}

.clipped-img {
clip-path: url(#raindropClipPath);
}
<svg id="raindropSVG" viewBox="0 0 800 800" preserveAspectRatio="xMinYMin meet">
    <defs>
        <clipPath id="raindropClipPath" >
            <path transform="scale(0.75)" d="M0,604.4C0,523.7,30.7,408.8,97.5,320,217,160.9,409.2,0,409.2,0S597.2,167.8,717,331c63,85.7,93,196.4,93,274,0,224.5-181.3,407-405,407S0,829.5,0,604.4Z"/>
        </clipPath>
    </defs>
<image class="clipped-img" xlink:href="https://i.stack.imgur.com/zubYX.png" x="0" y="0" width="800" height="800" />
	
	</svg>

【讨论】:

  • 感谢您的回答。当图像是 SVG 的一部分时,就像在您的示例中一样,它是响应式的。所以这是朝着正确方向迈出的一步。但是,出于我的目的,我需要它在图像位于 SVG 之外并且通过剪辑路径引用的路径时工作。这是因为我剪辑的可能不是图像,可能是视频或其他内容。所以这就是为什么我需要剪辑路径本身做出响应。
  • @Ron 你有一个非常有趣的想法。我会考虑一下。但是如果 svg 中的 clipPath 在所有现代浏览器中都有效,那么clip-path css 会被更糟糕的浏览器支持
  • 此方法的另一个缺点是您无法设置height:auto,但必须明确调整图像大小。
猜你喜欢
  • 2020-08-22
  • 2015-04-03
  • 2023-04-04
  • 2014-01-24
  • 1970-01-01
  • 2014-11-14
  • 2016-05-19
  • 2017-07-24
相关资源
最近更新 更多